initial commit
This commit is contained in:
7
scripts/vscripts/abilities/ability_lua/hanadayousei.lua
Executable file
7
scripts/vscripts/abilities/ability_lua/hanadayousei.lua
Executable file
@@ -0,0 +1,7 @@
|
||||
thtd_hanadayousei_01 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_hanadayousei_01", "abilities/ability_lua/modifier_hanadayousei_01", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_hanadayousei_01:GetIntrinsicModifierName()
|
||||
return "modifier_hanadayousei_01"
|
||||
end
|
||||
8
scripts/vscripts/abilities/ability_lua/hourainingyou.lua
Executable file
8
scripts/vscripts/abilities/ability_lua/hourainingyou.lua
Executable file
@@ -0,0 +1,8 @@
|
||||
thtd_hourainingyou_01 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_hourainingyou_01", "abilities/ability_lua/modifier_hourainingyou_01", LUA_MODIFIER_MOTION_NONE)
|
||||
LinkLuaModifier("modifier_hourainingyou_01_stun_lock", "abilities/ability_lua/modifier_hourainingyou_01_stun_lock", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_hourainingyou_01:GetIntrinsicModifierName()
|
||||
return "modifier_hourainingyou_01"
|
||||
end
|
||||
83
scripts/vscripts/abilities/ability_lua/lily.lua
Executable file
83
scripts/vscripts/abilities/ability_lua/lily.lua
Executable file
@@ -0,0 +1,83 @@
|
||||
thtd_lily_01 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_lily_01_effect_think", "abilities/ability_lua/modifier_lily_01_effect_think", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_lily_01:GetIntrinsicModifierName()
|
||||
return "modifier_lily_01_effect_think"
|
||||
end
|
||||
|
||||
function thtd_lily_01:GetAOERadius()
|
||||
return self:GetSpecialValueFor("radius")
|
||||
end
|
||||
|
||||
function thtd_lily_01:OnSpellStart()
|
||||
if SpawnSystem.IsUnLimited then return end
|
||||
if GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then return end
|
||||
local caster = self:GetCaster()
|
||||
local ability = self
|
||||
local targetPoint = self:GetCursorPosition()
|
||||
|
||||
local targets =
|
||||
FindUnitsInRadius(
|
||||
caster:GetTeamNumber(),
|
||||
targetPoint,
|
||||
nil,
|
||||
ability:GetSpecialValueFor("radius"),
|
||||
ability:GetAbilityTargetTeam(),
|
||||
ability:GetAbilityTargetType(),
|
||||
ability:GetAbilityTargetFlags(),
|
||||
FIND_CLOSEST,
|
||||
false
|
||||
)
|
||||
|
||||
local exp = 1000 + caster:THTD_GetPower() * ability:GetSpecialValueFor("power_factor")
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if v ~= nil and v:IsNull() == false and v:THTD_IsTower() and v ~= caster and v:GetOwner() == caster:GetOwner() and v:THTD_GetLevel() < THTD_MAX_LEVEL then
|
||||
v:THTD_AddExp(exp)
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lily/ability_lily_01_a.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
|
||||
thtd_lily_02 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_lily_02_buff", "abilities/ability_lua/modifier_lily_02_buff", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_lily_02:OnSpellStart()
|
||||
local caster = self:GetCaster()
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_lily_02")
|
||||
|
||||
self.radius = self:GetSpecialValueFor("radius")
|
||||
self.duration = self:GetSpecialValueFor("duration")
|
||||
self.damage_up = self:GetSpecialValueFor("damage_up")
|
||||
|
||||
local targets =
|
||||
FindUnitsInRadius(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
nil,
|
||||
self.radius,
|
||||
self:GetAbilityTargetTeam(),
|
||||
self:GetAbilityTargetType(),
|
||||
self:GetAbilityTargetFlags(),
|
||||
FIND_CLOSEST,
|
||||
false
|
||||
)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_lily_02_buff") then
|
||||
v:AddNewModifier(caster, self, "modifier_lily_02_buff", {Duration = self.duration})
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lily/ability_lily_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(self.radius,self.radius,self.radius))
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,self.duration)
|
||||
end
|
||||
61
scripts/vscripts/abilities/ability_lua/modifier_hanadayousei_01.lua
Executable file
61
scripts/vscripts/abilities/ability_lua/modifier_hanadayousei_01.lua
Executable file
@@ -0,0 +1,61 @@
|
||||
modifier_hanadayousei_01 = class({})
|
||||
|
||||
local public = modifier_hanadayousei_01
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsHidden()
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetTexture()
|
||||
return "touhoutd/thtd_hanadayousei_01"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:DeclareFunctions()
|
||||
local funcs = {
|
||||
MODIFIER_EVENT_ON_ATTACK,
|
||||
}
|
||||
return funcs
|
||||
end
|
||||
|
||||
function public:OnAttack( params )
|
||||
if IsServer() then
|
||||
if params.attacker ~= self:GetParent() or self:GetParent():IsIllusion() then return end
|
||||
if self:GetParent():PassivesDisabled() then return end
|
||||
|
||||
local caster = params.attacker
|
||||
local target = params.target
|
||||
|
||||
if caster.__hanadayousei_lock ~= true then
|
||||
caster.__hanadayousei_lock = true
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),800)
|
||||
local count = 1
|
||||
for i=1,#targets do
|
||||
local unit = targets[i]
|
||||
if unit~=nil and unit:IsNull()==false and unit~=target and unit:IsAlive() then
|
||||
caster:PerformAttack(unit,true,false,true,false,true,false,true)
|
||||
count = count + 1
|
||||
end
|
||||
if count > 3 then
|
||||
break
|
||||
end
|
||||
end
|
||||
caster.__hanadayousei_lock = false
|
||||
end
|
||||
end
|
||||
end
|
||||
61
scripts/vscripts/abilities/ability_lua/modifier_hourainingyou_01.lua
Executable file
61
scripts/vscripts/abilities/ability_lua/modifier_hourainingyou_01.lua
Executable file
@@ -0,0 +1,61 @@
|
||||
modifier_hourainingyou_01 = class({})
|
||||
|
||||
local public = modifier_hourainingyou_01
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsHidden()
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetTexture()
|
||||
return "touhoutd/thtd_hourainingyou_01"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:DeclareFunctions()
|
||||
local funcs = {
|
||||
MODIFIER_EVENT_ON_ATTACK_LANDED,
|
||||
}
|
||||
return funcs
|
||||
end
|
||||
|
||||
function public:OnAttackLanded( params )
|
||||
if IsServer() then
|
||||
if params.attacker ~= self:GetParent() or self:GetParent():IsIllusion() then return end
|
||||
if self:GetParent():PassivesDisabled() then return end
|
||||
|
||||
local caster = params.attacker
|
||||
local target = params.target
|
||||
local ability = self:GetAbility()
|
||||
|
||||
if RollPercentage(ability:GetSpecialValueFor("chance")) then
|
||||
if not target:HasModifier("modifier_hourainingyou_01_stun_lock") then
|
||||
target:AddNewModifier(caster, ability, "modifier_hourainingyou_01_stun_lock", {Duration = ability:GetSpecialValueFor("lock_time")})
|
||||
UnitStunTarget(caster,target,ability:GetSpecialValueFor("stun_time"))
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(ability),
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
modifier_hourainingyou_01_stun_lock = class({})
|
||||
|
||||
local public = modifier_hourainingyou_01_stun_lock
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsHidden()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetTexture()
|
||||
return "touhoutd/thtd_hourainingyou_01"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
50
scripts/vscripts/abilities/ability_lua/modifier_lily_01_effect_think.lua
Executable file
50
scripts/vscripts/abilities/ability_lua/modifier_lily_01_effect_think.lua
Executable file
@@ -0,0 +1,50 @@
|
||||
modifier_lily_01_effect_think = class({})
|
||||
|
||||
local public = modifier_lily_01_effect_think
|
||||
|
||||
function public:IsHidden()
|
||||
return true
|
||||
end
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetAttributes()
|
||||
return MODIFIER_ATTRIBUTE_IGNORE_INVULNERABLE
|
||||
end
|
||||
|
||||
function public:OnIntervalThink()
|
||||
if IsServer() then
|
||||
local caster = self:GetParent()
|
||||
local ability = self:GetAbility()
|
||||
|
||||
if ability:IsCooldownReady() and ability:IsFullyCastable() and SpawnSystem.IsUnLimited == false then
|
||||
if caster.thtd_lily_01_effectIndex == nil then
|
||||
caster.thtd_lily_01_effectIndex = ParticleManager:CreateParticle("particles/heroes/lily/ability_lily_01_ready.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(caster.thtd_lily_01_effectIndex , 0, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
end
|
||||
elseif caster.thtd_lily_01_effectIndex ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_lily_01_effectIndex,true)
|
||||
caster.thtd_lily_01_effectIndex = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function public:OnCreated(kv)
|
||||
if IsServer() then
|
||||
self:StartIntervalThink(self:GetAbility():GetSpecialValueFor("effect_tick"))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function public:OnDestroy(kv)
|
||||
if IsServer() then
|
||||
self:StartIntervalThink(-1)
|
||||
end
|
||||
end
|
||||
|
||||
51
scripts/vscripts/abilities/ability_lua/modifier_lily_02_buff.lua
Executable file
51
scripts/vscripts/abilities/ability_lua/modifier_lily_02_buff.lua
Executable file
@@ -0,0 +1,51 @@
|
||||
modifier_lily_02_buff = class({})
|
||||
|
||||
local public = modifier_lily_02_buff
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsHidden()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetTexture()
|
||||
return "touhoutd/thtd_lily_02"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:OnCreated(kv)
|
||||
if IsServer() then
|
||||
local target = self:GetParent()
|
||||
local ability_damage_up = self:GetAbility():GetSpecialValueFor("damage_up")
|
||||
|
||||
local playerid = self:GetCaster():GetPlayerOwnerID()
|
||||
local crit = 1.0
|
||||
if GameRules.player_bb_buff[playerid]["item_3029"] > 0 then
|
||||
crit = 1 + GameRules.player_bb_buff[playerid]["item_3029"]/100
|
||||
end
|
||||
|
||||
local bonus = math.floor(ability_damage_up * crit)
|
||||
target:AddDamageOutgoingAll(bonus, "thtd_lily_02_damage_up")
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:OnDestroy(kv)
|
||||
if IsServer() then
|
||||
self:GetParent():AddDamageOutgoingAll("thtd_lily_02_damage_up")
|
||||
end
|
||||
end
|
||||
74
scripts/vscripts/abilities/ability_lua/modifier_mugiyousei_01.lua
Executable file
74
scripts/vscripts/abilities/ability_lua/modifier_mugiyousei_01.lua
Executable file
@@ -0,0 +1,74 @@
|
||||
modifier_mugiyousei_01 = class({})
|
||||
|
||||
local public = modifier_mugiyousei_01
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsHidden()
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetTexture()
|
||||
return "touhoutd/thtd_mugiyousei_01"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:DeclareFunctions()
|
||||
local funcs = {
|
||||
MODIFIER_EVENT_ON_ATTACK_LANDED,
|
||||
}
|
||||
return funcs
|
||||
end
|
||||
|
||||
function public:OnAttackLanded( params )
|
||||
if IsServer() then
|
||||
if params.attacker ~= self:GetParent() or self:GetParent():IsIllusion() then return end
|
||||
if self:GetParent():PassivesDisabled() then return end
|
||||
|
||||
local caster = params.attacker
|
||||
local target = params.target
|
||||
local ability = self:GetAbility()
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
|
||||
local time = ability:GetSpecialValueFor("damage_duration")
|
||||
target:AddPoison(1, caster)
|
||||
target:SetContextThink(DoUniqueString("thtd_mugiyousei01_attack"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 or THTD_IsValid(target) == false then
|
||||
if target ~= nil and target:IsNull() == false then
|
||||
target:AddPoison(-1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
time = time - 1.0
|
||||
return 1.0
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
102
scripts/vscripts/abilities/ability_lua/modifier_nazrin_01.lua
Executable file
102
scripts/vscripts/abilities/ability_lua/modifier_nazrin_01.lua
Executable file
@@ -0,0 +1,102 @@
|
||||
modifier_nazrin_01 = class({})
|
||||
|
||||
local public = modifier_nazrin_01
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsDebuff()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsHidden()
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
function public:GetTexture()
|
||||
return "touhoutd/thtd_nazrin_01"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function public:DeclareFunctions()
|
||||
local funcs = {
|
||||
MODIFIER_EVENT_ON_ATTACK_LANDED,
|
||||
}
|
||||
return funcs
|
||||
end
|
||||
|
||||
function public:OnAttackLanded( params )
|
||||
if IsServer() then
|
||||
-- 必须加下下面判断,否则会对所有单位攻击都有效,因lua这个是按事件处理,和KV的不同,只要是攻击这个行为就会触发事件,所以尽量不要使用lua的OnXXX事件方式
|
||||
if params.attacker ~= self:GetParent() or self:GetParent():IsIllusion() then return end
|
||||
if self:GetParent():PassivesDisabled() then return end
|
||||
|
||||
-- PrintTable(params)
|
||||
-- [VScript] attacker:
|
||||
-- [VScript] basher_tested: false
|
||||
-- [VScript] cost: 0
|
||||
-- [VScript] damage: 4
|
||||
-- [VScript] damage_category: 1
|
||||
-- [VScript] damage_flags: 0
|
||||
-- [VScript] damage_type: 1
|
||||
-- [VScript] diffusal_applied: false
|
||||
-- [VScript] distance: 0
|
||||
-- [VScript] do_not_consume: false
|
||||
-- [VScript] fail_type: 0
|
||||
-- [VScript] gain: 0
|
||||
-- [VScript] heart_regen_applied: false
|
||||
-- [VScript] ignore_invis: false
|
||||
-- [VScript] issuer_player_index: 0
|
||||
-- [VScript] mkb_tested: false
|
||||
-- [VScript] new_pos: Vector 0000000003530FA8 [0.000000 0.000000 0.000000]
|
||||
-- [VScript] no_attack_cooldown: false
|
||||
-- [VScript] order_type: 0
|
||||
-- [VScript] original_damage: 4
|
||||
-- [VScript] process_procs: true
|
||||
-- [VScript] ranged_attack: true
|
||||
-- [VScript] record: 1
|
||||
-- [VScript] reincarnate: false
|
||||
-- [VScript] stout_tested: false
|
||||
-- [VScript] target:
|
||||
|
||||
local caster = params.attacker
|
||||
local target = params.target
|
||||
local ability = self:GetAbility()
|
||||
|
||||
if SpawnSystem.IsUnLimited then
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),400)
|
||||
local damage = caster:GetGold()*caster:THTD_GetStar()*caster.thtd_byakuren_buff_nazrin
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then return end
|
||||
|
||||
if RollPercentage(ability:GetSpecialValueFor("bonus_chance")) then
|
||||
local gold = math.floor(caster:THTD_GetPower() * ability:GetSpecialValueFor("power_percent")/100 + ability:GetSpecialValueFor("bonus_gold"))
|
||||
THTD_ModifyGoldEx(caster:GetPlayerOwnerID(), gold , true, DOTA_ModifyGold_CreepKill)
|
||||
SendOverheadEventMessage(caster:GetPlayerOwner(), OVERHEAD_ALERT_GOLD, target, gold, caster:GetPlayerOwner() )
|
||||
caster:EmitSound("Sound_THTD.thtd_nazrin_01")
|
||||
end
|
||||
end
|
||||
end
|
||||
7
scripts/vscripts/abilities/ability_lua/mugiyousei.lua
Executable file
7
scripts/vscripts/abilities/ability_lua/mugiyousei.lua
Executable file
@@ -0,0 +1,7 @@
|
||||
thtd_mugiyousei_01 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_mugiyousei_01", "abilities/ability_lua/modifier_mugiyousei_01", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_mugiyousei_01:GetIntrinsicModifierName()
|
||||
return "modifier_mugiyousei_01"
|
||||
end
|
||||
7
scripts/vscripts/abilities/ability_lua/nazrin.lua
Executable file
7
scripts/vscripts/abilities/ability_lua/nazrin.lua
Executable file
@@ -0,0 +1,7 @@
|
||||
thtd_nazrin_01 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_nazrin_01", "abilities/ability_lua/modifier_nazrin_01", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_nazrin_01:GetIntrinsicModifierName()
|
||||
return "modifier_nazrin_01"
|
||||
end
|
||||
395
scripts/vscripts/abilities/abilityalice.lua
Executable file
395
scripts/vscripts/abilities/abilityalice.lua
Executable file
@@ -0,0 +1,395 @@
|
||||
|
||||
function OnAlice01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"alice_boom",
|
||||
targetPoint,
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
if (unit == nil) then return end
|
||||
unit.thtd_spawn_unit_owner = caster
|
||||
unit:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
||||
FindClearSpaceForUnit(unit, targetPoint, false)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_alice_01_rooted", {})
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_alice_boom_tracker", {})
|
||||
unit:AddNewModifier(unit, nil, "modifier_invisible", nil)
|
||||
|
||||
local ability = unit:FindAbilityByName("thtd_alice_unit_kill")
|
||||
if ability then
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
local time = keys.duration_time
|
||||
caster:SetContextThink(DoUniqueString("thtd_alice_01"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if unit==nil or unit:IsNull() or unit:IsAlive()==false then
|
||||
return nil
|
||||
end
|
||||
if caster==nil or caster:IsNull() or caster:IsAlive()==false or caster:THTD_IsHidden() or time <= 0 then
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
|
||||
local enemies = THTD_FindUnitsInRadius(caster, targetPoint, keys.range1)
|
||||
if #enemies > 0 then
|
||||
enemies = THTD_FindUnitsInRadius(caster, targetPoint, keys.range2)
|
||||
if ability then
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (caster.thtd_alice03_damage_up or 1)
|
||||
if caster:HasModifier("modifier_alice_power666") then
|
||||
damage = damage * 3
|
||||
end
|
||||
|
||||
for k,v in pairs(enemies) do
|
||||
local d = GetDistanceBetweenTwoVec2D(targetPoint, v:GetAbsOrigin())
|
||||
local factor = 1.0
|
||||
if d <= keys.range1 then
|
||||
factor = 5
|
||||
else
|
||||
factor = keys.range2 / d
|
||||
end
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
UnitStunTarget(caster,v,keys.stun_time * math.min(2.0, factor))
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * factor,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
unit:CastAbilityNoTarget(ability, caster:GetPlayerOwnerID())
|
||||
unit:EmitSound("Hero_Techies.LandMine.Detonate")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnAliceUnitKillSpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
caster:SetContextThink(DoUniqueString("thtd_alice_unit"),
|
||||
function()
|
||||
local owner = caster.thtd_spawn_unit_owner
|
||||
if owner:IsPower666() then
|
||||
local modifier = owner:FindModifierByName("modifier_alice_power666")
|
||||
if modifier == nil then
|
||||
owner:FindAbilityByName("thtd_alice_01"):ApplyDataDrivenModifier(owner, owner, "modifier_alice_power666", {Duration=10.0})
|
||||
else
|
||||
modifier:SetDuration(10.0, false)
|
||||
end
|
||||
end
|
||||
caster:AddNoDraw()
|
||||
caster:ForceKill(false)
|
||||
return nil
|
||||
end,
|
||||
0.5)
|
||||
end
|
||||
|
||||
function OnAlice02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"alice_falanxi_ningyou"
|
||||
,caster:GetOrigin() + caster:GetForwardVector() * 500
|
||||
,false
|
||||
,caster:GetOwner()
|
||||
,caster:GetOwner()
|
||||
,caster:GetTeam()
|
||||
)
|
||||
if unit == nil then
|
||||
keys.ability:EndCooldown()
|
||||
return
|
||||
end
|
||||
Margatroid_CreateLine(caster, unit)
|
||||
FindClearSpaceForUnit(unit, unit:GetOrigin(), false)
|
||||
unit:SetControllableByPlayer(caster:GetPlayerOwnerID(), false)
|
||||
unit:SetHasInventory(false)
|
||||
unit.thtd_spawn_unit_owner = caster
|
||||
|
||||
local oldSwpanUnit = caster.thtd_summon_unit
|
||||
if oldSwpanUnit ~=nil and oldSwpanUnit:IsNull() == false then
|
||||
oldSwpanUnit:AddNoDraw()
|
||||
oldSwpanUnit:ForceKill(false)
|
||||
end
|
||||
caster.thtd_summon_unit = unit
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_alice_02", nil)
|
||||
|
||||
local powerStack = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_alice_02")
|
||||
if pv ~= nil then
|
||||
powerStack = pv[1]
|
||||
end
|
||||
|
||||
local hero = caster:GetOwner()
|
||||
if GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"] > 0 or powerStack > 0 then
|
||||
unit:AddNewModifier(unit, nil, "modifier_bb_buff_3016_effect", nil):SetStackCount(GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"] + powerStack)
|
||||
end
|
||||
|
||||
-- local ability = unit:FindAbilityByName("doom_bringer_infernal_blade")
|
||||
unit:SetContextThink(DoUniqueString("modifier_alice_02"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster==nil or caster:IsNull() or caster:IsAlive()==false or caster:THTD_IsHidden() then
|
||||
ParticleManager:DestroyParticleSystem(unit.effect_line, true)
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
caster.thtd_summon_unit = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
unit:SetBaseDamageMax(caster:THTD_GetAttack())
|
||||
unit:SetBaseDamageMin(caster:THTD_GetAttack())
|
||||
|
||||
if GetDistanceBetweenTwoVec2D(caster:GetOrigin(), unit:GetOrigin()) > 1000 then
|
||||
local forward = (unit:GetAbsOrigin() - caster:GetAbsOrigin()):Normalized()
|
||||
unit:MoveToPosition(caster:GetOrigin() + forward*1000)
|
||||
end
|
||||
|
||||
return 0.3
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnAlice02Ningyou01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local owner = caster.thtd_spawn_unit_owner
|
||||
local particle = ParticleManager:CreateParticle("particles/units/heroes/hero_techies/techies_land_mine_explode.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,target:GetOrigin()+Vector(0,0,64))
|
||||
ParticleManager:DestroyParticleSystem(particle,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(owner, target:GetOrigin(), keys.range)
|
||||
local damage = owner:THTD_GetStarDamage() * keys.power_damage * (owner.thtd_alice03_damage_up or 1)
|
||||
if owner:HasModifier("modifier_alice_power666") then
|
||||
damage = damage * 3
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = owner,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnAlice02Ningyou02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex) --buff提供者
|
||||
local target = keys.target -- 被攻击目标
|
||||
|
||||
if RollPercentage(keys.CritChance) then
|
||||
UnitDamageHpRemove(caster.thtd_spawn_unit_owner, target, keys.CritHealth)
|
||||
end
|
||||
end
|
||||
|
||||
function OnAlice04SpellStart(keys)
|
||||
local caster=keys.caster
|
||||
local caster_pos=caster:GetOrigin()
|
||||
local direction=(keys.target:GetOrigin()-caster_pos):Normalized()
|
||||
local base_pos=caster_pos-direction*keys.Radius
|
||||
|
||||
caster:MoveToTargetToAttack(keys.target)
|
||||
caster.thtd_alice03_damage_up = keys.damage_up
|
||||
|
||||
local dolls_and_pos={} -- [doll,start_pos]
|
||||
|
||||
local start_pos=base_pos
|
||||
local doll0=Margatroid_CreateDoll(caster,caster_pos+(start_pos-caster_pos):Normalized()*20,direction)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, doll0, "modifier_alice_04_rooted", {})
|
||||
dolls_and_pos[1]={doll=doll0,start_pos=start_pos}
|
||||
|
||||
local rotate_angle=QAngle(0,35,0)
|
||||
local start_pos=RotatePosition(caster_pos,rotate_angle,base_pos)
|
||||
local doll=Margatroid_CreateDoll(caster,caster_pos+(start_pos-caster_pos):Normalized()*20,direction)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, doll, "modifier_alice_04_rooted", {})
|
||||
dolls_and_pos[2]={doll=doll,start_pos=start_pos}
|
||||
|
||||
local rotate_angle=QAngle(0,-35,0)
|
||||
local start_pos=RotatePosition(caster_pos,rotate_angle,base_pos)
|
||||
local doll=Margatroid_CreateDoll(caster,caster_pos+(start_pos-caster_pos):Normalized()*20,direction)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, doll, "modifier_alice_04_rooted", {})
|
||||
dolls_and_pos[3]={doll=doll,start_pos=start_pos}
|
||||
|
||||
local rotate_angle=QAngle(0,70,0)
|
||||
local start_pos=RotatePosition(caster_pos,rotate_angle,base_pos)
|
||||
local doll=Margatroid_CreateDoll(caster,caster_pos+(start_pos-caster_pos):Normalized()*20,direction)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, doll, "modifier_alice_04_rooted", {})
|
||||
dolls_and_pos[4]={doll=doll,start_pos=start_pos}
|
||||
|
||||
local rotate_angle=QAngle(0,-70,0)
|
||||
local start_pos=RotatePosition(caster_pos,rotate_angle,base_pos)
|
||||
local doll=Margatroid_CreateDoll(caster,caster_pos+(start_pos-caster_pos):Normalized()*20,direction)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, doll, "modifier_alice_04_rooted", {})
|
||||
dolls_and_pos[5]={doll=doll,start_pos=start_pos}
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_alice_03")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
for _,tab in pairs(dolls_and_pos) do
|
||||
local OnDollFinshMove=
|
||||
function (hDoll)
|
||||
local doll_pos=hDoll:GetOrigin()
|
||||
local target_dir=direction
|
||||
hDoll:SetForwardVector(target_dir)
|
||||
local time = (keys.max_count - 1) * 0.4
|
||||
local caster = hDoll.thtd_spawn_unit_owner
|
||||
|
||||
hDoll:SetContextThink(
|
||||
DoUniqueString("margatroid02_action_delay"),
|
||||
function ()
|
||||
if caster==nil or caster:IsNull() or caster:IsAlive()==false or caster:THTD_IsHidden() or time <= 0 then
|
||||
ParticleManager:DestroyParticleSystem(hDoll.effect_line ,false)
|
||||
hDoll:AddNoDraw()
|
||||
hDoll:ForceKill(false)
|
||||
if caster ~= nil then caster.thtd_alice03_damage_up = nil end
|
||||
return nil
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/alice/ability_alice_02.vpcf", PATTACH_CUSTOMORIGIN, hDoll)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, hDoll:GetAttachmentOrigin(hDoll:ScriptLookupAttachment("attach_attack1"))+Vector(0,0,30))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, hDoll:GetOrigin()+hDoll:GetForwardVector()*keys.Distance)
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, hDoll:GetAttachmentOrigin(hDoll:ScriptLookupAttachment("attach_attack1"))+Vector(0,0,30))
|
||||
hDoll:EmitSound("Voice_Thdots_Alice.AbilityAlice011")
|
||||
|
||||
-- local angles=VectorToAngles(target_dir)
|
||||
-- angles.y=-angles.y
|
||||
-- --print("x0="..tostring(target_dir.x).." y0="..tostring(target_dir.y).." z0="..tostring(target_dir.z))
|
||||
-- --print("x1="..tostring(angles.x).." y1="..tostring(angles.y).." z1="..tostring(angles.z))
|
||||
-- local rotate_angle=angles
|
||||
-- local enemies=FindUnitsInRadius(
|
||||
-- caster:GetTeamNumber(),
|
||||
-- doll_pos+target_dir*keys.Distance*0.5,
|
||||
-- nil,
|
||||
-- keys.Distance,
|
||||
-- DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
-- DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
-- DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
-- FIND_ANY_ORDER,
|
||||
-- false)
|
||||
-- local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
-- for __,enemy in pairs(enemies) do
|
||||
-- local after_rotate_pos=RotatePosition(doll_pos,rotate_angle,enemy:GetOrigin())
|
||||
-- if math.abs(after_rotate_pos.y-doll_pos.y)<keys.LaserRadius then
|
||||
-- local DamageTable = {
|
||||
-- ability = keys.ability,
|
||||
-- victim = enemy,
|
||||
-- attacker = caster,
|
||||
-- damage = damage,
|
||||
-- damage_type = keys.ability:GetAbilityDamageType(),
|
||||
-- damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
-- }
|
||||
-- UnitDamageTarget(DamageTable)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
if hDoll == doll0 then
|
||||
-- print("-----------first")
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
hDoll:GetOrigin(),
|
||||
hDoll:GetOrigin() + hDoll:GetForwardVector()*keys.Distance,
|
||||
nil,
|
||||
keys.Radius,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (caster.thtd_alice03_damage_up or 1) * (1 + powerDamage/100)
|
||||
if caster:HasModifier("modifier_alice_power666") then
|
||||
damage = damage * 3
|
||||
end
|
||||
if caster:IsPower999() then
|
||||
damage = damage * 5
|
||||
end
|
||||
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
|
||||
end
|
||||
|
||||
time = time - 0.4
|
||||
return 0.4
|
||||
end,
|
||||
0)
|
||||
end
|
||||
if tab.doll then
|
||||
Margatroid_MoveDoll(
|
||||
tab.doll,
|
||||
tab.start_pos,
|
||||
keys.Radius*2,
|
||||
OnDollFinshMove,false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Margatroid_CreateDoll(hCaster, vecPos, vecForward)
|
||||
local doll=CreateUnitByName(
|
||||
"alice_boom",
|
||||
vecPos,
|
||||
false,
|
||||
hCaster,
|
||||
hCaster,
|
||||
hCaster:GetTeam()
|
||||
)
|
||||
doll.thtd_spawn_unit_owner = hCaster
|
||||
Margatroid_CreateLine(hCaster,doll)
|
||||
|
||||
if vecForward then
|
||||
local angles = VectorToAngles(vecForward)
|
||||
doll:SetAngles(angles.x,angles.y,angles.z)
|
||||
end
|
||||
return doll
|
||||
end
|
||||
|
||||
function Margatroid_MoveDoll(hDoll, vecTarget, fMoveSpeed, fnOnFinshMove,isfly)
|
||||
local tick_interval=0.03
|
||||
|
||||
local distance=(hDoll:GetOrigin()-vecTarget):Length()
|
||||
local vecMove=(hDoll:GetOrigin()-vecTarget):Normalized()*fMoveSpeed*tick_interval
|
||||
local tick=math.floor(distance/(fMoveSpeed*tick_interval))
|
||||
local finish_move=false
|
||||
hDoll:SetContextThink(
|
||||
DoUniqueString("margatroid_move_doll"),
|
||||
function ()
|
||||
hDoll:SetAbsOrigin(GetGroundPosition(hDoll:GetOrigin()+vecMove,hDoll))
|
||||
tick=tick-1
|
||||
if tick<=0 then
|
||||
if fnOnFinshMove then fnOnFinshMove(hDoll) end
|
||||
return nil
|
||||
end
|
||||
return tick_interval
|
||||
end,0)
|
||||
end
|
||||
|
||||
function Margatroid_CreateLine(caster,doll)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/alice/ability_alice_line.vpcf", PATTACH_CUSTOMORIGIN, doll)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_line", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, doll, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
doll.effect_line = effectIndex
|
||||
end
|
||||
368
scripts/vscripts/abilities/abilityaya.lua
Executable file
368
scripts/vscripts/abilities/abilityaya.lua
Executable file
@@ -0,0 +1,368 @@
|
||||
function OnAya01RandomSuccess(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
OnAya01AttackEffectSuccess(keys,caster,target)
|
||||
end
|
||||
|
||||
function OnAya01AttackEffectSuccess(keys,caster,target)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_aya/ability_aya_01.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+caster:GetForwardVector()*60)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local ability = caster:FindAbilityByName("thtd_aya_01")
|
||||
local range = ability:GetSpecialValueFor("range")
|
||||
|
||||
if target:HasModifier("modifier_aya01_news_buff") == false then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_aya/ability_aya_01_news.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
ability:ApplyDataDrivenModifier(caster,target,"modifier_aya01_news_buff", nil)
|
||||
end
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_aya_01")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
local targets = THTD_FindUnitsInRadius(caster, target:GetOrigin(), range)
|
||||
for _,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/windrunner/windrunner_cape_cascade/windrunner_windrun_cascade.vpcf",PATTACH_CUSTOMORIGIN,nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,2)
|
||||
|
||||
if caster:FindAbilityByName("thtd_aya_03"):GetLevel() > 0 then
|
||||
caster:FindAbilityByName("thtd_aya_02"):EndCooldown()
|
||||
end
|
||||
end
|
||||
|
||||
function OnAya01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local entities = THTD_FindUnitsAll(caster)
|
||||
for k,v in pairs(entities) do
|
||||
local modifier = v:FindModifierByName("modifier_aya01_news_buff")
|
||||
if modifier == nil then
|
||||
modifier = v:FindModifierByName("modifier_hatate01_news_buff")
|
||||
end
|
||||
if modifier ~= nil then
|
||||
local count = modifier:GetStackCount()
|
||||
if count < 999 then
|
||||
modifier:SetStackCount(count + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAttack() * GetAyaBuffCrit(caster, target),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
function GetAyaBuffCrit(caster, target)
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_aya_01")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[2]
|
||||
end
|
||||
|
||||
local damage_up = caster:GetAbilityValue("thtd_aya_01", "damage_up") + powerDamage
|
||||
if caster:IsPower999() then
|
||||
damage_up = damage_up + 4
|
||||
end
|
||||
|
||||
local crit = 1.0
|
||||
local modifier = target:FindModifierByName("modifier_aya01_news_buff")
|
||||
if modifier == nil then
|
||||
modifier = target:FindModifierByName("modifier_hatate01_news_buff")
|
||||
end
|
||||
if modifier ~= nil then
|
||||
crit = crit + modifier:GetStackCount() * damage_up / 100
|
||||
end
|
||||
if caster:IsPower666() then
|
||||
crit = crit * 4
|
||||
end
|
||||
return crit
|
||||
end
|
||||
|
||||
function OnAya02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
local rad = GetRadBetweenTwoVec2D(caster:GetOrigin(),targetPoint)
|
||||
|
||||
caster:StartGesture(ACT_DOTA_CAST_ABILITY_2)
|
||||
caster:SetForwardVector(Vector(math.cos(rad),math.sin(rad),0))
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_aya_02_pause", nil)
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_aya_02")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
caster.last_start_point = caster:GetAbsOrigin()
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("ability_aya_02_move"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if GetDistanceBetweenTwoVec2D(caster:GetOrigin(), targetPoint) >= 90 and GetDistanceBetweenTwoVec2D(caster:GetOrigin(), targetPoint) < keys.ability:GetCastRange()
|
||||
and caster:HasModifier("modifier_touhoutd_release_hidden") == false then
|
||||
local vOrgin = caster:GetOrigin()
|
||||
local vCurrent = vOrgin + Vector(math.cos(rad),math.sin(rad),0)*90
|
||||
caster:SetAbsOrigin(vCurrent)
|
||||
count = count + 1
|
||||
if count >= 5 then
|
||||
count = 0
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster.last_start_point,
|
||||
vCurrent,
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
caster.last_start_point = vCurrent
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
for _,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * GetAyaBuffCrit(caster, v),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
|
||||
if caster:FindAbilityByName("thtd_aya_03"):GetLevel() > 0 then
|
||||
OnAyaAttack(keys,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local vCurrent = caster:GetAbsOrigin()
|
||||
FindClearSpaceForUnit(caster, vCurrent, false)
|
||||
caster:THTD_DestroyLevelEffect()
|
||||
caster:THTD_CreateLevelEffect()
|
||||
caster:RemoveGesture(ACT_DOTA_CAST_ABILITY_2)
|
||||
caster:RemoveModifierByName("modifier_aya_02_pause")
|
||||
if count > 0 then
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster.last_start_point,
|
||||
vCurrent,
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
for _,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * GetAyaBuffCrit(caster, v),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
|
||||
if caster:FindAbilityByName("thtd_aya_03"):GetLevel() > 0 then
|
||||
OnAyaAttack(keys,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03)
|
||||
end
|
||||
|
||||
function OnAyaAttack(keys,target)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster:HasModifier("modifier_eirin_02_spell_buff") then
|
||||
local eirin = caster:FindModifierByName("modifier_eirin_02_spell_buff"):GetCaster()
|
||||
if eirin ~= nil then
|
||||
OnAyaLinkToEirin01(eirin,target,caster)
|
||||
end
|
||||
end
|
||||
|
||||
if caster:HasModifier("modifier_item_2011_attack_stun") then
|
||||
--todo
|
||||
end
|
||||
|
||||
-- 基本上可叠 300 - 700 层
|
||||
local entities = THTD_FindUnitsAll(caster)
|
||||
for k,v in pairs(entities) do
|
||||
local modifier = v:FindModifierByName("modifier_aya01_news_buff")
|
||||
if modifier == nil then
|
||||
modifier = v:FindModifierByName("modifier_hatate01_news_buff")
|
||||
end
|
||||
if modifier ~= nil then
|
||||
local count = modifier:GetStackCount()
|
||||
if count < 999 then
|
||||
modifier:SetStackCount(count + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAttack() * GetAyaBuffCrit(caster, target),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
|
||||
if RollPercentage(caster:GetAbilityValue("thtd_aya_01", "chance")) then
|
||||
OnAya01AttackEffectSuccess(keys,caster,target)
|
||||
end
|
||||
end
|
||||
|
||||
function OnAya03WingsSpellThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if keys.ability:GetLevel() < 1 then
|
||||
if caster.thtd_aya_03_wings~=nil and caster.thtd_aya_03_wings:IsNull()==false then
|
||||
caster.thtd_aya_03_wings:RemoveSelf()
|
||||
caster.thtd_aya_03_wings = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if caster.thtd_aya_03_wings == nil then
|
||||
caster.thtd_aya_03_wings = CreateUnitByName(
|
||||
"npc_unit_aya_03_wings",
|
||||
caster:GetOrigin(),
|
||||
false,
|
||||
caster,
|
||||
caster,
|
||||
caster:GetTeam()
|
||||
)
|
||||
caster.thtd_aya_03_wings:FollowEntity( caster, true )
|
||||
end
|
||||
end
|
||||
|
||||
function OnAyaLinkToEirin01(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 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
|
||||
|
||||
-- 同abilityeirin.lua
|
||||
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
|
||||
|
||||
371
scripts/vscripts/abilities/abilitybyakuren.lua
Executable file
371
scripts/vscripts/abilities/abilitybyakuren.lua
Executable file
@@ -0,0 +1,371 @@
|
||||
function OnByakuren01SpellStartUp(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
--解决浮点数精度问题
|
||||
local tick_step = math.floor(keys.tick_step * 100 + 0.5) / 100
|
||||
local min_tick = math.floor(keys.min_tick * 100 + 0.5) / 100
|
||||
local max_tick = math.floor(keys.max_tick * 100 + 0.5) / 100
|
||||
local base_tick = math.floor(keys.base_tick * 100 + 0.5) / 100
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time == nil then
|
||||
caster.thtd_byakuren_01_attack_time = base_tick
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_extra_damage == nil then
|
||||
caster.thtd_byakuren_01_extra_damage = 100
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time > min_tick then
|
||||
caster.thtd_byakuren_01_attack_time = caster.thtd_byakuren_01_attack_time - tick_step
|
||||
caster.thtd_byakuren_01_extra_damage = caster.thtd_byakuren_01_extra_damage - keys.extra_damage
|
||||
local modifier = caster:FindModifierByName("modifier_attack_time") or caster:AddNewModifier(caster, nil, "modifier_attack_time", {})
|
||||
if modifier ~= nil then
|
||||
if caster.thtd_byakuren_01_attack_time <= min_tick then
|
||||
modifier:SetStackCount((caster.thtd_byakuren_01_attack_time+tick_step)*10)
|
||||
else
|
||||
modifier:SetStackCount(caster.thtd_byakuren_01_attack_time*10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ByakurenUpdateBuff(caster)
|
||||
end
|
||||
|
||||
function OnByakuren01SpellStartDown(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
--解决浮点数精度问题
|
||||
local tick_step = math.floor(keys.tick_step * 100 + 0.5) / 100
|
||||
local min_tick = math.floor(keys.min_tick * 100 + 0.5) / 100
|
||||
local max_tick = math.floor(keys.max_tick * 100 + 0.5) / 100
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time == nil then
|
||||
caster.thtd_byakuren_01_attack_time = base_tick
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_extra_damage == nil then
|
||||
caster.thtd_byakuren_01_extra_damage = 100
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time < max_tick then
|
||||
caster.thtd_byakuren_01_attack_time = caster.thtd_byakuren_01_attack_time + tick_step
|
||||
caster.thtd_byakuren_01_extra_damage = caster.thtd_byakuren_01_extra_damage + keys.extra_damage
|
||||
local modifier = caster:FindModifierByName("modifier_attack_time") or caster:AddNewModifier(caster, nil, "modifier_attack_time", {})
|
||||
if modifier ~= nil then
|
||||
modifier:SetStackCount(caster.thtd_byakuren_01_attack_time*10)
|
||||
end
|
||||
end
|
||||
|
||||
ByakurenUpdateBuff(caster)
|
||||
end
|
||||
|
||||
function ByakurenUpdateBuff(caster)
|
||||
local ability = caster:FindAbilityByName("thtd_byakuren_01")
|
||||
local base_tick = math.floor(ability:GetSpecialValueFor("base_tick") * 100 + 0.5) / 100
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time == nil then
|
||||
caster.thtd_byakuren_01_attack_time = base_tick
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_extra_damage == nil then
|
||||
caster.thtd_byakuren_01_extra_damage = 100
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time > base_tick then
|
||||
caster:RemoveModifierByName("modifier_byakuren_attack_down")
|
||||
caster:RemoveModifierByName("modifier_byakuren_attack_equal")
|
||||
ability:ApplyDataDrivenModifier(caster, caster, "modifier_byakuren_attack_up", {})
|
||||
elseif caster.thtd_byakuren_01_attack_time == base_tick then
|
||||
caster:RemoveModifierByName("modifier_byakuren_attack_down")
|
||||
caster:RemoveModifierByName("modifier_byakuren_attack_up")
|
||||
ability:ApplyDataDrivenModifier(caster, caster, "modifier_byakuren_attack_equal", {})
|
||||
elseif caster.thtd_byakuren_01_attack_time < base_tick then
|
||||
caster:RemoveModifierByName("modifier_byakuren_attack_up")
|
||||
caster:RemoveModifierByName("modifier_byakuren_attack_equal")
|
||||
ability:ApplyDataDrivenModifier(caster, caster, "modifier_byakuren_attack_down", {})
|
||||
end
|
||||
local modifier = caster:FindModifierByName("modifier_byakuren_damage_percent") or ability:ApplyDataDrivenModifier(caster, caster, "modifier_byakuren_damage_percent", {})
|
||||
if modifier ~= nil then
|
||||
modifier:SetStackCount(caster.thtd_byakuren_01_extra_damage)
|
||||
end
|
||||
|
||||
local ability = caster:FindAbilityByName("thtd_byakuren_04")
|
||||
if ability:GetLevel() > 0 then
|
||||
if caster.thtd_byakuren_01_attack_time > base_tick then
|
||||
if caster:HasModifier("modifier_byakuren_04_magic_buff") == false then
|
||||
ability:ApplyDataDrivenModifier(caster,caster,"modifier_byakuren_04_magic_buff", nil)
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_physical_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_physical_buff")
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_pure_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_pure_buff")
|
||||
end
|
||||
elseif caster.thtd_byakuren_01_attack_time == base_tick then
|
||||
if caster:HasModifier("modifier_byakuren_04_pure_buff") == false then
|
||||
ability:ApplyDataDrivenModifier(caster,caster,"modifier_byakuren_04_pure_buff", nil)
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_magic_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_magic_buff")
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_physical_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_physical_buff")
|
||||
end
|
||||
elseif caster.thtd_byakuren_01_attack_time < base_tick then
|
||||
if caster:HasModifier("modifier_byakuren_04_magic_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_magic_buff")
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_pure_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_pure_buff")
|
||||
end
|
||||
end
|
||||
else
|
||||
if caster:HasModifier("modifier_byakuren_04_physical_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_physical_buff")
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_pure_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_pure_buff")
|
||||
end
|
||||
if caster:HasModifier("modifier_byakuren_04_magic_buff") then
|
||||
caster:RemoveModifierByName("modifier_byakuren_04_magic_buff")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnByakuren01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_byakuren_01_extra_damage == nil then
|
||||
caster.thtd_byakuren_01_extra_damage = 100
|
||||
end
|
||||
|
||||
local factor = 1 + THTD_GetStarLotusBuffedTowerCount(caster) * keys.damage_up / 100
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * factor * caster.thtd_byakuren_01_extra_damage / 100
|
||||
|
||||
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,
|
||||
}
|
||||
local base_tick = math.floor(keys.base_tick * 100 + 0.5) / 100
|
||||
if caster.thtd_byakuren_01_attack_time == base_tick then
|
||||
damage_table.damage_type = DAMAGE_TYPE_PURE
|
||||
elseif caster.thtd_byakuren_01_attack_time > base_tick then
|
||||
damage_table.damage_type = DAMAGE_TYPE_MAGICAL
|
||||
elseif caster.thtd_byakuren_01_attack_time < base_tick then
|
||||
damage_table.damage_type = DAMAGE_TYPE_PHYSICAL
|
||||
end
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
local particle = ParticleManager:CreateParticle("particles/units/heroes/hero_abaddon/abaddon_aphotic_shield_explosion.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,target:GetOrigin()+Vector(0,0,64))
|
||||
ParticleManager:DestroyParticleSystem(particle,false)
|
||||
end
|
||||
|
||||
function OnByakuren03SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
if keys.ability == nil or keys.ability:GetLevel() < 1 then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetOrigin(),2500)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if v:HasModifier("modifier_byakuren_03_buff") == false then
|
||||
if THTD_IsStarLotusTower(v) then
|
||||
if v.thtd_byakuren_03_religious_count == nil then
|
||||
v.thtd_byakuren_03_religious_count = 0
|
||||
end
|
||||
v.thtd_byakuren_03_religious_count = v.thtd_byakuren_03_religious_count + 1
|
||||
SendOverheadEventMessage(v:GetPlayerOwner(), OVERHEAD_ALERT_BONUS_POISON_DAMAGE, v, v.thtd_byakuren_03_religious_count, v:GetPlayerOwner() )
|
||||
if v.thtd_byakuren_03_religious_count > 6000 then
|
||||
local unitName = v:GetUnitName()
|
||||
if unitName == "nazrin" then
|
||||
v.thtd_byakuren_buff_nazrin = keys.ability:GetSpecialValueFor("nazrin")
|
||||
elseif unitName == "toramaru" then
|
||||
v.thtd_byakuren_buff_toramaru = keys.ability:GetSpecialValueFor("toramaru")
|
||||
elseif unitName == "kogasa" then
|
||||
v.thtd_byakuren_buff_kogasa = keys.ability:GetSpecialValueFor("kogasa")
|
||||
elseif unitName == "nue" then
|
||||
v.thtd_byakuren_buff_nue = keys.ability:GetSpecialValueFor("nue")
|
||||
elseif unitName == "minamitsu" then
|
||||
v.thtd_byakuren_buff_minamitsu = keys.ability:GetSpecialValueFor("minamitsu")
|
||||
elseif unitName == "kyouko" then
|
||||
v.thtd_byakuren_buff_kyouko = keys.ability:GetSpecialValueFor("kyouko")
|
||||
end
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_byakuren_03_buff", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local thtd_byakuren_04_point =
|
||||
{
|
||||
[1] = Vector(-340,-145,32),
|
||||
[2] = Vector(340,-145,32),
|
||||
[3] = Vector(-185,220,32),
|
||||
[0] = Vector(185,220,32),
|
||||
}
|
||||
|
||||
function OnByakuren04AttackLanded(keys)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_byakuren_04_init ~= true then
|
||||
caster.thtd_byakuren_04_init = true
|
||||
ByakurenUpdateBuff(caster)
|
||||
end
|
||||
|
||||
local base_tick = math.floor(caster:GetAbilityValue("thtd_byakuren_01", "base_tick") * 100 + 0.5) / 100
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time == nil then
|
||||
caster.thtd_byakuren_01_attack_time = base_tick
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_extra_damage == nil then
|
||||
caster.thtd_byakuren_01_extra_damage = 100
|
||||
end
|
||||
|
||||
|
||||
local buffedCount = THTD_GetStarLotusBuffedTowerCount(caster)
|
||||
local buffedBonus = keys.power_bonus
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time > base_tick then
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),keys.range)
|
||||
if #targets > 0 then
|
||||
local count = 1
|
||||
local outCount = math.floor((keys.damage_count + buffedCount - 1)/#targets) + 1
|
||||
local damageCount = {}
|
||||
for iOut=1,outCount do
|
||||
for i=1,#targets do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_byakuren/ability_byakuren_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+thtd_byakuren_04_point[count%4])
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targets[i]:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targets[i]:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, caster:GetOrigin()+thtd_byakuren_04_point[count%4])
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_byakuren/ability_byakuren_04_item.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+thtd_byakuren_04_point[count%4])
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,1.0)
|
||||
|
||||
damageCount[i] = (damageCount[i] or 0) + 1
|
||||
count = count + 1
|
||||
if count > (keys.damage_count + buffedCount) then
|
||||
break
|
||||
end
|
||||
end
|
||||
if count > (keys.damage_count + buffedCount) then
|
||||
break
|
||||
end
|
||||
end
|
||||
-- PrintTable(damageCount)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (caster.thtd_byakuren_01_extra_damage/100) * (1 + buffedCount * buffedBonus/100)
|
||||
for i=1,#targets do
|
||||
if damageCount[i] ~= nil then
|
||||
local damage_table = {
|
||||
victim = targets[i],
|
||||
attacker = caster,
|
||||
damage = damage * damageCount[i],
|
||||
ability = keys.ability,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time == base_tick then
|
||||
if caster.thtd_byakuren_04_attack_count == nil then
|
||||
caster.thtd_byakuren_04_attack_count = 0
|
||||
end
|
||||
caster.thtd_byakuren_04_attack_count = caster.thtd_byakuren_04_attack_count + 1
|
||||
if caster.thtd_byakuren_04_attack_count >= keys.max_count / (1 + buffedCount * buffedBonus/100) then
|
||||
caster.thtd_byakuren_04_attack_count = 0
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + buffedCount * buffedBonus/100)
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
ability = keys.ability,
|
||||
damage_type = DAMAGE_TYPE_PURE,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
local particle = ParticleManager:CreateParticle("particles/heroes/byakuren/ability_byakuren_02.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,v:GetOrigin())
|
||||
ParticleManager:SetParticleControl(particle,1,v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(particle,false)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if caster.thtd_byakuren_01_attack_time < base_tick then
|
||||
if RollPercentage(keys.chance) and caster:HasModifier("modifier_byakuren_04_physical_buff") == false then
|
||||
caster.byakuren_04_power_bonus = buffedCount * buffedBonus
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_byakuren_04_physical_buff", {Duration = keys.duration_time})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedByakuren04PhysicalBuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_byakuren/ability_byakuren_04_phy.vpcf",PATTACH_CUSTOMORIGIN,target)
|
||||
ParticleManager:SetParticleControl(effectIndex,0,target:GetOrigin()+Vector(0,0,32))
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, keys.duration_time)
|
||||
target.thtd_byakuren_04_physical_buff_effect = effectIndex
|
||||
|
||||
local bonus = target.byakuren_04_power_bonus
|
||||
target:THTD_AddPowerPercentage(bonus, "thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddAttackPercentage(bonus, "thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddAttackSpeed(keys.attack_speed, "thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddBaseAttack(keys.attack_bonus, "thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddBasePower(keys.attack_bonus, "thtd_byakuren_04_physical_buff")
|
||||
end
|
||||
|
||||
function OnDestroyByakuren04PhysicalBuff(keys)
|
||||
local target = keys.target
|
||||
ParticleManager:DestroyParticleSystem(target.thtd_byakuren_04_physical_buff_effect, true)
|
||||
target:THTD_AddPowerPercentage("thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddAttackPercentage("thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddAttackSpeed("thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddBaseAttack("thtd_byakuren_04_physical_buff")
|
||||
target:THTD_AddBasePower("thtd_byakuren_04_physical_buff")
|
||||
end
|
||||
|
||||
function OnCreatedByakuren04PureBuff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddCritDamage(keys.crit_damage, "thtd_byakuren_04_pure_buff")
|
||||
target:THTD_AddCritChance(keys.crit_change, "thtd_byakuren_04_pure_buff")
|
||||
end
|
||||
|
||||
function OnDestroyByakuren04PureBuff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddCritDamage("thtd_byakuren_04_pure_buff")
|
||||
target:THTD_AddCritChance("thtd_byakuren_04_pure_buff")
|
||||
end
|
||||
|
||||
|
||||
function OnCreatedByakuren04Buff(keys)
|
||||
keys.target:AddDamageOutgoingMagical(keys.penetration, "thtd_byakuren_04_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyByakuren04Buff(keys)
|
||||
keys.target:AddDamageOutgoingMagical("thtd_byakuren_04_damage_up")
|
||||
end
|
||||
64
scripts/vscripts/abilities/abilitychen.lua
Executable file
64
scripts/vscripts/abilities/abilitychen.lua
Executable file
@@ -0,0 +1,64 @@
|
||||
function OnChen01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
local rad = GetRadBetweenTwoVec2D(caster:GetOrigin(),targetPoint)
|
||||
|
||||
caster.thtd_chen_01_last_origin = caster:GetOrigin()
|
||||
caster:StartGesture(ACT_DOTA_CAST_ABILITY_1)
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_chen_01_pause", nil)
|
||||
caster:SetContextThink(DoUniqueString("ability_chen_01_move"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if GetDistanceBetweenTwoVec2D(caster:GetOrigin(), targetPoint)>=30 and GetDistanceBetweenTwoVec2D(caster:GetOrigin(), targetPoint)<keys.ability:GetCastRange()
|
||||
and caster:THTD_IsHidden() == false then
|
||||
caster:SetAbsOrigin(caster:GetOrigin() + Vector(math.cos(rad),math.sin(rad),0)*30)
|
||||
else
|
||||
FindClearSpaceForUnit(caster, caster:GetOrigin(), false)
|
||||
caster:THTD_DestroyLevelEffect()
|
||||
caster:THTD_CreateLevelEffect()
|
||||
caster:RemoveGesture(ACT_DOTA_CAST_ABILITY_1)
|
||||
caster:RemoveModifierByName("modifier_chen_01_pause")
|
||||
return nil
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03)
|
||||
end
|
||||
|
||||
function OnChen01SpellThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_chen_01_vector == nil then
|
||||
caster.thtd_chen_01_vector = caster:GetOrigin()
|
||||
end
|
||||
|
||||
if caster.thtd_chen_01_distance_increase == nil then
|
||||
caster.thtd_chen_01_distance_increase = 100
|
||||
end
|
||||
|
||||
local dis = GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_chen_01_vector)
|
||||
if dis > 30 and caster:THTD_IsHidden()==false then
|
||||
caster.thtd_chen_01_vector = caster:GetOrigin()
|
||||
caster:EmitSoundParams("Sound_THTD.thtd_chen_01",1.0,0.2*(1+(dis/caster.thtd_chen_01_distance_increase)/8),2.0)
|
||||
local increase = GetDistanceBetweenTwoVec2D(caster.thtd_chen_01_vector, caster.thtd_chen_01_last_origin)/caster.thtd_chen_01_distance_increase
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),400*(1+increase/8))
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * increase
|
||||
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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_chen/ability_chen_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(400*(1+increase/8),400*(1+increase/8),400*(1+increase/8)))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
end
|
||||
265
scripts/vscripts/abilities/abilitycirno.lua
Executable file
265
scripts/vscripts/abilities/abilitycirno.lua
Executable file
@@ -0,0 +1,265 @@
|
||||
function OnCirno02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local damagedGroup = {}
|
||||
|
||||
Cirno02PassToNextUnit(keys,target,damagedGroup)
|
||||
end
|
||||
|
||||
function Cirno02PassToNextUnit(keys,target,damagedGroup)
|
||||
if keys.ability == nil or keys.ability:IsNull() then
|
||||
damagedGroup = {}
|
||||
return
|
||||
end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.radius)
|
||||
|
||||
local powerCount = 0
|
||||
local powerDamage = 1
|
||||
local pv = caster:GetAbilityPowerValue("thtd_cirno_02")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
powerCount = pv[2]
|
||||
end
|
||||
|
||||
caster.thtd_cirno02_power_crit = powerDamage
|
||||
|
||||
if targets[1]==nil or #damagedGroup >= keys.unit_max_count then
|
||||
damagedGroup = {}
|
||||
return
|
||||
end
|
||||
if #damagedGroup == 0 then
|
||||
table.insert(damagedGroup,target)
|
||||
local count = keys.ice_count + powerCount
|
||||
caster:SetContextThink(DoUniqueString("thtd_cirno02_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local info =
|
||||
{
|
||||
Target = target,
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_cirno/ability_cirno_02.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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
if count > 0 then
|
||||
count = count - 1
|
||||
return 0.05
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
0.05)
|
||||
caster:SetContextThink(DoUniqueString("thtd_cirno02_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
Cirno02PassToNextUnit(keys,target,damagedGroup)
|
||||
return nil
|
||||
end,
|
||||
0.5)
|
||||
else
|
||||
for k,v in pairs(targets) do
|
||||
if v~=nil and v:IsNull()==false and THTD_IsUnitInGroup(v,damagedGroup) == false then
|
||||
table.insert(damagedGroup,v)
|
||||
local count = keys.ice_count + powerCount
|
||||
caster:SetContextThink(DoUniqueString("thtd_cirno02_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local info =
|
||||
{
|
||||
Target = v,
|
||||
Source = target,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_cirno/ability_cirno_02.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
|
||||
}
|
||||
projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
if count > 0 then
|
||||
count = count - 1
|
||||
return 0.05
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
0.05)
|
||||
caster:SetContextThink(DoUniqueString("thtd_cirno02_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
Cirno02PassToNextUnit(keys,v,damagedGroup)
|
||||
return nil
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCirno02SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * caster.thtd_cirno02_power_crit
|
||||
if caster:IsPower999() then
|
||||
damage = damage * 9
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
if RollPercentage(keys.chance) then
|
||||
local stuntime = keys.StunTime
|
||||
if caster:THTD_IsTowerEx() == true then
|
||||
stuntime = stuntime * (1 + keys.stun_up/100)
|
||||
end
|
||||
keys.ability:ApplyDataDrivenModifier(caster,target,"modifier_cirno_frozen_unit", {Duration = stuntime})
|
||||
end
|
||||
|
||||
if target.thtd_ability_cirno_02_damaged ~= true then
|
||||
target.thtd_ability_cirno_02_damaged = true
|
||||
|
||||
target:SetContextThink(DoUniqueString("thtd_ability_cirno_02_damaged"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
target.thtd_ability_cirno_02_damaged = false
|
||||
return nil
|
||||
end,
|
||||
3.0)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/cirno/ability_cirno_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_cirno_02")
|
||||
end
|
||||
end
|
||||
|
||||
function OnCirno03Attack(keys)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/cirno/ability_cirno_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
if caster:IsPower666() then
|
||||
damage = damage + 69 * caster:THTD_GetStarDamage()
|
||||
end
|
||||
if caster:IsPower999() then
|
||||
damage = damage * 9
|
||||
end
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
-- caster:PerformAttack(v,true,false,true,false,false,false,true) 造成攻击但不显示弹道
|
||||
if caster:IsPower666() then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_crystalmaiden/maiden_freezing_field_explosion.vpcf", PATTACH_CUSTOMORIGIN, v)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
function OnCirno04Attack(keys)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
if caster.thtd_cirno_04_attack_count == nil then
|
||||
caster.thtd_cirno_04_attack_count = 0
|
||||
end
|
||||
|
||||
caster.thtd_cirno_04_attack_count = caster.thtd_cirno_04_attack_count + 1
|
||||
|
||||
if caster.thtd_cirno_04_attack_count >= keys.max_count then
|
||||
caster.thtd_cirno_04_attack_count = 0
|
||||
local count = 1
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_cirno/ability_cirno_04_circle.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local powerDamage = 1
|
||||
local pv = caster:GetAbilityPowerValue("thtd_cirno_04")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * powerDamage
|
||||
if caster:IsPower999() then
|
||||
damage = damage * 9
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_cirno_04_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count%5 == 0 then
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * 5 * 0.05,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
if count > 40 then
|
||||
return nil
|
||||
end
|
||||
caster:EmitSound("Sound_THTD.thtd_cirno_04")
|
||||
count = count + 1
|
||||
return 0.05
|
||||
end,
|
||||
0.05)
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedCirnoExBuff(keys)
|
||||
keys.target:AddDamageOutgoingMagical(keys.damage_up, "thtd_cirno_ex_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyCirnoExBuff(keys)
|
||||
keys.target:AddDamageOutgoingMagical("thtd_cirno_ex_damage_up")
|
||||
end
|
||||
219
scripts/vscripts/abilities/abilityclownpiece.lua
Executable file
219
scripts/vscripts/abilities/abilityclownpiece.lua
Executable file
@@ -0,0 +1,219 @@
|
||||
function OnSpellStartClownpiece01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_clown_ball == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_moon.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.3,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(150,0,0))
|
||||
|
||||
caster.thtd_clown_ball =
|
||||
{
|
||||
["Vector"] = targetPoint + Vector(0,0,128),
|
||||
["EffectIndex"] = effectIndex
|
||||
}
|
||||
else
|
||||
caster.thtd_clown_ball["Vector"] = targetPoint + Vector(0,0,128)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster.thtd_clown_ball["Vector"])
|
||||
end
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]/100
|
||||
end
|
||||
|
||||
local range = keys.range
|
||||
local count = 1
|
||||
caster:SetContextThink(DoUniqueString("thtd_clownpiece_01_cast"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
count = count - 1
|
||||
if count < 0 then
|
||||
ClownpieceRemoveAllBall(keys)
|
||||
return nil
|
||||
end
|
||||
|
||||
for i=1,12 do
|
||||
local forward1 = Vector(math.cos(i*math.pi/6),math.sin(i*math.pi/6),0)
|
||||
local forward2 = Vector(math.cos(i*math.pi/6+math.pi/2),math.sin(i*math.pi/6+math.pi/2),0)
|
||||
local startPoint = caster.thtd_clown_ball["Vector"]
|
||||
local endPoint = caster.thtd_clown_ball["Vector"] + forward1 * range + Vector(0,0,128)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_reflex.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, startPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex , 1, endPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex , 9, startPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster.thtd_clown_ball["Vector"],range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + powerDamage)
|
||||
|
||||
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 0.5
|
||||
end,
|
||||
0.3)
|
||||
end
|
||||
|
||||
function ClownpieceRemoveAllBall(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_clown_ball ~= nil then
|
||||
local effectIndex = caster.thtd_clown_ball["EffectIndex"]
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
caster.thtd_clown_ball = nil
|
||||
end
|
||||
end
|
||||
|
||||
function OnSpellStartClownpiece02(keys)
|
||||
local caster = keys.caster
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_junko/ability_junko_03.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local powerRange = 0
|
||||
local powerDuration = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerRange = pv[1]
|
||||
powerDuration = pv[2]
|
||||
end
|
||||
|
||||
local radius = keys.radius + powerRange
|
||||
local duration_time = keys.duration_time + powerDuration
|
||||
local damage_up_other = keys.damage_up_other
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,radius)
|
||||
local count = #targets
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_clownpiece_debuff")
|
||||
if modifier==nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_clownpiece_debuff", {Duration = duration_time})
|
||||
else
|
||||
modifier:SetDuration(duration_time,false)
|
||||
end
|
||||
end
|
||||
|
||||
if count > 0 then
|
||||
local powerDamageUp = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_clownpiece_02")
|
||||
if pv ~= nil then
|
||||
powerDamageUp = pv[3]
|
||||
end
|
||||
local factor = powerDamageUp + keys.damage_up_self
|
||||
caster.thtd_clownpiece_02_buff_bonus = count * keys.damage_up_other
|
||||
caster.thtd_clownpiece_02_self_bonus = caster.thtd_clownpiece_02_buff_bonus * factor
|
||||
|
||||
local hero = caster:GetOwner()
|
||||
for k,v in pairs(hero.thtd_hero_tower_list) do
|
||||
local unitName = v:GetUnitName()
|
||||
if unitName == "clownpiece" or unitName == "lily" or unitName == "luna" or unitName == "star" or unitName == "sunny" or unitName == "cirno" or unitName == "daiyousei" or unitName == "mugiyousei" or unitName == "hanadayousei" or unitName == "maidyousei" then
|
||||
v:RemoveModifierByName("modifier_clownpiece_buff")
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_clownpiece_buff", {Duration = duration_time}):SetStackCount(count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedClownpiece02Buff(keys)
|
||||
if keys.target:GetUnitName() == "clownpiece" then
|
||||
keys.target:AddDamageOutgoingAll(keys.caster.thtd_clownpiece_02_self_bonus or 0, "thtd_clownpiece_02_bonus")
|
||||
else
|
||||
keys.target:AddDamageOutgoingAll(keys.caster.thtd_clownpiece_02_buff_bonus or 0, "thtd_clownpiece_02_bonus")
|
||||
end
|
||||
end
|
||||
|
||||
function OnDestroyClownpiece02Buff(keys)
|
||||
keys.target:AddDamageOutgoingAll("thtd_clownpiece_02_bonus")
|
||||
end
|
||||
|
||||
function OnSpellStartClownpiece03(keys)
|
||||
local caster = keys.caster
|
||||
local targetPoint = keys.target_points[1]
|
||||
local casterPoint = caster:GetAbsOrigin()
|
||||
local forward = (targetPoint - casterPoint):Normalized()
|
||||
|
||||
local powerDuration = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerDuration = pv[2]
|
||||
end
|
||||
|
||||
if caster:IsPower666() then
|
||||
for i=1,6 do
|
||||
local forward1 = Vector(math.cos(i*math.pi/3),math.sin(i*math.pi/3),0)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/jakiro/jakiro_ti8_immortal_head/jakiro_ti8_dual_breath_fire.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward1 * keys.distance)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
local targets = THTD_FindUnitsInRadius(caster,casterPoint,keys.distance + 100)
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_clownpiece_03_debuff", {Duration = keys.duration_time + powerDuration})
|
||||
end
|
||||
else
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/jakiro/jakiro_ti8_immortal_head/jakiro_ti8_dual_breath_fire.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward * keys.distance)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
-- local effectIndex2 = ParticleManager:CreateParticle("particles/econ/items/jakiro/jakiro_ti8_immortal_head/jakiro_ti8_dual_breath_ice.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
-- ParticleManager:SetParticleControl(effectIndex2, 0, casterPoint)
|
||||
-- ParticleManager:SetParticleControl(effectIndex2, 1, (targetPoint - casterPoint):Normalized() * 1000)
|
||||
-- ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
|
||||
local targets = FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
casterPoint,
|
||||
casterPoint + forward * (keys.distance + 100),
|
||||
nil,
|
||||
300,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_clownpiece_03_debuff", {Duration = keys.duration_time + powerDuration})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnThinkClownpiece03(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
if caster:IsPower666() then powerDamage = powerDamage + 30 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
if caster:IsPower999() then damage = damage * 3 end
|
||||
damage = damage * keys.tick
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
1438
scripts/vscripts/abilities/abilitycommon.lua
Executable file
1438
scripts/vscripts/abilities/abilitycommon.lua
Executable file
File diff suppressed because it is too large
Load Diff
227
scripts/vscripts/abilities/abilitydaiyousei.lua
Executable file
227
scripts/vscripts/abilities/abilitydaiyousei.lua
Executable file
@@ -0,0 +1,227 @@
|
||||
function OnDaiyousei01SpellStart(keys)
|
||||
if SpawnSystem.IsUnLimited then return end
|
||||
if GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target:GetPlayerOwnerID() ~= caster:GetPlayerOwnerID() then return end
|
||||
|
||||
caster:EmitSound("Hero_Enchantress.EnchantCreep")
|
||||
|
||||
if target:THTD_IsTower() and target~=caster and target:THTD_GetLevel()<THTD_MAX_LEVEL then
|
||||
target:THTD_LevelUp(keys.level_up)
|
||||
end
|
||||
|
||||
local count = keys.level_up - 1
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,target:GetOrigin(),1200)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if count > 0 and v:THTD_IsTower() and v~=caster and v:THTD_GetLevel()<THTD_MAX_LEVEL and v~=target then
|
||||
v:THTD_LevelUp(count)
|
||||
count = count - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnDaiyousei02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_daiyousei_02")
|
||||
|
||||
local targets =
|
||||
FindUnitsInRadius(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
nil,
|
||||
1000,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags(),
|
||||
FIND_ANY_ORDER,
|
||||
false
|
||||
)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/items/item_yatagarasu.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0 , caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if IsInDaiyousei02BlackList(v) == false then
|
||||
v:GiveMana(keys.mana_reg)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/daiyousei/ability_daiyousei_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0 , v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local daiyousei_02_black_list =
|
||||
{
|
||||
"lily",
|
||||
"daiyousei",
|
||||
"youmu",
|
||||
}
|
||||
|
||||
function IsInDaiyousei02BlackList(unit)
|
||||
for k,v in pairs(daiyousei_02_black_list) do
|
||||
if unit:GetUnitName() == v then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function OnDaiyousei03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if caster == target then return end
|
||||
if not target:THTD_IsTower() then return end
|
||||
if target:HasModifier("modifier_daiyousei_03") then return end
|
||||
if target:GetPlayerOwnerID() ~= caster:GetPlayerOwnerID() then return end
|
||||
|
||||
caster:EmitSound("Hero_Wisp.Tether.Target")
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_daiyousei_03", nil)
|
||||
local effectIndex = Daiyousei03CreateLine(caster,target)
|
||||
|
||||
local hasCombo = caster:HasModifier("modifier_thtd_daiyousei_03_combo_buff")
|
||||
if hasCombo then
|
||||
if THTD_IsValid(caster.ability_daiyousei_03_target1) == false then
|
||||
caster.ability_daiyousei_03_target1 = target
|
||||
elseif THTD_IsValid(caster.ability_daiyousei_03_target2) == false then
|
||||
caster.ability_daiyousei_03_target2 = target
|
||||
else
|
||||
caster.ability_daiyousei_03_target1 = caster.ability_daiyousei_03_target2
|
||||
caster.ability_daiyousei_03_target2 = target
|
||||
end
|
||||
else
|
||||
caster.ability_daiyousei_03_target1 = target
|
||||
end
|
||||
|
||||
target:SetContextThink(DoUniqueString("modifier_daiyousei_03"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
if target == nil or target:IsNull() or target:IsAlive() == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
if caster.ability_daiyousei_03_target1 == target then
|
||||
caster.ability_daiyousei_03_target1 = nil
|
||||
elseif caster.ability_daiyousei_03_target2 == target then
|
||||
caster.ability_daiyousei_03_target2 = nil
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local isCancel = false
|
||||
|
||||
if THTD_IsValid(caster) == false then
|
||||
isCancel = true
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
caster.ability_daiyousei_03_target1 = nil
|
||||
caster.ability_daiyousei_03_target2 = nil
|
||||
end
|
||||
else
|
||||
if caster:HasModifier("modifier_thtd_daiyousei_03_combo_buff") == false then
|
||||
if caster.ability_daiyousei_03_target2 ~= nil then
|
||||
caster.ability_daiyousei_03_target1 = caster.ability_daiyousei_03_target2
|
||||
caster.ability_daiyousei_03_target2 = nil
|
||||
end
|
||||
end
|
||||
isCancel = (caster.ability_daiyousei_03_target1 ~= target and caster.ability_daiyousei_03_target2 ~= target)
|
||||
end
|
||||
|
||||
if isCancel then
|
||||
if target:HasModifier("modifier_daiyousei_03") then
|
||||
target:RemoveModifierByName("modifier_daiyousei_03")
|
||||
end
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
if caster.ability_daiyousei_03_target1 == target then
|
||||
caster.ability_daiyousei_03_target1 = nil
|
||||
elseif caster.ability_daiyousei_03_target2 == target then
|
||||
caster.ability_daiyousei_03_target2 = nil
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function Daiyousei03CreateLine(caster,target)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/daiyousei/ability_daiyousei_03.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
return effectIndex
|
||||
end
|
||||
|
||||
function OnCreatedDaiyousei03Buff(keys)
|
||||
local target = keys.target
|
||||
local bonus = 0
|
||||
if target:GetUnitName() == "cirno" then
|
||||
bonus = keys.crino_up
|
||||
else
|
||||
bonus = keys.damage_up
|
||||
end
|
||||
target:AddDamageOutgoingMagical(bonus, "thtd_daiyousei_03_damage_up")
|
||||
end
|
||||
|
||||
function OnUpgradeDaiyousei03Buff(keys)
|
||||
local caster = keys.caster
|
||||
local targets = {}
|
||||
if caster.ability_daiyousei_03_target1 ~= nil then
|
||||
table.insert(targets, caster.ability_daiyousei_03_target1)
|
||||
end
|
||||
if caster.ability_daiyousei_03_target2 ~= nil then
|
||||
table.insert(targets, caster.ability_daiyousei_03_target2)
|
||||
end
|
||||
|
||||
for _,target in pairs(targets) do
|
||||
local bonus = 0
|
||||
if target:GetUnitName() == "cirno" then
|
||||
bonus = keys.crino_up
|
||||
else
|
||||
bonus = keys.damage_up
|
||||
end
|
||||
target:AddDamageOutgoingMagical(bonus, "thtd_daiyousei_03_damage_up")
|
||||
end
|
||||
|
||||
targets = {}
|
||||
end
|
||||
|
||||
function OnDestroyDaiyousei03Buff(keys)
|
||||
keys.target:AddDamageOutgoingMagical("thtd_daiyousei_03_damage_up")
|
||||
end
|
||||
|
||||
function OnDaiyousei04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_ability_daiyousei_04_lock == nil then caster.thtd_ability_daiyousei_04_lock = false end
|
||||
|
||||
if target:GetUnitName() == "cirno" and target:THTD_GetStar() == 5 and caster.thtd_ability_daiyousei_04_lock == false then
|
||||
target:EmitSound("Hero_Wisp.Tether")
|
||||
caster.thtd_ability_daiyousei_04_lock = true
|
||||
target:THTD_UpgradeEx()
|
||||
target:SetAttackCapability(DOTA_UNIT_CAP_MELEE_ATTACK)
|
||||
target:SetModel("models/new_touhou_model/cirno/ex/ex_cirno.vmdl")
|
||||
target:SetOriginalModel("models/new_touhou_model/cirno/ex/ex_cirno.vmdl")
|
||||
local modifier = target:AddNewModifier(target, nil, "modifier_attack_time", {})
|
||||
modifier:SetStackCount(6) -- 8对应0.8,5对应0.5,6对应0.6
|
||||
local mana_regen_ability =target:FindAbilityByName("ability_common_mana_regen_buff")
|
||||
if mana_regen_ability ~= nil then
|
||||
if mana_regen_ability:GetLevel() < mana_regen_ability:GetMaxLevel() then
|
||||
mana_regen_ability:SetLevel(5)
|
||||
end
|
||||
end
|
||||
|
||||
local ability = target:FindAbilityByName("thtd_cirno_01")
|
||||
if ability ~= nil and target:HasModifier("modifier_cirno_suwako_aura") == false then
|
||||
ability:ApplyDataDrivenModifier(target, target, "modifier_cirno_suwako_aura", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
324
scripts/vscripts/abilities/abilityeirin.lua
Executable file
324
scripts/vscripts/abilities/abilityeirin.lua
Executable file
@@ -0,0 +1,324 @@
|
||||
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
|
||||
217
scripts/vscripts/abilities/abilityflandre.lua
Executable file
217
scripts/vscripts/abilities/abilityflandre.lua
Executable file
@@ -0,0 +1,217 @@
|
||||
function OnFlandre01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_flandre_illusion_table == nil then
|
||||
caster.thtd_flandre_illusion_table = {}
|
||||
end
|
||||
|
||||
caster:EmitSound("Hero_PhantomLancer.Doppelganger.Appear")
|
||||
|
||||
for i=1,3 do
|
||||
local illusion = CreateUnitByName(
|
||||
"flandre_illusion",
|
||||
caster:GetOrigin() + Vector(math.cos(math.pi/2*(i+1)),math.sin(math.pi/2*(i+1)),0)*100,
|
||||
false,
|
||||
caster,
|
||||
caster,
|
||||
caster:GetTeam()
|
||||
)
|
||||
illusion:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
||||
illusion:MoveToPosition(illusion:GetOrigin()+Vector(0,-100,0))
|
||||
illusion:SetForwardVector(caster:GetForwardVector())
|
||||
keys.ability:ApplyDataDrivenModifier(caster, illusion, "modifier_flandre_01_illusion", nil)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_flandre/ability_flandre_02_fire.vpcf", PATTACH_CUSTOMORIGIN, illusion)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, illusion, 5, "attach_attack1", Vector(0,0,0), true)
|
||||
|
||||
caster.thtd_flandre_illusion_table[i] = illusion
|
||||
|
||||
local count = 0
|
||||
illusion:SetContextThink(DoUniqueString("thtd_flandre_01_illusion"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count > 20 or THTD_IsValid(caster) == false then
|
||||
illusion:AddNoDraw()
|
||||
illusion:ForceKill(true)
|
||||
return nil
|
||||
elseif caster:IsAttacking()==false then
|
||||
illusion:RemoveGesture(ACT_DOTA_ATTACK)
|
||||
illusion:MoveToPosition(illusion:GetOrigin()+Vector(0,-100,0))
|
||||
end
|
||||
count = count + 1
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
|
||||
function OnFlandre02Created(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_flandre/ability_flandre_02_fire.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_attack1", Vector(0,0,0), true)
|
||||
|
||||
caster.thtd_flandre_02_effectIndex = effectIndex
|
||||
end
|
||||
|
||||
function OnFlandre02AttackStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_flandre_illusion_table == nil then
|
||||
caster.thtd_flandre_illusion_table = {}
|
||||
end
|
||||
|
||||
for k,v in pairs(caster.thtd_flandre_illusion_table) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
local forward = (target:GetOrigin() - v:GetOrigin()):Normalized()
|
||||
v:StartGesture(ACT_DOTA_ATTACK)
|
||||
v:MoveToTargetToAttack(target)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnFlandre02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local ability4 = caster:FindAbilityByName("thtd_flandre_04")
|
||||
if ability4:GetLevel() >= 1 then
|
||||
if caster.lock_target ~= target then
|
||||
if THTD_IsValid(caster.lock_target) then
|
||||
caster.lock_target:RemoveModifierByName("modifier_flandre_damage_lock")
|
||||
end
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_flandre_damage_lock", {duration = 2.0})
|
||||
caster.lock_target = target
|
||||
else
|
||||
local modifier = target:FindModifierByName("modifier_flandre_damage_lock")
|
||||
if modifier ~= nil then
|
||||
modifier:SetDuration(2.0, false)
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_flandre_damage_lock", {duration = 2.0})
|
||||
end
|
||||
end
|
||||
if ability4:IsCooldownReady() then
|
||||
target.flandre_04_lock = true
|
||||
else
|
||||
target.flandre_04_lock = false
|
||||
end
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 4
|
||||
local crit = 1
|
||||
local ability3 = caster:FindAbilityByName("thtd_flandre_03")
|
||||
if ability3:GetLevel() > 0 then
|
||||
crit = 1 + (100 - target:GetHealthPercent()) * ability3:GetSpecialValueFor("damage_up") / 100
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
OnFlandre02SpellStart(caster)
|
||||
end
|
||||
|
||||
function OnFlandre02SpellStart(caster)
|
||||
local step = caster:GetAbilityValue("thtd_flandre_02", "damage_up") * 4
|
||||
local maxUp = caster:GetAbilityValue("thtd_flandre_02", "max_up")
|
||||
local duration = caster:GetAbilityValue("thtd_flandre_02", "duration_time")
|
||||
|
||||
if caster.thtd_flandre_02_outgoing == nil then
|
||||
caster.thtd_flandre_02_outgoing = 0
|
||||
end
|
||||
|
||||
local count = math.min(step, maxUp - caster.thtd_flandre_02_outgoing)
|
||||
if count > 0 then
|
||||
caster:AddDamageOutgoingPhysical(count)
|
||||
caster.thtd_flandre_02_outgoing = caster.thtd_flandre_02_outgoing + count
|
||||
caster:SetContextThink(DoUniqueString("modifier_flandre_02_buff_count"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
caster:AddDamageOutgoingPhysical(-count)
|
||||
caster.thtd_flandre_02_outgoing = caster.thtd_flandre_02_outgoing - count
|
||||
return nil
|
||||
end,
|
||||
duration)
|
||||
end
|
||||
end
|
||||
|
||||
function OnFlandre02Destroy(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_flandre_02_effectIndex,false)
|
||||
end
|
||||
|
||||
function OnCreatedFlandreLock(keys)
|
||||
local target = keys.target
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_bounty_hunter/bounty_hunter_track_trail.vpcf", PATTACH_POINT_FOLLOW, target)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, PATTACH_ABSORIGIN_FOLLOW, "attach_hitloc", target:GetAbsOrigin(), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, target, PATTACH_POINT_FOLLOW, "attach_hitloc", target:GetAbsOrigin(), true)
|
||||
target.flandre_damage_lock_effect1 = effectIndex
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_bounty_hunter/bounty_hunter_track_shield.vpcf", PATTACH_OVERHEAD_FOLLOW, target)
|
||||
target.flandre_damage_lock_effect2 = effectIndex
|
||||
|
||||
target.flandre_damage_lock = true
|
||||
end
|
||||
|
||||
function OnDestroyFlandreLock(keys)
|
||||
local target = keys.target
|
||||
ParticleManager:DestroyParticleSystem(target.flandre_damage_lock_effect1,true)
|
||||
ParticleManager:DestroyParticleSystem(target.flandre_damage_lock_effect2,true)
|
||||
target.flandre_damage_lock = false
|
||||
end
|
||||
|
||||
function OnFlandre04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local ability = keys.ability
|
||||
|
||||
if caster:IsPower999() then
|
||||
local bonusCastCount = 4
|
||||
caster:SetContextThink(DoUniqueString("thtd_flandre_04_power999"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if bonusCastCount <= 0 then return nil end
|
||||
if THTD_IsValid(caster) and THTD_IsValid(target) then
|
||||
Flandre04SpellCast(caster, target, ability)
|
||||
bonusCastCount = bonusCastCount - 1
|
||||
return 0.25
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
else
|
||||
Flandre04SpellCast(caster, target, ability)
|
||||
end
|
||||
end
|
||||
|
||||
function Flandre04SpellCast(caster, target, ability)
|
||||
-- target:StartGesture(ACT_DOTA_DIE)
|
||||
caster:EmitSound("Hero_DoomBringer.LvlDeath")
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability) * 4
|
||||
local crit = 1
|
||||
local ability3 = caster:FindAbilityByName("thtd_flandre_03")
|
||||
if ability3:GetLevel() > 0 then
|
||||
crit = 1 + (100 - target:GetHealthPercent()) * ability3:GetSpecialValueFor("damage_up") / 100
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
OnFlandre02SpellStart(caster)
|
||||
end
|
||||
|
||||
184
scripts/vscripts/abilities/abilityfuto.lua
Executable file
184
scripts/vscripts/abilities/abilityfuto.lua
Executable file
@@ -0,0 +1,184 @@
|
||||
function OnFuto01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_futo_01_effct_index == nil then
|
||||
caster.thtd_futo_01_effct_index = 1
|
||||
end
|
||||
|
||||
if caster.thtd_futo_01_effct_index == 1 then
|
||||
local damage = caster:THTD_GetStarDamage() * keys.damage1 * (1 + GetFuto02Buff(caster))
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
target:GetOrigin(),
|
||||
target:GetOrigin() + 800 * -target:GetForwardVector(),
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
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
|
||||
elseif caster.thtd_futo_01_effct_index == 2 then
|
||||
if caster.__foto_lock ~= true then
|
||||
caster.__foto_lock = true
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),1200)
|
||||
local damage = caster:THTD_GetStarDamage() * keys.damage2 * (1 + GetFuto02Buff(caster))
|
||||
for i=1,#targets do
|
||||
local unit = targets[i]
|
||||
if unit~=nil and unit:IsNull()==false and unit~=target and unit:IsAlive() then
|
||||
caster:PerformAttack(unit,false,false,false,false,true,false,false)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = unit,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
caster.__foto_lock = false
|
||||
end
|
||||
elseif caster.thtd_futo_01_effct_index == 3 then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetStarDamage() * keys.damage3 * 0.3 * (1 + GetFuto02Buff(caster))
|
||||
for k,v in pairs(targets) do
|
||||
local time = keys.duration_time
|
||||
v:AddPoison(1, caster)
|
||||
v:SetContextThink(DoUniqueString("thtd_futo_01_damage_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then
|
||||
v:AddPoison(-1)
|
||||
return nil
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
time = time - 0.3
|
||||
return 0.3
|
||||
end,
|
||||
0.3)
|
||||
end
|
||||
elseif caster.thtd_futo_01_effct_index == 4 then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetStarDamage() * keys.damage4 * (1 + GetFuto02Buff(caster))
|
||||
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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_futo/ability_thtd_futo_01_fire.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
elseif caster.thtd_futo_01_effct_index == 5 then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_futo_01_lock") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_futo_01_lock", {Duration = 1.0})
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
end
|
||||
elseif caster.thtd_futo_01_effct_index == 6 then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = keys.attack_damage * keys.crit * (1 + GetFuto02Buff(caster))
|
||||
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)
|
||||
SendOverheadEventMessage(caster:GetPlayerOwner(), OVERHEAD_ALERT_CRITICAL, v, damage, caster:GetPlayerOwner() )
|
||||
end
|
||||
end
|
||||
|
||||
caster.thtd_futo_01_effct_index = RandomInt(1,6)
|
||||
caster:SetRangedProjectileName("particles/heroes/thtd_futo/ability_futo_base_attack_"..caster.thtd_futo_01_effct_index..".vpcf")
|
||||
end
|
||||
|
||||
function OnFuto02Kill(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local modifier = caster:FindModifierByName("modifier_futo_02_buff")
|
||||
if modifier==nil then
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_futo_02_buff", {Duration = keys.duration_time})
|
||||
modifier:SetStackCount(1)
|
||||
else
|
||||
if modifier:GetStackCount() < keys.max_count then
|
||||
modifier:SetStackCount(modifier:GetStackCount()+1)
|
||||
end
|
||||
modifier:SetDuration(keys.duration_time,false)
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuto02Buff(caster)
|
||||
local modifier = caster:FindModifierByName("modifier_futo_02_buff")
|
||||
if modifier~=nil then
|
||||
return modifier:GetStackCount() * caster:GetAbilityValue("thtd_futo_02", "damage_up", true)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function OnFuto03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_futo/ability_thtd_futo_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local time = keys.duration_time
|
||||
caster:SetContextThink(DoUniqueString("thtd_futo_03_spell_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2 * (1 + GetFuto02Buff(caster))
|
||||
if caster:HasModifier("modifier_miko_02_buff") and caster.thtd_miko_buff_futo03 ~= nil then
|
||||
damage = damage * (1 + caster.thtd_miko_buff_futo03/100)
|
||||
end
|
||||
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
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
31
scripts/vscripts/abilities/abilityhanadayousei.lua
Executable file
31
scripts/vscripts/abilities/abilityhanadayousei.lua
Executable file
@@ -0,0 +1,31 @@
|
||||
function OnHanadayousei01Attack(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local powerCount = 0
|
||||
local powerRange = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerCount = pv[1]
|
||||
powerRange = pv[2]
|
||||
end
|
||||
|
||||
if caster.__hanadayousei_lock ~= true then
|
||||
caster.__hanadayousei_lock = true
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(), 800 + powerRange)
|
||||
local count = 0
|
||||
for i=1,#targets do
|
||||
local unit = targets[i]
|
||||
if unit~=nil and unit:IsNull()==false and unit~=target and unit:IsAlive() then
|
||||
caster:PerformAttack(unit,true,false,true,false,true,false,true)
|
||||
count = count + 1
|
||||
end
|
||||
if powerCount ~= 99 then
|
||||
if count >= (3 + powerCount) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
caster.__hanadayousei_lock = false
|
||||
end
|
||||
end
|
||||
112
scripts/vscripts/abilities/abilityhatate.lua
Executable file
112
scripts/vscripts/abilities/abilityhatate.lua
Executable file
@@ -0,0 +1,112 @@
|
||||
function OnHatate01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hatate/ability_hatate_01_news.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+caster:GetForwardVector()*60)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
for _,v in pairs(targets) do
|
||||
if v:HasModifier("modifier_hatate01_news_buff") == false and v:HasModifier("modifier_aya01_news_buff") == false then
|
||||
|
||||
end
|
||||
end
|
||||
local deal_damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_hatate01_news_buff")
|
||||
if modifier == nil then
|
||||
modifier = v:FindModifierByName("modifier_aya01_news_buff")
|
||||
end
|
||||
if modifier == nil then
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_hatate01_news_buff", nil)
|
||||
elseif modifier:GetStackCount() < 999 then
|
||||
modifier:IncrementStackCount()
|
||||
end
|
||||
local crit = 1.0
|
||||
if modifier ~= nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hatate/ability_hatate_01.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
crit = crit + modifier:GetStackCount() * caster:GetAbilityValue("thtd_hatate_01", "damage_up", true)
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = deal_damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
|
||||
function OnHatate01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.__thtd_hatate_01_lock == true then return end
|
||||
caster.__thtd_hatate_01_lock = true
|
||||
|
||||
local entities = THTD_FindUnitsAll(caster)
|
||||
for k,v in pairs(entities) do
|
||||
if v:HasModifier("modifier_hatate01_news_buff") or v:HasModifier("modifier_aya01_news_buff") then
|
||||
local modifier = v:FindModifierByName("modifier_hatate01_news_buff")
|
||||
if modifier == nil then
|
||||
modifier = v:FindModifierByName("modifier_aya01_news_buff")
|
||||
end
|
||||
if modifier == nil then
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_hatate01_news_buff", nil)
|
||||
elseif modifier:GetStackCount() < 999 then
|
||||
modifier:IncrementStackCount()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
caster.__thtd_hatate_01_lock = false
|
||||
end
|
||||
|
||||
function OnHatate02SpellStart(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local inners = THTD_FindUnitsInner(caster)
|
||||
local outers = THTD_FindUnitsOuter(caster)
|
||||
|
||||
for k,v in pairs(outers) do
|
||||
table.insert(inners,v)
|
||||
end
|
||||
|
||||
local deal_damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * keys.tick_time
|
||||
for k,v in pairs(inners) do
|
||||
local modifier = v:FindModifierByName("modifier_hatate01_news_buff")
|
||||
if modifier == nil then
|
||||
modifier = v:FindModifierByName("modifier_aya01_news_buff")
|
||||
end
|
||||
if modifier == nil then
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_hatate01_news_buff", nil)
|
||||
elseif modifier:GetStackCount() < 999 then
|
||||
modifier:IncrementStackCount()
|
||||
end
|
||||
if RandomInt(1,5) == 1 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hatate/ability_hatate_01.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
local crit = 1.0
|
||||
if modifier ~= nil then
|
||||
crit = crit + modifier:GetStackCount() * caster:GetAbilityValue("thtd_hatate_01", "damage_up", true)
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = deal_damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
890
scripts/vscripts/abilities/abilityhecatia.lua
Executable file
890
scripts/vscripts/abilities/abilityhecatia.lua
Executable file
@@ -0,0 +1,890 @@
|
||||
local thtd_hecatia_model_list =
|
||||
{
|
||||
[1] = "models/new_touhou_model/hecatia/hecatia_earth/hecatia_earth.vmdl",
|
||||
[2] = "models/new_touhou_model/hecatia/hecatia_moon/hecatia_moon.vmdl",
|
||||
[3] = "models/new_touhou_model/hecatia/hecatia.vmdl",
|
||||
}
|
||||
|
||||
local HECATIA_TYPE_EARTH = 1
|
||||
local HECATIA_TYPE_MOON = 2
|
||||
local HECATIA_TYPE_OTHERWORLD = 3
|
||||
|
||||
function OnHecatia01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_hecatia_ball_table == nil then
|
||||
caster.thtd_hecatia_ball_table = {}
|
||||
caster.thtd_hecatia_ball_table["earth"] = nil
|
||||
caster.thtd_hecatia_ball_table["moon"] = nil
|
||||
caster.thtd_hecatia_ball_table["otherworld"] = nil
|
||||
end
|
||||
|
||||
caster.thtd_hecatia_01_think_count = 0
|
||||
|
||||
if caster.thtd_hecatia_ball_table["earth"] == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_earth.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.4,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(200,0,0))
|
||||
|
||||
caster.thtd_hecatia_ball_table["earth"] =
|
||||
{
|
||||
["Vector"] = targetPoint + Vector(0,0,128),
|
||||
["EffectIndex"] = effectIndex
|
||||
}
|
||||
else
|
||||
caster.thtd_hecatia_ball_table["earth"]["Vector"] = targetPoint + Vector(0,0,128)
|
||||
end
|
||||
end
|
||||
|
||||
function OnHecatia02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_hecatia_ball_table == nil then
|
||||
caster.thtd_hecatia_ball_table = {}
|
||||
caster.thtd_hecatia_ball_table["earth"] = nil
|
||||
caster.thtd_hecatia_ball_table["moon"] = nil
|
||||
caster.thtd_hecatia_ball_table["otherworld"] = nil
|
||||
end
|
||||
|
||||
caster.thtd_hecatia_01_think_count = 0
|
||||
|
||||
if caster.thtd_hecatia_ball_table["moon"] == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_moon.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.3,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(150,0,0))
|
||||
|
||||
caster.thtd_hecatia_ball_table["moon"] =
|
||||
{
|
||||
["Vector"] = targetPoint + Vector(0,0,128),
|
||||
["EffectIndex"] = effectIndex
|
||||
}
|
||||
else
|
||||
caster.thtd_hecatia_ball_table["moon"]["Vector"] = targetPoint + Vector(0,0,128)
|
||||
end
|
||||
end
|
||||
|
||||
function OnHecatia03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_hecatia_ball_table == nil then
|
||||
caster.thtd_hecatia_ball_table = {}
|
||||
caster.thtd_hecatia_ball_table["earth"] = nil
|
||||
caster.thtd_hecatia_ball_table["moon"] = nil
|
||||
caster.thtd_hecatia_ball_table["otherworld"] = nil
|
||||
end
|
||||
|
||||
caster.thtd_hecatia_01_think_count = 0
|
||||
|
||||
if caster.thtd_hecatia_ball_table["otherworld"] == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_01_otherworld.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(0.4,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(200,0,0))
|
||||
|
||||
caster.thtd_hecatia_ball_table["otherworld"] =
|
||||
{
|
||||
["Vector"] = targetPoint + Vector(0,0,128),
|
||||
["CurPoint"] = targetPoint + Vector(0,0,128),
|
||||
["EffectIndex"] = effectIndex
|
||||
}
|
||||
else
|
||||
local hasCombo = caster:HasModifier("modifier_thtd_hecatia_03_combo_buff")
|
||||
if not hasCombo then
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["Vector"] = targetPoint + Vector(0,0,128)
|
||||
else
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["Vector"] = targetPoint + Vector(0,0,128)
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] = targetPoint + Vector(0,0,128)
|
||||
caster.thtd_hecatia_ball_midOrigin = targetPoint + Vector(0,0,128)
|
||||
ParticleManager:SetParticleControl(caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"], 0, targetPoint + Vector(0,0,128))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function HecatiaRemoveAllBall(caster)
|
||||
if caster.thtd_hecatia_ball_table == nil then
|
||||
caster.thtd_hecatia_ball_table = {}
|
||||
caster.thtd_hecatia_ball_table["earth"] = nil
|
||||
caster.thtd_hecatia_ball_table["moon"] = nil
|
||||
caster.thtd_hecatia_ball_table["otherworld"] = nil
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
end
|
||||
if caster.thtd_hecatia_ball_table["moon"] ~= nil then
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["moon"]["EffectIndex"]
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
end
|
||||
if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"]
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
end
|
||||
if caster.thtd_hecatia_ball_midOrigin ~= nil then
|
||||
caster.thtd_hecatia_ball_midOrigin = nil
|
||||
end
|
||||
if caster.thtd_hecatia_01_think_count ~= nil then
|
||||
caster.thtd_hecatia_01_think_count = nil
|
||||
end
|
||||
|
||||
caster.thtd_hecatia_ball_table = {}
|
||||
end
|
||||
|
||||
local MIN_RADIUS = 300
|
||||
function OnHecatia01Think(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster.thtd_hecatia_ball_table == nil then
|
||||
caster.thtd_hecatia_ball_table = {}
|
||||
caster.thtd_hecatia_ball_table["earth"] = nil
|
||||
caster.thtd_hecatia_ball_table["moon"] = nil
|
||||
caster.thtd_hecatia_ball_table["otherworld"] = nil
|
||||
end
|
||||
if caster.cast_factor == nil then
|
||||
caster.cast_factor = 10 -- 卡顿优化,每0.3秒释放一次技能(原0.03)
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_01_think_count == nil then
|
||||
caster.thtd_hecatia_01_think_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_01_think_count < 360 then
|
||||
caster.thtd_hecatia_01_think_count = caster.thtd_hecatia_01_think_count + 1
|
||||
else
|
||||
caster.thtd_hecatia_01_think_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_01_think_count_moon == nil then
|
||||
caster.thtd_hecatia_01_think_count_moon = 0
|
||||
end
|
||||
|
||||
local hasCombo = caster:HasModifier("modifier_thtd_hecatia_03_combo_buff")
|
||||
if caster.thtd_hecatia_01_think_count_moon < 360 then
|
||||
if hasCombo then
|
||||
caster.thtd_hecatia_01_think_count_moon = caster.thtd_hecatia_01_think_count_moon + 2
|
||||
else
|
||||
caster.thtd_hecatia_01_think_count_moon = caster.thtd_hecatia_01_think_count_moon + 1
|
||||
end
|
||||
else
|
||||
caster.thtd_hecatia_01_think_count_moon = 0
|
||||
end
|
||||
|
||||
if caster==nil or caster:IsNull()==true or caster:IsAlive()==false or caster:THTD_IsHidden() then
|
||||
HecatiaRemoveAllBall(caster)
|
||||
end
|
||||
|
||||
if caster:FindAbilityByName("thtd_hecatia_04"):GetLevel() >= 1 and caster.thtd_hecatia_04_lock ~= true then
|
||||
OnHecatiaTriggerTriangle(caster)
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_ball_table ~= nil then
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
|
||||
if not hasCombo then
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"],
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
|
||||
|
||||
local midOrigin = (caster.thtd_hecatia_ball_table["earth"]["Vector"] + caster.thtd_hecatia_ball_table["otherworld"]["Vector"])/2
|
||||
local point = midOrigin +
|
||||
Vector(
|
||||
math.cos(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
|
||||
math.sin(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
|
||||
0)
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["earth"]["CurPoint"] = point
|
||||
if caster.thtd_hecatia_ball_midOrigin ~= midOrigin then
|
||||
caster.thtd_hecatia_ball_midOrigin = midOrigin
|
||||
end
|
||||
else
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS * 2, GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"],
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
|
||||
local curPoint = caster.thtd_hecatia_ball_table["otherworld"]["Vector"]
|
||||
|
||||
if caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] ~= nil then
|
||||
curPoint = caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"]
|
||||
end
|
||||
|
||||
local point = curPoint +
|
||||
Vector(
|
||||
math.cos(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
|
||||
math.sin(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
|
||||
0)
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["earth"]["CurPoint"] = point
|
||||
|
||||
if caster.thtd_hecatia_ball_midOrigin ~= caster.thtd_hecatia_ball_table["otherworld"]["Vector"] then
|
||||
caster.thtd_hecatia_ball_midOrigin = caster.thtd_hecatia_ball_table["otherworld"]["Vector"]
|
||||
end
|
||||
end
|
||||
else
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["earth"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_hecatia_ball_table["earth"]["Vector"]))
|
||||
local point = caster:GetOrigin() +
|
||||
Vector(
|
||||
math.cos(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
|
||||
math.sin(caster.thtd_hecatia_01_think_count * math.pi/180)*distance,
|
||||
128)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["earth"]["CurPoint"] = point
|
||||
end
|
||||
if caster.cast_factor >= 10 then
|
||||
OnHecatiaEarthHit(caster)
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_ball_table["moon"] ~= nil then
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["moon"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"],
|
||||
caster.thtd_hecatia_ball_table["moon"]["Vector"]))
|
||||
local curPoint = caster.thtd_hecatia_ball_table["earth"]["Vector"]
|
||||
|
||||
if caster.thtd_hecatia_ball_table["earth"]["CurPoint"] ~= nil then
|
||||
curPoint = caster.thtd_hecatia_ball_table["earth"]["CurPoint"]
|
||||
end
|
||||
|
||||
local point = curPoint +
|
||||
Vector(
|
||||
math.cos(caster.thtd_hecatia_01_think_count_moon * math.pi/90)*distance,
|
||||
math.sin(caster.thtd_hecatia_01_think_count_moon * math.pi/90)*distance,
|
||||
0)
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["moon"]["CurPoint"] = point
|
||||
else
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["moon"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_hecatia_ball_table["moon"]["Vector"]))
|
||||
local point = caster:GetOrigin() +
|
||||
Vector(
|
||||
math.cos(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
|
||||
math.sin(caster.thtd_hecatia_01_think_count * math.pi/90)*distance,
|
||||
128)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["moon"]["CurPoint"] = point
|
||||
end
|
||||
if caster.cast_factor >= 10 then
|
||||
OnHecatiaMoonHit(caster)
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
|
||||
if not hasCombo then
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster.thtd_hecatia_ball_table["earth"]["Vector"],
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
|
||||
|
||||
local midOrigin = (caster.thtd_hecatia_ball_table["earth"]["Vector"] + caster.thtd_hecatia_ball_table["otherworld"]["Vector"])/2
|
||||
local point = midOrigin +
|
||||
Vector(
|
||||
math.cos((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
|
||||
math.sin((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
|
||||
0)
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] = point
|
||||
if caster.thtd_hecatia_ball_midOrigin ~= midOrigin then
|
||||
caster.thtd_hecatia_ball_midOrigin = midOrigin
|
||||
end
|
||||
else
|
||||
local effectIndex = caster.thtd_hecatia_ball_table["otherworld"]["EffectIndex"]
|
||||
local distance = math.max(MIN_RADIUS,GetDistanceBetweenTwoVec2D(caster:GetOrigin(), caster.thtd_hecatia_ball_table["otherworld"]["Vector"]))
|
||||
local point = caster:GetOrigin() +
|
||||
Vector(
|
||||
math.cos((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
|
||||
math.sin((caster.thtd_hecatia_01_think_count + 180) * math.pi/180)*distance,
|
||||
128)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"] = point
|
||||
end
|
||||
else
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
if caster.thtd_hecatia_ball_midOrigin ~= caster.thtd_hecatia_ball_table["otherworld"]["Vector"] then
|
||||
caster.thtd_hecatia_ball_midOrigin = caster.thtd_hecatia_ball_table["otherworld"]["Vector"]
|
||||
end
|
||||
end
|
||||
end
|
||||
if caster.cast_factor >= 10 then
|
||||
OnHecatiaOtherworldHit(caster)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if caster.cast_factor >= 10 then
|
||||
caster.cast_factor = 0
|
||||
RefreshBonus(caster)
|
||||
else
|
||||
caster.cast_factor = caster.cast_factor + 1
|
||||
end
|
||||
end
|
||||
|
||||
function RefreshBonus(caster)
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
caster:THTD_AddPowerPercentage(caster:GetAbilityValue("thtd_hecatia_01", "power_up"), "thtd_hecatia_01_bonus")
|
||||
else
|
||||
caster:THTD_AddPowerPercentage("thtd_hecatia_01_bonus")
|
||||
end
|
||||
if caster.thtd_hecatia_ball_table["moon"] ~= nil then
|
||||
caster:THTD_AddCritChance(caster:GetAbilityValue("thtd_hecatia_02", "chance"), "thtd_hecatia_02_bonus")
|
||||
caster:THTD_AddCritDamage(caster:GetAbilityValue("thtd_hecatia_02", "crit"), "thtd_hecatia_02_bonus")
|
||||
else
|
||||
caster:THTD_AddCritChance("thtd_hecatia_02_bonus")
|
||||
caster:THTD_AddCritDamage("thtd_hecatia_02_bonus")
|
||||
end
|
||||
if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
|
||||
caster:AddDamageOutgoingAll(caster:GetAbilityValue("thtd_hecatia_03", "damage_up"), "thtd_hecatia_03_bonus")
|
||||
else
|
||||
caster:AddDamageOutgoingAll("thtd_hecatia_03_bonus")
|
||||
end
|
||||
end
|
||||
|
||||
function OnHecatiaEarthHit(caster)
|
||||
local earthOrigin = caster.thtd_hecatia_ball_table["earth"]["CurPoint"]
|
||||
local ability = caster:FindAbilityByName("thtd_hecatia_01")
|
||||
if caster.thtd_hecatia_change_type == HECATIA_TYPE_EARTH then
|
||||
if caster.thtd_hecatia_triangle_count == nil or caster.thtd_hecatia_triangle_count == 0 then
|
||||
OnHecatiaCreateTriangle(caster)
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)
|
||||
local range = ability:GetSpecialValueFor("range1")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,earthOrigin, range)
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_hecatia_01_earth_lock") then
|
||||
ability:ApplyDataDrivenModifier(caster, v, "modifier_hecatia_01_earth_lock", {})
|
||||
ability:ApplyDataDrivenModifier(caster, v, "modifier_thtd_hecatia_01_debuff", {})
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
else
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)
|
||||
local range = ability:GetSpecialValueFor("range2")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,earthOrigin, range)
|
||||
for k,v in pairs(targets) do
|
||||
local targetOrigin = v:GetOrigin()
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_earth_rain.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, targetOrigin)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,0.5)
|
||||
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnHecatiaMoonHit(caster)
|
||||
local moonOrigin = caster.thtd_hecatia_ball_table["moon"]["CurPoint"]
|
||||
local ability = caster:FindAbilityByName("thtd_hecatia_02")
|
||||
|
||||
if caster.thtd_hecatia_change_type == HECATIA_TYPE_MOON then
|
||||
if caster.thtd_hecatia_triangle_count == 1 then
|
||||
OnHecatiaCreateTriangle(caster)
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)
|
||||
local range = ability:GetSpecialValueFor("range1")
|
||||
local backDistance = ability:GetSpecialValueFor("back_distance")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,moonOrigin, range)
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_hecatia_01_moon_lock") then
|
||||
ability:ApplyDataDrivenModifier(caster, v, "modifier_hecatia_01_moon_lock", {})
|
||||
|
||||
local forward = (v:GetAbsOrigin()-Vector(moonOrigin.x,moonOrigin.y,0)):Normalized()
|
||||
v:SetAbsOrigin(v:GetOrigin()+forward*backDistance)
|
||||
FindClearSpaceForUnit(v, v:GetOrigin(), false)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_hit.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, moonOrigin+Vector(0,0,64))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
else
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)
|
||||
local range = ability:GetSpecialValueFor("range2")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,moonOrigin,range)
|
||||
if #targets > 0 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_reflex.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex , 1, moonOrigin+Vector(0,0,64))
|
||||
ParticleManager:SetParticleControl(effectIndex , 9, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,moonOrigin,range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)
|
||||
for k,v in pairs(targets) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_moon_reflex.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, caster.thtd_hecatia_ball_table["moon"]["CurPoint"]+Vector(0,0,64))
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, v, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControl(effectIndex , 9, caster.thtd_hecatia_ball_table["moon"]["CurPoint"]+Vector(0,0,64))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnHecatiaOtherworldHit(caster)
|
||||
local otherworldOrigin = caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"]
|
||||
local ability = caster:FindAbilityByName("thtd_hecatia_03")
|
||||
|
||||
if caster.thtd_hecatia_change_type == HECATIA_TYPE_OTHERWORLD then
|
||||
if caster.thtd_hecatia_triangle_count == 2 then
|
||||
OnHecatiaCreateTriangle(caster)
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)
|
||||
local activeRange = ability:GetSpecialValueFor("active_range")
|
||||
local fullRange = ability:GetSpecialValueFor("full_range")
|
||||
local suckTime = ability:GetSpecialValueFor("suck_duration")
|
||||
|
||||
local targetsFirst = THTD_FindUnitsInRadius(caster,otherworldOrigin, activeRange)
|
||||
if #targetsFirst > 0 then
|
||||
if caster.thtd_hecatia_otherworld_think_lock ~= true then
|
||||
caster.thtd_hecatia_otherworld_think_lock = true
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_otherworld.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
local time = suckTime
|
||||
local clearGroup = {}
|
||||
THTD_SetSpellLock(caster, "thtd_hecatia_03", suckTime)
|
||||
caster:SetContextThink(DoUniqueString("ability_hecatia_otherworld_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 or caster==nil or caster:IsNull()==true or caster:IsAlive()==false or caster:THTD_IsHidden() then
|
||||
for k,v in pairs(clearGroup) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
FindClearSpaceForUnit(v, v:GetOrigin(), false)
|
||||
end
|
||||
end
|
||||
clearGroup = {}
|
||||
caster.thtd_hecatia_otherworld_think_lock = false
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
local cur_origin = caster.thtd_hecatia_ball_table["otherworld"]["CurPoint"]
|
||||
local targets = THTD_FindUnitsInRadius(caster,cur_origin, fullRange)
|
||||
clearGroup = targets
|
||||
for k,v in pairs(targets) do
|
||||
local forward = (Vector(cur_origin.x,cur_origin.y,0)-v:GetAbsOrigin()):Normalized()
|
||||
v:SetAbsOrigin(v:GetOrigin()+forward*100)
|
||||
UnitStunTarget(caster,v,0.2)
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, cur_origin)
|
||||
ParticleManager:SetParticleControl(effectIndex , 2, cur_origin)
|
||||
time = time - 0.3
|
||||
return 0.3
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
else
|
||||
local range = ability:GetSpecialValueFor("range2")
|
||||
local targetsFirst = THTD_FindUnitsInRadius(caster,otherworldOrigin,range)
|
||||
if #targetsFirst > 0 then
|
||||
if caster.thtd_hecatia_otherworld_hit_lock ~= true then
|
||||
caster.thtd_hecatia_otherworld_hit_lock = true
|
||||
-- caster.thtd_hecatia_otherworld_hit_list = {}
|
||||
caster:SetContextThink(DoUniqueString("ability_hecatia_hit_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 2)
|
||||
local targets = THTD_FindUnitsInRadius(caster,otherworldOrigin,range)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
caster.thtd_hecatia_otherworld_hit_lock = false
|
||||
return nil
|
||||
end,
|
||||
0.5)
|
||||
|
||||
local hasCombo = caster:HasModifier("modifier_thtd_hecatia_03_combo_buff")
|
||||
for i=1,12 do
|
||||
local forward1 = Vector(math.cos(i*math.pi/6),math.sin(i*math.pi/6),0)
|
||||
local forward2 = Vector(math.cos(i*math.pi/6+math.pi/2),math.sin(i*math.pi/6+math.pi/2),0)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_otherworld_projectile.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
if hasCombo then
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, otherworldOrigin + Vector(0,0,128))
|
||||
else
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, otherworldOrigin + forward1 * 150 + Vector(0,0,128))
|
||||
end
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward2 * 800)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, 0.9)
|
||||
end
|
||||
|
||||
-- for i=1,12 do
|
||||
-- local forward1 = Vector(math.cos(i*math.pi/6),math.sin(i*math.pi/6),0)
|
||||
-- local forward2 = Vector(math.cos(i*math.pi/6+math.pi/2),math.sin(i*math.pi/6+math.pi/2),0)
|
||||
-- local info =
|
||||
-- {
|
||||
-- Ability = ability,
|
||||
-- EffectName = "particles/heroes/thtd_hecatia/ability_hecatia_otherworld_projectile.vpcf",
|
||||
-- vSpawnOrigin = otherworldOrigin + forward1 * 100 + Vector(0,0,128),
|
||||
-- fDistance = range,
|
||||
-- fStartRadius = 150,
|
||||
-- fEndRadius = 150,
|
||||
-- Source = caster,
|
||||
-- bHasFrontalCone = false,
|
||||
-- bReplaceExisting = false,
|
||||
-- iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
-- iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
-- iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
-- fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
-- bDeleteOnHit = false,
|
||||
-- vVelocity = forward2 * 500,
|
||||
-- bProvidesVision = true,
|
||||
-- iVisionRadius = 1000,
|
||||
-- iVisionTeamNumber = caster:GetTeamNumber()
|
||||
-- }
|
||||
-- local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
-- ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
-- end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- function OnHecatiaProjectileHit(keys)
|
||||
-- local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
-- local target = keys.target
|
||||
|
||||
-- for k,v in pairs(caster.thtd_hecatia_otherworld_hit_list) do
|
||||
-- if v == target then
|
||||
-- return
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- local damage = caster:THTD_GetAbilityPowerDamage(caster:FindAbilityByName("thtd_hecatia_03"), 2)
|
||||
-- local DamageTable = {
|
||||
-- ability = keys.ability,
|
||||
-- victim = target,
|
||||
-- attacker = caster,
|
||||
-- damage = damage,
|
||||
-- damage_type = keys.ability:GetAbilityDamageType(),
|
||||
-- damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
-- }
|
||||
-- UnitDamageTarget(DamageTable)
|
||||
-- table.insert(caster.thtd_hecatia_otherworld_hit_list, target)
|
||||
-- end
|
||||
|
||||
function OnHecatia04Think(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster:GetTowerPowerLevel() >= 3 then
|
||||
if caster.thtd_hecatia_change_list == nil or #caster.thtd_hecatia_change_list == 0 then
|
||||
caster.thtd_hecatia_change_list = {HECATIA_TYPE_EARTH, HECATIA_TYPE_MOON, HECATIA_TYPE_OTHERWORLD, HECATIA_TYPE_EARTH, HECATIA_TYPE_MOON, HECATIA_TYPE_OTHERWORLD}
|
||||
end
|
||||
local index = RandomInt(1,#caster.thtd_hecatia_change_list)
|
||||
local randomType = caster.thtd_hecatia_change_list[index]
|
||||
table.remove(caster.thtd_hecatia_change_list, index)
|
||||
caster:SetModel(thtd_hecatia_model_list[randomType])
|
||||
caster:SetOriginalModel(thtd_hecatia_model_list[randomType])
|
||||
caster.thtd_hecatia_change_type = randomType
|
||||
return
|
||||
end
|
||||
|
||||
local randomType = RandomInt(1,3)
|
||||
caster:SetModel(thtd_hecatia_model_list[randomType])
|
||||
caster:SetOriginalModel(thtd_hecatia_model_list[randomType])
|
||||
caster.thtd_hecatia_change_type = randomType
|
||||
|
||||
-- local level = 1
|
||||
-- if GetHecatiaBallCount(caster) == 3 then
|
||||
-- level = 2
|
||||
-- end
|
||||
-- for i=1,4 do
|
||||
-- local ability = caster:FindAbilityByName("thtd_hecatia_0"..tostring(i))
|
||||
-- if ability ~= nil and ability:GetLevel() ~= level then
|
||||
-- ability:SetLevel(level)
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
|
||||
function OnHecatiaCreateTriangle(caster)
|
||||
if caster.thtd_hecatia_ball_midOrigin == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_triangle_count == nil then
|
||||
caster.thtd_hecatia_triangle_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_triangle_table == nil then
|
||||
caster.thtd_hecatia_triangle_table = {}
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_triangle_angle == nil then
|
||||
caster.thtd_hecatia_triangle_angle = RandomInt(0, 360)
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_triangle_count < 3 then
|
||||
local radius = 900
|
||||
local point = RotatePosition(caster.thtd_hecatia_ball_midOrigin, QAngle(0,caster.thtd_hecatia_triangle_angle,0), caster.thtd_hecatia_ball_midOrigin + Vector(0, radius, 0))
|
||||
caster.thtd_hecatia_triangle_count = caster.thtd_hecatia_triangle_count + 1
|
||||
if caster.thtd_hecatia_triangle_count == 2 then
|
||||
point = RotatePosition(caster.thtd_hecatia_ball_midOrigin, QAngle(0,120,0), point)
|
||||
elseif caster.thtd_hecatia_triangle_count == 3 then
|
||||
point = RotatePosition(caster.thtd_hecatia_ball_midOrigin, QAngle(0,240,0), point)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_triangle.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, point)
|
||||
ParticleManager:SetParticleControl(effectIndex , 3, point)
|
||||
|
||||
caster.thtd_hecatia_triangle_table[caster.thtd_hecatia_triangle_count] = {}
|
||||
caster.thtd_hecatia_triangle_table[caster.thtd_hecatia_triangle_count]["EffectIndex"] = effectIndex
|
||||
caster.thtd_hecatia_triangle_table[caster.thtd_hecatia_triangle_count]["Origin"] = point
|
||||
end
|
||||
end
|
||||
|
||||
function OnHecatiaTriggerTriangle(caster)
|
||||
if caster.thtd_hecatia_triangle_count == nil then
|
||||
caster.thtd_hecatia_triangle_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_triangle_table == nil then
|
||||
caster.thtd_hecatia_triangle_table = {}
|
||||
end
|
||||
|
||||
if caster.thtd_hecatia_triangle_count >= 3 and THTD_HasUnitsInRadius(caster, caster:GetAbsOrigin(), 1500) then
|
||||
local ability = caster:FindAbilityByName("thtd_hecatia_04")
|
||||
local duration = math.floor(ability:GetSpecialValueFor("duration_time") * 100 + 0.5)/100
|
||||
local power_bonus = ability:GetSpecialValueFor("power_bonus")
|
||||
local durationDelay = 0
|
||||
local delayCount = 0
|
||||
local time = 0
|
||||
local count = 0
|
||||
local triangleTable = caster.thtd_hecatia_triangle_table
|
||||
caster.thtd_hecatia_04_lock = true
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_hecatia_triangle_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time > duration + durationDelay or THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_hecatia_triangle_table[1]["EffectIndex"],true)
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_hecatia_triangle_table[2]["EffectIndex"],true)
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_hecatia_triangle_table[3]["EffectIndex"],true)
|
||||
triangleTable = {}
|
||||
caster.thtd_hecatia_triangle_table = {}
|
||||
caster.thtd_hecatia_triangle_count = 0
|
||||
caster.thtd_hecatia_triangle_angle = nil
|
||||
caster.thtd_hecatia_04_lock = false
|
||||
return nil
|
||||
end
|
||||
-- 改为三角连接和中心发射同时进行
|
||||
count = count + 1
|
||||
if count > 3 then
|
||||
count = 1
|
||||
end
|
||||
local countNext = count + 1
|
||||
if countNext > 3 then
|
||||
countNext = 1
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, triangleTable[count]["Origin"])
|
||||
ParticleManager:SetParticleControl(effectIndex , 1, triangleTable[countNext]["Origin"])
|
||||
ParticleManager:SetParticleControl(effectIndex , 9, triangleTable[count]["Origin"])
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local distance = GetDistanceBetweenTwoVec2D(triangleTable[count]["Origin"], triangleTable[countNext]["Origin"])
|
||||
local speed = 3000
|
||||
local delayTime = distance / speed
|
||||
time = time + delayTime
|
||||
if delayCount < 3 then
|
||||
delayCount = delayCount + 1
|
||||
durationDelay = delayTime
|
||||
|
||||
if delayCount == 3 then
|
||||
caster:THTD_AddBasePower(power_bonus, "thtd_hecatia_04_buff")
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if time > duration + durationDelay or THTD_IsValid(caster) == false then
|
||||
caster:THTD_AddBasePower("thtd_hecatia_04_buff")
|
||||
return nil
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
local center,radius = GetCircleCenterAndRadius(triangleTable[1]["Origin"],triangleTable[2]["Origin"],triangleTable[3]["Origin"])
|
||||
local targets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
for k,v in pairs(targets) do
|
||||
if v ~= nil and v:IsNull() == false and v:IsAlive() and IsInTriangle(triangleTable[1]["Origin"],triangleTable[2]["Origin"],triangleTable[3]["Origin"],v:GetAbsOrigin()) then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, center)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, v, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControl(effectIndex , 9, center)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
0.3)
|
||||
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
end
|
||||
return delayTime
|
||||
|
||||
-- 这个效果是三个三角依次连接后再从中心发射
|
||||
-- if count < 3 then
|
||||
-- count = count + 1
|
||||
|
||||
-- local countNext = count + 1
|
||||
-- if countNext > 3 then
|
||||
-- countNext = 1
|
||||
-- end
|
||||
|
||||
-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 0, triangleTable[count]["Origin"])
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 1, triangleTable[countNext]["Origin"])
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 9, triangleTable[count]["Origin"])
|
||||
-- ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
-- local distance = GetDistanceBetweenTwoVec2D(triangleTable[count]["Origin"], triangleTable[countNext]["Origin"])
|
||||
-- local speed = 3000
|
||||
-- local delayTime = distance / speed
|
||||
-- time = time - delayTime
|
||||
-- return delayTime
|
||||
-- else
|
||||
-- local center,radius = GetCircleCenterAndRadius(triangleTable[1]["Origin"],triangleTable[2]["Origin"],triangleTable[3]["Origin"])
|
||||
-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 0, triangleTable[1]["Origin"])
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 1, caster.thtd_hecatia_ball_midOrigin)
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 9, triangleTable[1]["Origin"])
|
||||
-- ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
-- local distance = GetDistanceBetweenTwoVec2D(triangleTable[1]["Origin"], caster.thtd_hecatia_ball_midOrigin)
|
||||
-- local speed = 3000
|
||||
-- local delayTime = distance / speed
|
||||
|
||||
-- caster:SetContextThink(DoUniqueString("ability_hecatia_04_delay"),
|
||||
-- function()
|
||||
-- if GameRules:IsGamePaused() then return 0.03 end
|
||||
-- local damage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
-- local targets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
-- for k,v in pairs(targets) do
|
||||
-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_hecatia/ability_hecatia_04_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 0, caster.thtd_hecatia_ball_midOrigin)
|
||||
-- ParticleManager:SetParticleControlEnt(effectIndex , 1, v, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
-- ParticleManager:SetParticleControl(effectIndex , 9, caster.thtd_hecatia_ball_midOrigin)
|
||||
-- ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
-- local DamageTable = {
|
||||
-- ability = ability,
|
||||
-- victim = v,
|
||||
-- attacker = caster,
|
||||
-- damage = damage,
|
||||
-- damage_type = ability:GetAbilityDamageType(),
|
||||
-- damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
-- }
|
||||
-- UnitDamageTarget(DamageTable)
|
||||
-- end
|
||||
-- return nil
|
||||
-- end,
|
||||
-- delayTime)
|
||||
|
||||
-- count = 0
|
||||
|
||||
-- time = time - tick
|
||||
-- return tick
|
||||
-- end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
|
||||
function GetHecatiaBallCount(caster)
|
||||
if caster.thtd_hecatia_ball_table == nil then return 0 end
|
||||
local count = 0
|
||||
if caster.thtd_hecatia_ball_table["earth"] ~= nil then
|
||||
count = count + 1
|
||||
end
|
||||
if caster.thtd_hecatia_ball_table["moon"] ~= nil then
|
||||
count = count + 1
|
||||
end
|
||||
if caster.thtd_hecatia_ball_table["otherworld"] ~= nil then
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
143
scripts/vscripts/abilities/abilityhina.lua
Executable file
143
scripts/vscripts/abilities/abilityhina.lua
Executable file
@@ -0,0 +1,143 @@
|
||||
|
||||
-- 特殊太卡,弃用
|
||||
function OnHina02Think(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
-- caster:EmitSound("Hero_TrollWarlord.WhirlingAxes.Melee")
|
||||
|
||||
local effect = "particles/econ/items/troll_warlord/troll_ti10_shoulder/troll_ti10_whirling_axe_melee.vpcf"
|
||||
local damage = 1000
|
||||
local damage_tick = 0.1
|
||||
local damage_duration = 3.0
|
||||
local max_count = math.floor(damage_duration/damage_tick + 0.5)
|
||||
local radius = 1000 - 200
|
||||
local elapsed_duration = 0
|
||||
local enemies_hit = {}
|
||||
|
||||
local caster_pos = caster:GetAbsOrigin()
|
||||
local caster_direction = caster:GetForwardVector()
|
||||
local effectIndexList = {}
|
||||
local effectPointList = {}
|
||||
for i = 1,5 do
|
||||
local axe_target_point = RotatePosition(caster_pos, QAngle(0, i * 72, 0), caster_pos + caster_direction * 175)
|
||||
local effectIndex = ParticleManager:CreateParticle(effect, PATTACH_ABSORIGIN_FOLLOW, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster_pos + Vector(0, 0, 100))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, axe_target_point + Vector(0, 0, 100))
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, Vector(damage_duration, 0, 0))
|
||||
effectIndexList[i] = effectIndex
|
||||
effectPointList[i] = axe_target_point
|
||||
end
|
||||
|
||||
local count = 1
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
|
||||
for i = 1,5 do
|
||||
local axe_target_point = RotatePosition(caster_pos, QAngle(0, 360 * count/max_count, 0), effectPointList[i])
|
||||
axe_target_point = axe_target_point + (axe_target_point - caster_pos):Normalized() * radius * count/max_count
|
||||
ParticleManager:SetParticleControl(effectIndexList[i], 1, axe_target_point + Vector(0, 0, 100))
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster_pos,1200)
|
||||
local damage = 1200
|
||||
for k,v in pairs(targets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
if enemies_hit[v:entindex()] ~= true then
|
||||
enemies_hit[v:entindex()] = true
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
-- If the duration is over, end
|
||||
if count < max_count then
|
||||
count = count + 1
|
||||
return damage_tick
|
||||
else
|
||||
for i = 1,5 do
|
||||
ParticleManager:ReleaseParticleIndex(effectIndexList[i])
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
|
||||
|
||||
function OnSpellStartHina02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local range = keys.range
|
||||
local bonus_crit = keys.bonus_crit
|
||||
local chance = keys.chance
|
||||
local duration = math.floor(keys.duration * 100 + 0.5)/100
|
||||
local tick = math.floor(keys.tick * 100 + 0.5)/100
|
||||
|
||||
local effect = "particles/econ/items/troll_warlord/troll_ti10_shoulder/troll_ti10_whirling_axe_melee.vpcf"
|
||||
local effectIndex = ParticleManager:CreateParticle(effect, PATTACH_ABSORIGIN_FOLLOW, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin() + Vector(0, 0, 100))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint + Vector(0, 0, 100))
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, Vector(duration + 4, 0, 0))
|
||||
|
||||
local powerChance = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_hina_02")
|
||||
if pv ~= nil then
|
||||
powerChance = pv[1]
|
||||
end
|
||||
|
||||
local crit666 = 1
|
||||
if caster:IsPower666() then crit666 = 5 end
|
||||
|
||||
local time = duration
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
time = time - tick
|
||||
if time < 0 then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local crit = 1
|
||||
v.thtd_hina_02_debuff_count = math.min(999, (v.thtd_hina_02_debuff_count or 0) + 1)
|
||||
local count = v.thtd_hina_02_debuff_count
|
||||
if caster:IsPower999() then
|
||||
for _,tar in pairs(targets) do
|
||||
if v ~= tar then
|
||||
count = count + (tar.thtd_hina_02_debuff_count or 0) * 0.4
|
||||
end
|
||||
end
|
||||
end
|
||||
if RollPercentage(chance + powerChance) then
|
||||
crit = 1 + count * (bonus_crit + powerChance)/100
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit * crit666,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
return tick
|
||||
end,
|
||||
tick)
|
||||
|
||||
end
|
||||
21
scripts/vscripts/abilities/abilityhourainingyou.lua
Executable file
21
scripts/vscripts/abilities/abilityhourainingyou.lua
Executable file
@@ -0,0 +1,21 @@
|
||||
function OnHourainingyou01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if RollPercentage(keys.chance) then
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
if not target:HasModifier("modifier_hourainingyou_01_stun_lock") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_hourainingyou_01_stun_lock", {Duration = keys.lock_time})
|
||||
UnitStunTarget(caster,target,keys.stun_time)
|
||||
end
|
||||
end
|
||||
end
|
||||
95
scripts/vscripts/abilities/abilityiku.lua
Executable file
95
scripts/vscripts/abilities/abilityiku.lua
Executable file
@@ -0,0 +1,95 @@
|
||||
function OnIku01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
if caster.thtd_iku_01_attack_count == nil then
|
||||
caster.thtd_iku_01_attack_count = 0
|
||||
end
|
||||
|
||||
caster.thtd_iku_01_attack_count = caster.thtd_iku_01_attack_count + 1
|
||||
|
||||
if caster.thtd_iku_01_attack_count >= keys.max_count then
|
||||
caster.thtd_iku_01_attack_count = 0
|
||||
caster:EmitSound("Sound_THTD.thtd_iku_01")
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
for k,v in pairs(targets) do
|
||||
if v:HasModifier("modifier_iku_01_debuff_lock") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_iku_01_debuff", {Duration = keys.stun_time})
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_iku_01_debuff_lock", nil)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/iku/ability_iku_01_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
end
|
||||
|
||||
function OnIku02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local time = keys.duration_time
|
||||
local tick = keys.tick_time
|
||||
|
||||
Iku02CreateEffect(keys)
|
||||
caster:EmitSound("Sound_THTD.thtd_iku_02")
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_iku02_lightning"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * tick
|
||||
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
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function Iku02CreateEffect(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
local vec = caster:GetOrigin() + 700*caster:GetForwardVector() + Vector(0,0,128)
|
||||
|
||||
local particle = ParticleManager:CreateParticle("particles/thd2/heroes/iku/ability_iku_04_light_b.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,vec)
|
||||
ParticleManager:SetParticleControlForward(particle,0,caster:GetForwardVector())
|
||||
ParticleManager:SetParticleControl(particle,2,vec)
|
||||
ParticleManager:SetParticleControl(particle,3,vec)
|
||||
ParticleManager:SetParticleControl(particle,4,-caster:GetForwardVector())
|
||||
ParticleManager:SetParticleControl(particle,5,-caster:GetForwardVector())
|
||||
|
||||
ParticleManager:DestroyParticleSystemTime(particle,keys.duration_time)
|
||||
|
||||
particle = ParticleManager:CreateParticle("particles/thd2/heroes/iku/ability_iku_04_model.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,caster:GetOrigin()+caster:GetForwardVector()*350 + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControlForward(particle,0,caster:GetForwardVector())
|
||||
|
||||
ParticleManager:DestroyParticleSystemTime(particle,keys.duration_time)
|
||||
end
|
||||
204
scripts/vscripts/abilities/abilityinaba.lua
Executable file
204
scripts/vscripts/abilities/abilityinaba.lua
Executable file
@@ -0,0 +1,204 @@
|
||||
local inaba_01_black_list =
|
||||
{
|
||||
"lily",
|
||||
"daiyousei",
|
||||
}
|
||||
|
||||
function IsInInaba01BlackList(unit)
|
||||
for k,v in pairs(inaba_01_black_list) do
|
||||
if unit:GetUnitName() == v then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function OnSpellStartInaba01(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
if target:THTD_IsTower() == false or target:GetPlayerOwnerID() ~= caster:GetPlayerOwnerID() then
|
||||
keys.ability:EndCooldown()
|
||||
caster:GiveMana(caster:GetRealManaCost(keys.ability))
|
||||
return
|
||||
end
|
||||
|
||||
caster.thtd_last_cast_unit = target
|
||||
caster:EmitSound("Hero_OgreMagi.Bloodlust.Cast")
|
||||
|
||||
local modifier = target:FindModifierByName("modifier_inaba_01_buff")
|
||||
if modifier == nil then
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_inaba_01_buff", nil)
|
||||
else
|
||||
modifier:SetDuration(keys.duration, false)
|
||||
end
|
||||
|
||||
local effectName = "particles/econ/items/ogre_magi/ogre_ti8_immortal_weapon/ogre_ti8_immortal_bloodlust_buff.vpcf"
|
||||
local effectIndex = ParticleManager:CreateParticle(effectName, PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex, 0, caster, PATTACH_POINT_FOLLOW, "attach_hitloc", caster:GetAbsOrigin(), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex, 2, target, PATTACH_CUSTOMORIGIN_FOLLOW, nil, target:GetAbsOrigin(), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex, 3, target, PATTACH_CUSTOMORIGIN_FOLLOW, nil, target:GetAbsOrigin(), true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
|
||||
function OnCreatedInaba01Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddCritChance(keys.chance, "thtd_inaba_01_buff_bonus")
|
||||
target:THTD_AddAttackSpeed(keys.attack_speed, "thtd_inaba_01_buff_bonus")
|
||||
if not IsInInaba01BlackList(target) then
|
||||
target:AddManaCostReducePercent(keys.mana_cost, "thtd_inaba_01_buff_bonus")
|
||||
end
|
||||
end
|
||||
|
||||
function OnDestroyInaba01Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddCritChance("thtd_inaba_01_buff_bonus")
|
||||
target:THTD_AddAttackSpeed("thtd_inaba_01_buff_bonus")
|
||||
if not IsInInaba01BlackList(target) then
|
||||
target:AddManaCostReducePercent("thtd_inaba_01_buff_bonus")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnAttackLandedInaba02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = keys.target:GetAbsOrigin()
|
||||
|
||||
caster.thtd_inaba_02_attack_count = (caster.thtd_inaba_02_attack_count or 0) + 1
|
||||
|
||||
local powerDamageUp = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_inaba_02")
|
||||
if pv ~= nil then
|
||||
powerDamageUp = pv[1]
|
||||
end
|
||||
|
||||
local damage_up = keys.damage_up + powerDamageUp
|
||||
local max_count = keys.max_count
|
||||
if caster:IsPower999() then
|
||||
max_count = max_count * 2
|
||||
end
|
||||
|
||||
if caster:HasModifier("modifier_inaba_02_buff") then
|
||||
caster:FindModifierByName("modifier_inaba_02_buff"):SetDuration(2.0, false)
|
||||
end
|
||||
|
||||
if caster.thtd_inaba_02_attack_count % keys.count1 == 0 then
|
||||
if caster.thtd_inaba_power666_bonus_power ~= nil then
|
||||
caster:THTD_AddPowerPercentage(-caster.thtd_inaba_power666_bonus_power)
|
||||
caster.thtd_inaba_power666_bonus_power = nil
|
||||
end
|
||||
if caster:IsPower999() then
|
||||
caster.thtd_inaba_power666_bonus_power = 300
|
||||
caster:THTD_AddPowerPercentage(caster.thtd_inaba_power666_bonus_power)
|
||||
end
|
||||
local unit = CreateUnitByName(
|
||||
"inaba_rabbit"
|
||||
,caster:GetOrigin() + caster:GetForwardVector() * 120
|
||||
,false
|
||||
,caster:GetOwner()
|
||||
,caster:GetOwner()
|
||||
,caster:GetTeam()
|
||||
)
|
||||
|
||||
local lastVec = target:GetAbsOrigin()
|
||||
if unit ~= nil then
|
||||
unit:SetControllableByPlayer(caster:GetPlayerOwnerID(), false)
|
||||
unit.thtd_spawn_unit_owner = caster
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_inaba_02_rabbit", nil)
|
||||
unit:AddNewModifier(unit, nil, "modifier_phased", {})
|
||||
local kill_time = 10.0
|
||||
unit:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
kill_time = kill_time - 0.2
|
||||
if THTD_IsValid(caster) == false or kill_time < 0 then
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
unit:MoveToPosition(lastVec)
|
||||
if THTD_IsValid(target) then
|
||||
lastVec = target:GetAbsOrigin()
|
||||
end
|
||||
if (lastVec - unit:GetAbsOrigin()):Length2D() < 100 then
|
||||
-- EmitSoundOnLocationWithCaster(lastVec, "Hero_Techies.LandMine.Detonate", caster)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_techies/techies_blast_off.vpcf", PATTACH_POINT, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, lastVec)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, false)
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
|
||||
local boomTargets = THTD_FindUnitsInRadius(caster,lastVec,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
|
||||
local modifier = caster:FindModifierByName("modifier_inaba_02_buff")
|
||||
if modifier ~= nil then
|
||||
local stack_count = modifier:GetStackCount()
|
||||
damage = damage * (1 + stack_count * damage_up/100)
|
||||
modifier:SetStackCount(math.min(max_count, stack_count+1))
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_inaba_02_buff", {duration = 2.0}):SetStackCount(1)
|
||||
end
|
||||
for k,v in pairs(boomTargets) 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
|
||||
|
||||
return 0.2
|
||||
end,
|
||||
0.2)
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_inaba_02_attack_count >= keys.count2 then
|
||||
caster.thtd_inaba_02_attack_count = 0
|
||||
local effectName = "particles/econ/items/sniper/sniper_fall20_immortal/sniper_fall20_immortal_shrapnel.vpcf"
|
||||
local effectIndex = ParticleManager:CreateParticle(effectName, PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(keys.range, 0, 0))
|
||||
local time = math.floor(keys.duration * 100 + 0.5)/100
|
||||
local tick = 0.5
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
time = time - tick
|
||||
if time < 0 or THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2)
|
||||
local modifier = caster:FindModifierByName("modifier_inaba_02_buff")
|
||||
if modifier ~= nil then
|
||||
damage = damage * (1 + modifier:GetStackCount() * damage_up/100)
|
||||
end
|
||||
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 tick
|
||||
end,
|
||||
0.1)
|
||||
|
||||
end
|
||||
end
|
||||
486
scripts/vscripts/abilities/abilityitem.lua
Executable file
486
scripts/vscripts/abilities/abilityitem.lua
Executable file
@@ -0,0 +1,486 @@
|
||||
function OnItem2001_SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
if caster:IsRealHero() or caster:GetUnitName() == "reimu_pet" then
|
||||
local entities = Entities:FindAllByClassname("npc_dota_creature")
|
||||
|
||||
for k,v in pairs(entities) do
|
||||
local findNum = string.find(v:GetUnitName(), 'creature')
|
||||
if findNum ~= nil and v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
if SpawnSystem.IsUnLimited then
|
||||
if v.thtd_player_index == caster:GetPlayerOwnerID() then
|
||||
caster:NpcKill(v)
|
||||
end
|
||||
else
|
||||
caster:NpcKill(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if SpawnSystem.CurWave > 100 then
|
||||
if caster:GetUnitName() == "reimu_pet" then
|
||||
caster:GetOwner().use_item2001_count = (caster:GetOwner().use_item2001_count or 0) + 1
|
||||
else
|
||||
caster.use_item2001_count = (caster.use_item2001_count or 0) + 1
|
||||
end
|
||||
if SpawnSystem.RankMinWave >= SpawnSystem.CurWave then
|
||||
SpawnSystem.RankMinWave = SpawnSystem.RankMinWave + 1
|
||||
end
|
||||
end
|
||||
|
||||
local particle = ParticleManager:CreateParticle("particles/heroes/yumemi/ability_yumemi_04_exolosion.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(particle,false)
|
||||
|
||||
if keys.ability:IsItem() then
|
||||
local charge = keys.ability:GetCurrentCharges()
|
||||
if charge > 1 then
|
||||
keys.ability:SetCurrentCharges(charge-1)
|
||||
else
|
||||
caster:RemoveItem(keys.ability)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem2002_SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
if caster:IsRealHero() then
|
||||
if keys.ability:IsItem() then
|
||||
local select_cards = {}
|
||||
for k,v in pairs(towerPlayerList[caster:GetPlayerOwnerID()+1]) do
|
||||
if v["quality"] == 4 and string.find(v["itemName"],"item_20") == nil and v["count"] > 0 then
|
||||
select_cards[v["itemName"]] = v["itemName"]
|
||||
end
|
||||
end
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_select_card_panel", {cards=select_cards} )
|
||||
caster.thtd_last_select_item = keys.ability
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem2003_SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
if caster:IsRealHero() then
|
||||
if keys.ability:IsItem() then
|
||||
local select_cards = {}
|
||||
for k,v in pairs(towerPlayerList[caster:GetPlayerOwnerID()+1]) do
|
||||
if v["quality"] == 3 and string.find(v["itemName"],"item_20") == nil and v["count"] > 0 then
|
||||
select_cards[v["itemName"]] = v["itemName"]
|
||||
end
|
||||
end
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_select_card_panel", {cards=select_cards} )
|
||||
caster.thtd_last_select_item = keys.ability
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem2004_SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
if caster:IsRealHero() then
|
||||
if keys.ability:IsItem() then
|
||||
local select_cards = {}
|
||||
for k,v in pairs(towerPlayerList[caster:GetPlayerOwnerID()+1]) do
|
||||
if v["quality"] == 2 and string.find(v["itemName"],"item_20") == nil and v["count"] > 0 then
|
||||
select_cards[v["itemName"]] = v["itemName"]
|
||||
end
|
||||
end
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_select_card_panel", {cards=select_cards} )
|
||||
caster.thtd_last_select_item = keys.ability
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem2021_SpellStart(keys)
|
||||
local target = keys.target
|
||||
|
||||
if target:THTD_IsTower() and target:HasModifier("modifier_item_2021_buff") == false then
|
||||
local duration_time = math.max(keys.duration_min, keys.duration_max - keys.step * (target.item2021_count or 0)) * 1.0
|
||||
target.item2021_count = (target.item2021_count or 0) + 1
|
||||
keys.ability:ApplyDataDrivenModifier(target, target, "modifier_item_2021_buff", {duration = duration_time})
|
||||
|
||||
if keys.ability:IsItem() then
|
||||
local charge = keys.ability:GetCurrentCharges()
|
||||
if charge > 1 then
|
||||
keys.ability:SetCurrentCharges(charge-1)
|
||||
else
|
||||
keys.caster:RemoveItem(keys.ability)
|
||||
end
|
||||
end
|
||||
else
|
||||
keys.ability:EndCooldown()
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedItem2021Buff(keys)
|
||||
local target = keys.target
|
||||
local bonus = keys.bonus
|
||||
target:THTD_AddManaRegenPercentage(bonus, "thtd_item_2021_bonus")
|
||||
target:THTD_AddAttackSpeed(bonus, "thtd_item_2021_bonus")
|
||||
target:THTD_AddCritChance(bonus, "thtd_item_2021_bonus")
|
||||
target:THTD_AddCritDamage(bonus, "thtd_item_2021_bonus")
|
||||
target:THTD_AddPowerPercentage(bonus, "thtd_item_2021_bonus")
|
||||
target:THTD_AddAttackPercentage(bonus, "thtd_item_2021_bonus")
|
||||
target:SetModelScale(target:GetModelScale() * 1.25)
|
||||
end
|
||||
|
||||
function OnRemoveItem2021Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddManaRegenPercentage("thtd_item_2021_bonus")
|
||||
target:THTD_AddAttackSpeed("thtd_item_2021_bonus")
|
||||
target:THTD_AddCritChance("thtd_item_2021_bonus")
|
||||
target:THTD_AddCritDamage("thtd_item_2021_bonus")
|
||||
target:THTD_AddPowerPercentage("thtd_item_2021_bonus")
|
||||
target:THTD_AddAttackPercentage("thtd_item_2021_bonus")
|
||||
target:SetModelScale(target:GetModelScale() / 1.25)
|
||||
end
|
||||
|
||||
function OnItem2022_SpellStart(keys)
|
||||
if SpawnSystem.IsUnLimited then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster:IsRealHero() then
|
||||
if target:THTD_IsTower() and target:THTD_GetLevel()<THTD_MAX_LEVEL then
|
||||
target:THTD_SetLevel(THTD_MAX_LEVEL)
|
||||
else
|
||||
keys.ability:EndCooldown()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem3146_SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster:IsRealHero() == false then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_hero_use"})
|
||||
return
|
||||
end
|
||||
|
||||
if (caster.item_power_used or 0) >= 4 then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="reach_to_limit"})
|
||||
return
|
||||
end
|
||||
|
||||
if target:THTD_IsTower() then
|
||||
local maxLevel = target:GetMaxPowerLevel()
|
||||
local modifier = target:FindModifierByName("modifier_fairy_count")
|
||||
if modifier == nil then
|
||||
target:AddNewModifier(target, nil, "modifier_fairy_count", nil):SetStackCount(math.min(maxLevel,keys.point))
|
||||
target.thtd_power_from_item = (target.thtd_power_from_item or 0) + math.min(maxLevel,keys.point)
|
||||
else
|
||||
local count = modifier:GetStackCount()
|
||||
if count >= maxLevel then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="reach_to_limit"})
|
||||
return
|
||||
end
|
||||
target.thtd_power_from_item = (target.thtd_power_from_item or 0) + math.min(maxLevel - count, keys.point)
|
||||
count = math.min(maxLevel, count + keys.point)
|
||||
modifier:SetStackCount(count)
|
||||
if target.thtd_power_level ~= nil then
|
||||
target.thtd_power_level = count
|
||||
target:AddPowerBonus()
|
||||
end
|
||||
end
|
||||
target:EmitSound("Quest.Completed")
|
||||
caster.item_power_used = (caster.item_power_used or 0) + 1
|
||||
if GameRules.GameData.luck_card ~= "all" then
|
||||
Service:SavePowerMaxCount(keys.ability.owner_player_id, false)
|
||||
end
|
||||
keys.ability:RemoveSelf()
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem3150_SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if not caster:THTD_IsTower() then return end
|
||||
|
||||
local radius = 900
|
||||
local duration = 10
|
||||
|
||||
if keys.ability.spell_effect ~= nil then
|
||||
ParticleManager:DestroyParticle(keys.ability.spell_effect, true)
|
||||
end
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_riki/riki_tricks.vpcf", PATTACH_ABSORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(radius,radius,radius))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(duration,0,0))
|
||||
keys.ability.spell_effect = effectIndex
|
||||
|
||||
local damage = caster:THTD_GetStarDamage() * keys.power_damage
|
||||
local attackDamage = caster:THTD_GetAttack()
|
||||
local targets = THTD_FindUnitsInRadius(caster, caster:GetAbsOrigin(), radius)
|
||||
local count = 0
|
||||
for k,v in pairs(targets) do
|
||||
count = count + 1
|
||||
if count <= 3 then
|
||||
-- 多了造成卡顿,改为取消普通攻击动画实现
|
||||
--倒数第二个参数:bFakeAttack如果为true,则不会造成伤害
|
||||
--第三个参数如果为false,则会触发OnAttack事件,但是不会触发其余的几个事件(start、land、finish),这样有些攻击命中才生效的逻辑就不会触发了
|
||||
--PerformAttack(handle hTarget, bool bUseCastAttackOrb, bool bProcessProcs, bool bSkipCooldown, bool bIgnoreInvis, bool bUseProjectile, bool bFakeAttack, bool bNeverMiss)
|
||||
caster:PerformAttack(v,true,true,true,false,false,false,true)
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
if count > 3 then
|
||||
DamageTable.damage = DamageTable.damage + attackDamage
|
||||
end
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
|
||||
function OnItem3151_SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if keys.ability:IsCooldownReady() then
|
||||
keys.ability:StartCooldown(keys.ability:GetCooldown(0))
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
target:EmitSound("Hero_Spirit_Breaker.Charge.Impact")
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/dzz/qingshanjiansheng_yjzcs.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage = caster:THTD_GetStarDamage() * keys.power_damage
|
||||
local targets = THTD_FindUnitsInRadius(caster, target:GetAbsOrigin(), keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
|
||||
local item3152_effect_caster = {
|
||||
"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_crowrotating.vpcf",
|
||||
"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_crowrotating_b.vpcf",
|
||||
"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_crow.vpcf",
|
||||
}
|
||||
local item3152_effect_target = {
|
||||
"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff.vpcf",
|
||||
"particles/econ/items/queen_of_pain/qop_ti8_immortal/queen_ti8_golden_shadow_strike_debuff_creep.vpcf",
|
||||
}
|
||||
|
||||
function OnItem3152_SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if keys.ability:IsCooldownReady() then
|
||||
keys.ability:StartCooldown(keys.ability:GetCooldown(0))
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if caster.item3152_effect ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.item3152_effect, true)
|
||||
end
|
||||
local effectIndex = ParticleManager:CreateParticle(item3152_effect_caster[RandomInt(1, #item3152_effect_caster)], PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
caster.item3152_effect = effectIndex
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle(item3152_effect_target[RandomInt(1, #item3152_effect_target)], PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
if not caster:THTD_IsTower() then return end
|
||||
|
||||
local damage = caster:THTD_GetStarDamage() * keys.power_damage
|
||||
local targets = THTD_FindUnitsInRadius(caster, target:GetAbsOrigin(), keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_item_3152_debuff") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_item_3152_debuff", nil)
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_PURE,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedItem3150(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3150_bonus")
|
||||
caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3150_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyItem3150(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower("item_3150_bonus")
|
||||
caster:THTD_AddBaseAttack("item_3150_bonus")
|
||||
|
||||
local ability = keys.ability
|
||||
if ability.spell_effect then
|
||||
ParticleManager:DestroyParticle(ability.spell_effect, true)
|
||||
ability.spell_effect = nil
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedItem3151(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3151_bonus")
|
||||
caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3151_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyItem3151(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower("item_3151_bonus")
|
||||
caster:THTD_AddBaseAttack("item_3151_bonus")
|
||||
end
|
||||
|
||||
function OnCreatedItem3152(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3152_bonus")
|
||||
caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3152_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyItem3152(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower("item_3152_bonus")
|
||||
caster:THTD_AddBaseAttack("item_3152_bonus")
|
||||
end
|
||||
|
||||
function OnCreatedItem3153(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower(keys.power_bonus or 0, "item_3153_bonus")
|
||||
caster:THTD_AddBaseAttack(keys.power_bonus or 0, "item_3153_bonus")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/monkey_king/mk_ti9_immortal/mk_ti9_immortal_army_ring.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(700,50,1))
|
||||
caster.item3153_effect = effectIndex
|
||||
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("thtd_item3153_cast"),
|
||||
function()
|
||||
count = count + 1
|
||||
if count > 50 then
|
||||
if caster.item3153_effect ~= nil then
|
||||
ParticleManager:DestroyParticle(caster.item3153_effect, true)
|
||||
caster.item3153_effect = nil
|
||||
return nil
|
||||
end
|
||||
else
|
||||
if caster.item3153_effect ~= nil then
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(700 - count * 15,50,1))
|
||||
end
|
||||
return 0.1
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnDestroyItem3153(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:IsRealHero() then
|
||||
return
|
||||
end
|
||||
|
||||
caster:THTD_AddBasePower("item_3153_bonus")
|
||||
caster:THTD_AddBaseAttack("item_3153_bonus")
|
||||
|
||||
if caster.item3153_effect ~= nil then
|
||||
ParticleManager:DestroyParticle(caster.item3153_effect, true)
|
||||
end
|
||||
|
||||
caster:RemoveModifierByNameAndCaster("modifier_junko_01", caster)
|
||||
end
|
||||
|
||||
function OnItem3153_SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if caster:IsRealHero() then return end
|
||||
if keys.ability:IsCooldownReady() then
|
||||
keys.ability:StartCooldown(keys.ability:GetCooldown(0))
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local damageType = DAMAGE_TYPE_PURE
|
||||
local pureDg = caster:GetDamageOutgoingPure()
|
||||
local magicDg = caster:GetDamageOutgoingMagical()
|
||||
local phyDg = caster:GetDamageOutgoingPhysical()
|
||||
if pureDg >= magicDg and pureDg >= phyDg then
|
||||
damageType = DAMAGE_TYPE_PURE
|
||||
elseif magicDg >= pureDg and magicDg >= phyDg then
|
||||
damageType = DAMAGE_TYPE_MAGICAL
|
||||
elseif phyDg >= magicDg and phyDg >= pureDg then
|
||||
damageType = DAMAGE_TYPE_PHYSICAL
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_omniknight/omniknight_purification.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(100,30,900))
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, 2.5)
|
||||
|
||||
local damage = caster:THTD_GetStarDamage() * keys.power_damage
|
||||
local targets = THTD_FindUnitsInRadius(caster, target:GetAbsOrigin(), 700)
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_item_3153_debuff") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_item_3153_debuff", nil)
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = damageType,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedItem3153Debuff(keys)
|
||||
keys.target:AddDamageIncomingAll(keys.damage_debuff, "thtd_item_3153_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyItem3153Debuff(keys)
|
||||
keys.target:AddDamageIncomingAll("thtd_item_3153_damage_up")
|
||||
end
|
||||
308
scripts/vscripts/abilities/abilityjunko.lua
Executable file
308
scripts/vscripts/abilities/abilityjunko.lua
Executable file
@@ -0,0 +1,308 @@
|
||||
function OnJunko01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
-- if caster == target then return end
|
||||
if not target:THTD_IsTower() then return end
|
||||
if target:HasModifier("modifier_junko_01") then return end
|
||||
if target:GetPlayerOwnerID() ~= caster:GetPlayerOwnerID() then return end
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_junko_01", nil)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_junko/ability_junko_01_buff.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
|
||||
local hasCombo = caster:HasModifier("modifier_thtd_junko_01_combo_buff")
|
||||
if hasCombo then
|
||||
if THTD_IsValid(caster.ability_junko_01_target1) == false then
|
||||
caster.ability_junko_01_target1 = target
|
||||
elseif THTD_IsValid(caster.ability_junko_01_target2) == false then
|
||||
caster.ability_junko_01_target2 = target
|
||||
else
|
||||
caster.ability_junko_01_target1 = caster.ability_junko_01_target2
|
||||
caster.ability_junko_01_target2 = target
|
||||
end
|
||||
else
|
||||
caster.ability_junko_01_target1 = target
|
||||
end
|
||||
|
||||
target:SetContextThink(DoUniqueString("modifier_junko_01"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
if target == nil or target:IsNull() or target:IsAlive() == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
if caster.ability_junko_01_target1 == target then
|
||||
caster.ability_junko_01_target1 = nil
|
||||
elseif caster.ability_junko_01_target2 == target then
|
||||
caster.ability_junko_01_target2 = nil
|
||||
end
|
||||
if caster.ability_junko_01_target1 == nil and caster.ability_junko_01_target2 == nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.ability_junko_01_effectIndex,true)
|
||||
caster.ability_junko_01_effectIndex = nil
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local isCancel = false
|
||||
|
||||
if THTD_IsValid(caster) == false then
|
||||
isCancel = true
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
caster.ability_junko_01_target1 = nil
|
||||
caster.ability_junko_01_target2 = nil
|
||||
end
|
||||
else
|
||||
if caster:HasModifier("modifier_thtd_junko_01_combo_buff") == false then
|
||||
if caster.ability_junko_01_target2 ~= nil then
|
||||
caster.ability_junko_01_target1 = caster.ability_junko_01_target2
|
||||
caster.ability_junko_01_target2 = nil
|
||||
end
|
||||
end
|
||||
isCancel = (caster.ability_junko_01_target1 ~= target and caster.ability_junko_01_target2 ~= target)
|
||||
end
|
||||
|
||||
if isCancel then
|
||||
if target:HasModifier("modifier_junko_01") then
|
||||
target:RemoveModifierByName("modifier_junko_01")
|
||||
end
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
if caster.ability_junko_01_target1 == target then
|
||||
caster.ability_junko_01_target1 = nil
|
||||
elseif caster.ability_junko_01_target2 == target then
|
||||
caster.ability_junko_01_target2 = nil
|
||||
end
|
||||
end
|
||||
if caster.ability_junko_01_target1 == nil and caster.ability_junko_01_target2 == nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.ability_junko_01_effectIndex,true)
|
||||
caster.ability_junko_01_effectIndex = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
return 0.2
|
||||
end,
|
||||
0.2)
|
||||
end
|
||||
|
||||
function OnCreatedJunko01Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
local bonus = 0
|
||||
if target:GetUnitName() == "hecatia" then
|
||||
bonus = keys.hecatia_up
|
||||
else
|
||||
bonus = keys.damage_up
|
||||
end
|
||||
target:AddDamageOutgoingPure(bonus, "thtd_junko_01_damage_up")
|
||||
end
|
||||
|
||||
function OnUpgradeJunko01Buff(keys)
|
||||
local caster = keys.caster
|
||||
local targets = {}
|
||||
if caster.ability_junko_01_target1 ~= nil then
|
||||
table.insert(targets, caster.ability_junko_01_target1)
|
||||
end
|
||||
if caster.ability_junko_01_target2 ~= nil then
|
||||
table.insert(targets, caster.ability_junko_01_target2)
|
||||
end
|
||||
|
||||
for _,target in pairs(targets) do
|
||||
local bonus = 0
|
||||
if target:GetUnitName() == "hecatia" then
|
||||
bonus = keys.hecatia_up
|
||||
else
|
||||
bonus = keys.damage_up
|
||||
end
|
||||
target:AddDamageOutgoingPure(bonus, "thtd_junko_01_damage_up")
|
||||
end
|
||||
|
||||
targets = {}
|
||||
end
|
||||
|
||||
function OnDestroyJunko01Buff(keys)
|
||||
keys.target:AddDamageOutgoingPure("thtd_junko_01_damage_up")
|
||||
end
|
||||
|
||||
function OnJunko02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local casterForward = caster:GetForwardVector()
|
||||
local casterPoint = caster:GetOrigin()
|
||||
|
||||
local point = THTDSystem:FindRadiusOnePointPerfectAOE(caster, caster:Script_GetAttackRange(), 390 * 2)
|
||||
if point ~= nil then
|
||||
casterForward = (Vector(point.x, point.y,casterPoint.z) - casterPoint):Normalized()
|
||||
end
|
||||
|
||||
local duration_time = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
local tick = math.floor(keys.tick * 100 + 0.5) / 100
|
||||
|
||||
local time = duration_time
|
||||
|
||||
caster:SetContextThink("modifier_junko_02_think",
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if not THTD_IsValid(caster) then return nil end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
local forwardCos = casterForward.x
|
||||
local forwardSin = casterForward.y
|
||||
local angle = (39 - 6.5 * RandomInt(0,12)) / 180 * math.pi
|
||||
local forward = Vector( math.cos(angle)*forwardCos - math.sin(angle)*forwardSin,
|
||||
forwardSin*math.cos(angle) + forwardCos*math.sin(angle),0)
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_junko/ability_junko_02.vpcf",
|
||||
vSpawnOrigin = casterPoint + forward * 500 - casterForward * 500 + Vector(0,0,128),
|
||||
fDistance = 1200,
|
||||
fStartRadius = 150,
|
||||
fEndRadius = 150,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO, -- 解决撞击后消失
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = casterForward * 1800,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
casterPoint,
|
||||
casterPoint + casterForward * 1500,
|
||||
nil,
|
||||
390,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
tick)
|
||||
end
|
||||
|
||||
function OnJunko03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
|
||||
local duration_time = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
local damage_up = keys.damage_up
|
||||
local power_suck = keys.power_suck
|
||||
|
||||
local modifier = caster:FindModifierByName("modifier_junko_03_buff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_junko_03_buff", nil)
|
||||
else
|
||||
modifier:SetDuration(duration_time, false)
|
||||
end
|
||||
|
||||
local total = 0
|
||||
for k,v in pairs(friends) do
|
||||
if v ~= caster then
|
||||
local power = v:THTD_GetBasePower()
|
||||
local bonus_power = math.min(power, power_suck)
|
||||
if bonus_power > 0 then
|
||||
total = total + bonus_power
|
||||
v:THTD_AddBasePower(-bonus_power)
|
||||
v:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
v:THTD_AddBasePower(bonus_power)
|
||||
return nil
|
||||
end,
|
||||
duration_time)
|
||||
end
|
||||
end
|
||||
end
|
||||
if total > 0 then
|
||||
caster:THTD_AddBasePower(total)
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:THTD_AddBasePower(-total)
|
||||
return nil
|
||||
end,
|
||||
duration_time)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_junko/ability_junko_03.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnCreatedJunko03Buff(keys)
|
||||
keys.target:AddDamageOutgoingAll(keys.damage_up, "thtd_junko_03_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyJunko03Buff(keys)
|
||||
keys.target:AddDamageOutgoingAll("thtd_junko_03_damage_up")
|
||||
end
|
||||
|
||||
function OnJunko04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
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)
|
||||
if THTD_IsValid(v) and v:HasModifier("modifier_junko_04_debuff") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_junko_04_debuff", nil)
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_junko/ability_junko_04.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint+Vector(0,0,64))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(255,255,255))
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnThinkJunko04Debuff(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
99
scripts/vscripts/abilities/abilitykagerou.lua
Executable file
99
scripts/vscripts/abilities/abilitykagerou.lua
Executable file
@@ -0,0 +1,99 @@
|
||||
function OnSpellStartKagerou01(keys)
|
||||
local caster = keys.caster
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local vecForward = (targetPoint - caster:GetOrigin()):Normalized()
|
||||
local angles = VectorToAngles(vecForward) -- 该方向的角度,水平向右逆时针旋转,360度
|
||||
print(angles.y)
|
||||
local angles2 = VectorToAngles(caster:GetForwardVector()) -- 朝向的角度
|
||||
print(angles2.y)
|
||||
end
|
||||
|
||||
function OnSpellStartKagerou02(keys)
|
||||
local caster = keys.caster
|
||||
local duraiton_time = keys.duration_time
|
||||
caster:RemoveModifierByName("modifier_kagerou_02_buff")
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_kagerou_02_buff", {Duration = duraiton_time})
|
||||
end
|
||||
|
||||
function OnCreatedKagerou02Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
local powerBonus = 0
|
||||
local pv = target:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerBonus = pv[1]
|
||||
end
|
||||
|
||||
if target:IsPower666() then
|
||||
powerBonus = powerBonus + 30
|
||||
end
|
||||
|
||||
local power = target:THTD_GetBasePower()
|
||||
local bonus = (keys.bonus_attack + powerBonus) * power
|
||||
target:THTD_AddBaseAttack(bonus, "thtd_kagerou_02_bonus")
|
||||
target:THTD_AddBasePower(-power, "thtd_kagerou_02_bonus")
|
||||
target:THTD_AddAttackSpeed(keys.attack_speed, "thtd_kagerou_02_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKagerou02Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddBaseAttack("thtd_kagerou_02_bonus")
|
||||
target:THTD_AddBasePower("thtd_kagerou_02_bonus")
|
||||
target:THTD_AddAttackSpeed("thtd_kagerou_02_bonus")
|
||||
end
|
||||
|
||||
function OnSpellStartKagerou03(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
local powerDuration = 0
|
||||
local powerAttackup = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerAttackup = pv[1]
|
||||
powerDuration = pv[2]
|
||||
end
|
||||
|
||||
local attack_up = keys.attack_up + powerAttackup
|
||||
local duraiton_time = keys.duration_time + powerDuration
|
||||
|
||||
local shiftTime = 0.5
|
||||
UnitStunTarget(caster,caster,shiftTime)
|
||||
caster:SetContextThink(DoUniqueString("thtd_yuuka_02_plant"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
caster.kagerou_03_attack_percentage = attack_up
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_kagerou_03_wolf", {Duration = duraiton_time})
|
||||
return nil
|
||||
end,
|
||||
shiftTime)
|
||||
end
|
||||
|
||||
function OnCreatedKagerou03wolf(keys)
|
||||
local target = keys.target
|
||||
local model = "models/heroes/lycan/lycan_wolf.vmdl"
|
||||
if target.origin_mode == nil then
|
||||
target.origin_mode = target:GetModelName()
|
||||
end
|
||||
target:SetOriginalModel(model)
|
||||
target:SetModel(model)
|
||||
|
||||
target:THTD_AddAttackPercentage(target.kagerou_03_attack_percentage, "thtd_kagerou_03_bonus")
|
||||
target:THTD_AddCritChance(keys.crit_chance, "thtd_kagerou_03_bonus")
|
||||
|
||||
local bonus = keys.crit_damage
|
||||
if target:IsPower999() then
|
||||
bonus = bonus + 500
|
||||
end
|
||||
target:THTD_AddCritDamage(bonus, "thtd_kagerou_03_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKagerou03wolf(keys)
|
||||
local target = keys.target
|
||||
target:SetOriginalModel(target.origin_mode )
|
||||
target:SetModel(target.origin_mode )
|
||||
|
||||
target:THTD_AddAttackPercentage("thtd_kagerou_03_bonus")
|
||||
target:THTD_AddCritChance("thtd_kagerou_03_bonus")
|
||||
target:THTD_AddCritDamage("thtd_kagerou_03_bonus")
|
||||
end
|
||||
314
scripts/vscripts/abilities/abilitykaguya.lua
Executable file
314
scripts/vscripts/abilities/abilitykaguya.lua
Executable file
@@ -0,0 +1,314 @@
|
||||
function OnKaguya01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local count = keys.max_count
|
||||
caster:SetContextThink(DoUniqueString("thtd_kaguya01_spell_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count <= 0 then
|
||||
return nil
|
||||
end
|
||||
OnKaguya01SpellThink(keys,count)
|
||||
count = count - 1
|
||||
return 0.7
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnKaguya01SpellThink(keys,count)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
for i=1,count*5 do
|
||||
local forwardVector = caster:GetForwardVector()
|
||||
local rollRad = i*math.pi*2/(count*5)
|
||||
local forwardCos = forwardVector.x
|
||||
local forwardSin = forwardVector.y
|
||||
local damageVector = Vector(math.cos(rollRad)*forwardCos - math.sin(rollRad)*forwardSin,
|
||||
forwardSin*math.cos(rollRad) + forwardCos*math.sin(rollRad),
|
||||
0) * count*100 + targetPoint
|
||||
|
||||
local effectIndex
|
||||
if((i*count*5)%3==0)then
|
||||
effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/kaguya/ability_kaguya01_light.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
elseif((i*count*5)%3==1)then
|
||||
effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/kaguya/ability_kaguya01_light_green.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
elseif((i*count*5)%3==2)then
|
||||
effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/kaguya/ability_kaguya01_light_red.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
end
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, damageVector)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, damageVector)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,damageVector,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
function OnKaguya02SpellThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
if caster.thtd_kaguya_02_count == nil then
|
||||
caster.thtd_kaguya_02_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_kaguya_02_count == 0 then
|
||||
local effectName = "particles/econ/items/windrunner/wr_ti8_immortal_shoulder/wr_ti8_shackleshot_pair_rope_target_glow.vpcf"
|
||||
local effectIndex = ParticleManager:CreateParticle(effectName, PATTACH_ABSORIGIN_FOLLOW, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin() + Vector(0, 0, 100))
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
end
|
||||
|
||||
caster.thtd_kaguya_02_count = caster.thtd_kaguya_02_count + 1
|
||||
if caster.thtd_kaguya_02_count >= 20 then
|
||||
caster.thtd_kaguya_02_count = 0
|
||||
end
|
||||
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetAbsOrigin(),1000)
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_kaguya_02_buff")
|
||||
-- 持续时间比think大一点
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_kaguya_02_buff", {Duration = 0.3})
|
||||
else
|
||||
modifier:SetDuration(0.3, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedKaguya02_buff(keys)
|
||||
local target = keys.target
|
||||
local factor = 0.5
|
||||
if target:GetUnitName() == "kaguya" then
|
||||
factor = 1
|
||||
end
|
||||
target:THTD_AddCritChance(keys.bonus_chance * factor, "thtd_kaguya_02_bonus")
|
||||
target:THTD_AddCritDamage(keys.bonus_crit * factor, "thtd_kaguya_02_bonus")
|
||||
end
|
||||
|
||||
function OnRemoveKaguya02_buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddCritChance("thtd_kaguya_02_bonus")
|
||||
target:THTD_AddCritDamage("thtd_kaguya_02_bonus")
|
||||
end
|
||||
|
||||
function OnKaguya03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_kaguya_03_roll == false then
|
||||
caster.thtd_kaguya_03_roll = true
|
||||
else
|
||||
caster.thtd_kaguya_03_roll = false
|
||||
end
|
||||
end
|
||||
|
||||
function OnUpgradeKaguya03(keys)
|
||||
local caster = keys.caster
|
||||
local friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
local enemies = THTD_FindUnitsAll(caster)
|
||||
for i=1,4 do
|
||||
local buff = "modifier_kaguya_03_"..i.."_buff"
|
||||
local debuff = "modifier_kaguya_03_"..i.."_debuff"
|
||||
for k,v in pairs(friends) do
|
||||
if v:FindModifierByNameAndCaster(buff,caster)~=nil then
|
||||
v:RemoveModifierByName(buff)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(enemies) do
|
||||
if v:FindModifierByNameAndCaster(debuff,caster)~=nil then
|
||||
v:RemoveModifierByName(debuff)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKaguya03SpellThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
if GameRules:IsGamePaused() then return end
|
||||
if caster:THTD_IsHidden() then
|
||||
OnKaguya03ReleaseBall(caster)
|
||||
return
|
||||
end
|
||||
|
||||
if caster.thtd_kaguya_03_treasure_table == nil then
|
||||
caster.thtd_kaguya_03_treasure_table = {}
|
||||
end
|
||||
|
||||
if caster.thtd_kaguya_03_think_count == nil then
|
||||
caster.thtd_kaguya_03_think_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_kaguya_03_roll ~= false then
|
||||
if caster.thtd_kaguya_03_think_count < 360 then
|
||||
caster.thtd_kaguya_03_think_count = caster.thtd_kaguya_03_think_count + 1
|
||||
else
|
||||
caster.thtd_kaguya_03_think_count = 0
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_effect_count == nil then
|
||||
caster.thtd_effect_count = 1
|
||||
end
|
||||
|
||||
-- 旋转宝具
|
||||
for i=1,4 do
|
||||
if caster.thtd_kaguya_03_treasure_table[i] == nil then
|
||||
caster.thtd_kaguya_03_treasure_table[i] = {}
|
||||
end
|
||||
if caster.thtd_kaguya_03_treasure_table[i]["effectIndex"] == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_kaguya/thtd_kaguya_03_"..i..".vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1/12,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(500/12,0,0))
|
||||
caster.thtd_kaguya_03_treasure_table[i]["effectIndex"] = effectIndex
|
||||
end
|
||||
|
||||
if caster.thtd_kaguya_03_roll ~= false then
|
||||
caster.thtd_kaguya_03_treasure_table[i]["origin"] = caster:GetOrigin() +
|
||||
Vector(
|
||||
math.cos(i*2*math.pi/4 + caster.thtd_kaguya_03_think_count * math.pi/180)*400,
|
||||
math.sin(i*2*math.pi/4 + caster.thtd_kaguya_03_think_count * math.pi/180)*400,
|
||||
150)
|
||||
end
|
||||
end
|
||||
|
||||
local friends = {}
|
||||
local enemies = {}
|
||||
if caster.thtd_effect_count >= 10 then
|
||||
friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
enemies = THTD_FindUnitsAll(caster)
|
||||
end
|
||||
for i=1,4 do
|
||||
if caster.thtd_kaguya_03_treasure_table[i]["effectIndex"] ~= nil then
|
||||
ParticleManager:SetParticleControl(caster.thtd_kaguya_03_treasure_table[i]["effectIndex"], 0, caster.thtd_kaguya_03_treasure_table[i]["origin"] )
|
||||
end
|
||||
|
||||
if caster.thtd_effect_count >= 10 then
|
||||
local buff = "modifier_kaguya_03_"..i.."_buff"
|
||||
local debuff = "modifier_kaguya_03_"..i.."_debuff"
|
||||
for k,v in pairs(friends) do
|
||||
if GetDistanceBetweenTwoVec2D(caster.thtd_kaguya_03_treasure_table[i]["origin"], v:GetOrigin()) > keys.range then
|
||||
if v:FindModifierByNameAndCaster(buff,caster)~=nil then
|
||||
v:RemoveModifierByName(buff)
|
||||
end
|
||||
else
|
||||
if v:HasModifier(buff) == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, buff, {})
|
||||
end
|
||||
end
|
||||
end
|
||||
for k,v in pairs(enemies) do
|
||||
if GetDistanceBetweenTwoVec2D(caster.thtd_kaguya_03_treasure_table[i]["origin"], v:GetOrigin()) > keys.range then
|
||||
if v:FindModifierByNameAndCaster(debuff,caster)~=nil then
|
||||
v:RemoveModifierByName(debuff)
|
||||
end
|
||||
else
|
||||
if i ~= 2 and v:HasModifier(debuff) == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, debuff, {})
|
||||
end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2
|
||||
if i == 2 then
|
||||
damage = damage * (1 + keys.damage_up/100)
|
||||
end
|
||||
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
|
||||
end
|
||||
if i == 4 then caster.thtd_effect_count = 1 end
|
||||
else
|
||||
if i == 4 then caster.thtd_effect_count = caster.thtd_effect_count + 1 end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnKaguya03ReleaseBall(caster)
|
||||
if caster.thtd_kaguya_03_treasure_table ~= nil and caster.thtd_kaguya_03_treasure_table[1] ~= nil and caster.thtd_kaguya_03_treasure_table[1]["effectIndex"] ~= nil then
|
||||
local friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
local enemies = THTD_FindUnitsAll(caster)
|
||||
|
||||
for i=1,4 do
|
||||
local buff = "modifier_kaguya_03_"..i.."_buff"
|
||||
local debuff = "modifier_kaguya_03_"..i.."_debuff"
|
||||
for k,v in pairs(friends) do
|
||||
if v:FindModifierByNameAndCaster(buff,caster)~=nil then
|
||||
v:RemoveModifierByName(buff)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(enemies) do
|
||||
if v:FindModifierByNameAndCaster(debuff,caster)~=nil then
|
||||
v:RemoveModifierByName(debuff)
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_kaguya_03_treasure_table[i]["effectIndex"] ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_kaguya_03_treasure_table[i]["effectIndex"],true)
|
||||
caster.thtd_kaguya_03_treasure_table[i]["effectIndex"] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedKaguya03_2_buff(keys)
|
||||
keys.target:THTD_AddAttackPercentage(keys.attack_percent, "thtd_kaguya_03_2_buff_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKaguya03_2_buff(keys)
|
||||
keys.target:THTD_AddAttackPercentage("thtd_kaguya_03_2_buff_bonus")
|
||||
end
|
||||
|
||||
function OnCreatedKaguya03_3_debuff(keys)
|
||||
keys.target:AddDamageIncomingAll(keys.incoming_percent, "thtd_kaguya_03_3_debuff_damage_up")
|
||||
end
|
||||
|
||||
function OnRemoveKaguya03_3_debuff(keys)
|
||||
keys.target:AddDamageIncomingAll("thtd_kaguya_03_3_debuff_damage_up")
|
||||
end
|
||||
|
||||
function OnCreatedKaguya03_3_buff(keys)
|
||||
keys.target:AddDamageOutgoingAll(keys.outgoing_percent, "thtd_kaguya_03_3_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyKaguya03_3_buff(keys)
|
||||
keys.target:AddDamageOutgoingAll("thtd_kaguya_03_3_damage_up")
|
||||
end
|
||||
|
||||
function OnCreatedKaguya03_4_debuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddPhysicalArmor(-keys.armor)
|
||||
end
|
||||
|
||||
function OnDestroyKaguya03_4_debuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddPhysicalArmor(keys.armor)
|
||||
end
|
||||
|
||||
function OnCreatedKaguya03_4_buff(keys)
|
||||
keys.target:AddDamageOutgoingPhysical(keys.penetration, "thtd_kaguya_03_4_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyKaguya03_4_buff(keys)
|
||||
keys.target:AddDamageOutgoingPhysical("thtd_kaguya_03_4_damage_up")
|
||||
end
|
||||
368
scripts/vscripts/abilities/abilitykanako.lua
Executable file
368
scripts/vscripts/abilities/abilitykanako.lua
Executable file
@@ -0,0 +1,368 @@
|
||||
local doorVec =
|
||||
{
|
||||
[0] = Vector(-2440,1880,0),
|
||||
[1] = Vector(2440,1880,0),
|
||||
[2] = Vector(2440,-1880,0),
|
||||
[3] = Vector(-2440,-1880,0),
|
||||
}
|
||||
|
||||
local outX =
|
||||
{
|
||||
[0] = -4300,
|
||||
[1] = 4300,
|
||||
[2] = 4300,
|
||||
[3] = -4300
|
||||
}
|
||||
|
||||
|
||||
function OnKanako01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target:GetOrigin()
|
||||
local targetForward = keys.target:GetForwardVector()
|
||||
|
||||
local duration_time = math.floor(keys.duration_time * 100 + 0.5)/100
|
||||
local tick = math.floor(keys.tick * 100 + 0.5)/100
|
||||
|
||||
local id = caster:GetPlayerOwnerID()
|
||||
if math.abs(targetPoint.x) <= math.abs(doorVec[id].x) then
|
||||
if GetDistanceBetweenTwoVec2D(targetPoint, FirstPointList[id]) < 1200 then
|
||||
targetForward = (targetPoint - FirstPointList[id]):Normalized()
|
||||
end
|
||||
else
|
||||
if GetDistanceBetweenTwoVec2D(targetPoint, FirstPointList[id]) < 2000 then
|
||||
targetForward = (Vector(outX[id], targetPoint.y, 0) - targetPoint):Normalized()
|
||||
end
|
||||
end
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/kanako/ability_kanako_01.vpcf",
|
||||
vSpawnOrigin = targetPoint + Vector(0,0,128),
|
||||
fDistance = 500,
|
||||
fStartRadius = 400,
|
||||
fEndRadius = 400,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = -targetForward * 200,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
caster:SetContextThink(DoUniqueString("thtd_kanako_01_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
return nil
|
||||
end,
|
||||
duration_time - 1.25)
|
||||
|
||||
local origin = targetPoint + targetForward * 150
|
||||
local time = duration_time
|
||||
local count = 0
|
||||
local knockBackGroup = {}
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_kanako_01_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
count = count + 1
|
||||
local targets = THTD_FindUnitsInRadius(caster,origin,300)
|
||||
origin = origin - targetForward * 8
|
||||
for k,v in pairs(targets) do
|
||||
local forward = v:GetForwardVector()
|
||||
v:SetAbsOrigin(v:GetOrigin() - forward * 16)
|
||||
table.insert(knockBackGroup,v)
|
||||
if count == 5 then
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
local modifier = v:FindModifierByName("modifier_kanako_01_stun")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_kanako_01_stun", {duration=0.1})
|
||||
else
|
||||
modifier:SetDuration(0.1,false)
|
||||
end
|
||||
end
|
||||
|
||||
if count == 5 then
|
||||
count = 0
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_kanako/ability_kanako_01_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, origin+Vector(0,0,160) - targetForward * 150)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, targetForward)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(100,1,1))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
if time <= 0 then
|
||||
for k,v in pairs(knockBackGroup) do
|
||||
if IsValidAlive(v) then
|
||||
FindClearSpaceForUnit(v, v:GetOrigin(), false)
|
||||
end
|
||||
end
|
||||
knockBackGroup = {}
|
||||
return nil
|
||||
end
|
||||
|
||||
time = time - 0.04
|
||||
return 0.04
|
||||
end,
|
||||
0.04)
|
||||
end
|
||||
|
||||
function OnKanako02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_kanako_gojou_count == nil then
|
||||
caster.thtd_kanako_gojou_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_kanako_gojou_count < keys.max_count then
|
||||
|
||||
local gojou = CreateUnitByName(
|
||||
"kanako_gojou",
|
||||
targetPoint,
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
if gojou ~= nil then
|
||||
gojou.thtd_spawn_unit_owner = caster
|
||||
gojou:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
||||
FindClearSpaceForUnit(gojou, targetPoint, false)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, gojou, "modifier_kanako_rooted", {})
|
||||
|
||||
local ability = gojou:FindAbilityByName("thtd_kanako_03_unit")
|
||||
if ability then
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
|
||||
if caster.thtd_kanako_gojou_group == nil then
|
||||
caster.thtd_kanako_gojou_group = {}
|
||||
end
|
||||
|
||||
table.insert(caster.thtd_kanako_gojou_group,gojou)
|
||||
caster.thtd_kanako_gojou_count = caster.thtd_kanako_gojou_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKanako03Think(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_kanako_gojou_group == nil then
|
||||
caster.thtd_kanako_gojou_group = {}
|
||||
end
|
||||
|
||||
if keys.ability:GetLevel() < 1 or caster:THTD_IsHidden() then
|
||||
for k,v in pairs(caster.thtd_kanako_gojou_group) do
|
||||
OnKanako03ReleaseUnit(caster,v)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
for k,v in pairs(caster.thtd_kanako_gojou_group) do
|
||||
v.thtd_kanako_gojou_thinked = nil
|
||||
end
|
||||
|
||||
for k,v in pairs(caster.thtd_kanako_gojou_group) do
|
||||
if IsValidAlive(v) and v.thtd_kanako_03_is_contact == true and IsValidAlive(v.thtd_kanako_03_last_link_unit) then
|
||||
if v.thtd_kanako_gojou_thinked ~= true then
|
||||
v.thtd_kanako_gojou_thinked = true
|
||||
v.thtd_kanako_03_last_link_unit.thtd_kanako_gojou_thinked = true
|
||||
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
v:GetOrigin(),
|
||||
v.thtd_kanako_03_last_link_unit:GetOrigin(),
|
||||
nil,
|
||||
80,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
local vecA = v:GetAbsOrigin()
|
||||
local vecB = v.thtd_kanako_03_last_link_unit:GetAbsOrigin()
|
||||
local key = "thtd_kanako_gojou_"..tostring(v:GetEntityIndex()).."_side"
|
||||
|
||||
for index,unit in pairs(targets) do
|
||||
local side = IsLeftToLineSide(unit:GetAbsOrigin(), vecA, vecB)
|
||||
if unit[key] == nil then
|
||||
unit[key] = IsLeftToLineSide(unit:GetAbsOrigin() - 100 * unit:GetForwardVector(), vecA, vecB)
|
||||
end
|
||||
if unit[key] ~= side then
|
||||
-- print("[unit"..tostring(unit:GetEntityIndex()).."]"..key.." : "..tostring(side))
|
||||
unit[key] = side
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = unit,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function OnKanako03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target:GetUnitName() == "kanako_gojou" then
|
||||
OnKanako03ReleaseUnit(caster,target)
|
||||
end
|
||||
end
|
||||
|
||||
function OnKanako03ReleaseUnit(caster,target)
|
||||
if caster.thtd_kanako_gojou_group == nil then
|
||||
caster.thtd_kanako_gojou_group = {}
|
||||
end
|
||||
for k,v in pairs(caster.thtd_kanako_gojou_group) do
|
||||
if v==nil or v:IsNull() or v:IsAlive()==false or v == target then
|
||||
if v.thtd_kanako_03_gojou_effect~=nil then
|
||||
ParticleManager:DestroyParticleSystem(v.thtd_kanako_03_gojou_effect,true)
|
||||
end
|
||||
if v.thtd_kanako_03_last_link_unit ~= nil and v.thtd_kanako_03_last_link_unit:IsNull()==false and v.thtd_kanako_03_last_link_unit:IsAlive() then
|
||||
if v.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(v.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect,true)
|
||||
v.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect = nil
|
||||
end
|
||||
v.thtd_kanako_03_last_link_unit.thtd_kanako_03_is_contact = false
|
||||
end
|
||||
table.remove(caster.thtd_kanako_gojou_group,k)
|
||||
caster.thtd_kanako_gojou_count = caster.thtd_kanako_gojou_count - 1
|
||||
end
|
||||
end
|
||||
|
||||
target:AddNoDraw()
|
||||
target:ForceKill(true)
|
||||
end
|
||||
|
||||
function OnKanako03UnitSpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local hero = caster.thtd_spawn_unit_owner
|
||||
|
||||
if target:GetUnitName() == "kanako_gojou" and caster~=target and target.thtd_kanako_03_is_contact ~= true then
|
||||
if caster.thtd_kanako_03_last_link_unit ~= nil and caster.thtd_kanako_03_last_link_unit:IsNull()==false and caster.thtd_kanako_03_last_link_unit:IsAlive() then
|
||||
caster.thtd_kanako_03_last_link_unit.thtd_kanako_03_is_contact = false
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect,true)
|
||||
caster.thtd_kanako_03_last_link_unit.thtd_kanako_03_gojou_effect = nil
|
||||
end
|
||||
caster.thtd_kanako_03_last_link_unit = target
|
||||
target.thtd_kanako_03_last_link_unit = caster
|
||||
target.thtd_kanako_03_is_contact = true
|
||||
caster.thtd_kanako_03_is_contact = true
|
||||
if caster.thtd_kanako_03_gojou_effect == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_kanako/ability_kanako_03_line.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
caster.thtd_kanako_03_gojou_effect = effectIndex
|
||||
else
|
||||
ParticleManager:SetParticleControlEnt(caster.thtd_kanako_03_gojou_effect , 1, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKanako04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local origin = caster:GetOrigin()
|
||||
|
||||
local time = keys.ability:GetCooldownTimeRemaining()
|
||||
local tick = keys.tick
|
||||
time = math.floor(time * 100 + 0.5) / 100
|
||||
tick = math.floor(tick * 100 + 0.5) / 100
|
||||
|
||||
local key = "thtd_kanako_04_"..tostring(caster:GetEntityIndex()).."_circle"
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_kanako_04_effect", {duration = time})
|
||||
|
||||
caster:THTD_AddCritChance(keys.crit_chance, "thtd_kanako_04_crit_chance")
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_kanako_04_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster:THTD_IsHidden() or time <= 0 then
|
||||
caster:RemoveModifierByName("modifier_kanako_04_effect")
|
||||
caster:AddDamageOutgoingAll("thtd_kanako_04_bonus")
|
||||
caster:THTD_AddCritChance("thtd_kanako_04_crit_chance")
|
||||
return nil
|
||||
end
|
||||
|
||||
if caster:HasModifier("modifier_sanae_04_buff") then
|
||||
caster:AddDamageOutgoingAll(math.floor(caster:THTD_GetFaith() * keys.damage_up), "thtd_kanako_04_bonus")
|
||||
else
|
||||
caster:AddDamageOutgoingAll("thtd_kanako_04_bonus")
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,origin,keys.range + 80)
|
||||
for k,v in pairs(targets) do
|
||||
local isInCircle = (GetDistanceBetweenTwoVec2D(v:GetAbsOrigin(), origin) <= keys.range)
|
||||
if v[key] == nil then
|
||||
v[key] = (GetDistanceBetweenTwoVec2D(v:GetAbsOrigin() - 80 * v:GetForwardVector(), origin) <= keys.range)
|
||||
end
|
||||
if v[key] ~= isInCircle then
|
||||
-- print("[unit"..tostring(v:GetEntityIndex()).."]"..key.." : "..tostring(isInCircle))
|
||||
v[key] = isInCircle
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
|
||||
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
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2)
|
||||
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
|
||||
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
tick)
|
||||
end
|
||||
|
||||
|
||||
function OnKanakoKill(keys)
|
||||
-- local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
-- caster:THTD_AddFaith()
|
||||
end
|
||||
286
scripts/vscripts/abilities/abilitykeine.lua
Executable file
286
scripts/vscripts/abilities/abilitykeine.lua
Executable file
@@ -0,0 +1,286 @@
|
||||
|
||||
THTD_KEINE_02_HUMEN = 1
|
||||
THTD_KEINE_02_SHIRASAWA = 2
|
||||
|
||||
function OnKeine01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_keine_change == nil then
|
||||
caster.thtd_keine_change = THTD_KEINE_02_HUMEN
|
||||
end
|
||||
|
||||
if caster.thtd_keine_change == THTD_KEINE_02_HUMEN then
|
||||
if target:THTD_IsTower() then
|
||||
caster.thtd_last_cast_unit = target
|
||||
|
||||
if target:HasModifier("modifier_keine_01_buff") then
|
||||
target:FindModifierByName("modifier_keine_01_buff"):SetDuration(keys.bonus_time, false)
|
||||
else
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_keine/ability_keine_01_buff.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
keys.ability:ApplyDataDrivenModifier(caster,target, "modifier_keine_01_buff", {duration = keys.bonus_time})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedKeine01Buff(keys)
|
||||
keys.target:THTD_AddBaseAttack(keys.attack_bonus, "thtd_keine_01_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKeine01Buff(keys)
|
||||
keys.target:THTD_AddBaseAttack("thtd_keine_01_bonus")
|
||||
end
|
||||
|
||||
function OnKeine01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
if caster.thtd_keine_change == THTD_KEINE_02_SHIRASAWA then
|
||||
if RollPercentage(keys.chance) then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_keine/ability_keine_01_stun.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(keys.range,keys.range,keys.range))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
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)
|
||||
|
||||
if not v:HasModifier("modifier_keine_01_lock") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_keine_01_lock", {Duration = keys.lock_time})
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKeine02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_keine_change == nil then
|
||||
caster.thtd_keine_change = THTD_KEINE_02_HUMEN
|
||||
end
|
||||
|
||||
if caster.thtd_keine_change == THTD_KEINE_02_HUMEN then
|
||||
caster.thtd_keine_change = THTD_KEINE_02_SHIRASAWA
|
||||
caster:SetModel("models/thd_hero/keine/keine2/keine2.vmdl")
|
||||
caster:SetOriginalModel("models/thd_hero/keine/keine2/keine2.vmdl")
|
||||
if caster.thtd_close_ai == true then
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_keine_shirasawa", duration=5, params={}, color="#0ff"} )
|
||||
end
|
||||
elseif caster.thtd_keine_change == THTD_KEINE_02_SHIRASAWA then
|
||||
caster.thtd_keine_change = THTD_KEINE_02_HUMEN
|
||||
caster:SetModel("models/thd_hero/keine/keine.vmdl")
|
||||
caster:SetOriginalModel("models/thd_hero/keine/keine.vmdl")
|
||||
if caster.thtd_close_ai == true then
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_keine_humen", duration=5, params={}, color="#0ff"} )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKeine03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range1)
|
||||
|
||||
if caster.thtd_keine_change == nil then
|
||||
caster.thtd_keine_change = THTD_KEINE_02_HUMEN
|
||||
end
|
||||
|
||||
if caster.thtd_keine_change == THTD_KEINE_02_HUMEN then
|
||||
for k,v in pairs(targets) do
|
||||
Keine03MarkUnit(v)
|
||||
local modifier = v:FindModifierByName("thtd_keine_03_debuff")
|
||||
if modifier==nil and v.thtd_keine_mark_count < keys.max_count then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "thtd_keine_03_debuff", nil)
|
||||
end
|
||||
end
|
||||
elseif caster.thtd_keine_change == THTD_KEINE_02_SHIRASAWA then
|
||||
for k,v in pairs(targets) do
|
||||
if v:HasModifier("thtd_keine_03_debuff") then
|
||||
v.thtd_keine_mark_count = v.thtd_keine_mark_count + 1
|
||||
v:RemoveModifierByName("thtd_keine_03_debuff")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Keine03MarkUnit(unit)
|
||||
unit.thtd_keine_mark_count = 0
|
||||
unit.thtd_keine_03_origin = unit:GetOrigin()
|
||||
unit.thtd_keine_03_mark_health = unit:GetHealth()
|
||||
unit.thtd_keine_03_next_move_point = unit.next_move_point
|
||||
unit.thtd_keine_03_next_move_forward = unit.next_move_forward
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_keine/ability_keine_03.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, unit:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, unit:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, unit:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnKeine03AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if RollPercentage(keys.chance) then
|
||||
local targetPoint = target:GetOrigin()
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range2)
|
||||
if caster.thtd_keine_change == THTD_KEINE_02_HUMEN then
|
||||
for k,v in pairs(targets) do
|
||||
Keine03MarkUnit(v)
|
||||
local modifier = v:FindModifierByName("thtd_keine_03_debuff")
|
||||
if modifier==nil and v.thtd_keine_mark_count < keys.max_count then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "thtd_keine_03_debuff", nil)
|
||||
end
|
||||
end
|
||||
else
|
||||
for k,v in pairs(targets) do
|
||||
if v:HasModifier("thtd_keine_03_debuff") then
|
||||
v.thtd_keine_mark_count = v.thtd_keine_mark_count + 1
|
||||
v:RemoveModifierByName("thtd_keine_03_debuff")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKeine03Destroy(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target~=nil and target:IsNull()==false and target:IsAlive() and target.thtd_keine_03_origin ~= nil then
|
||||
local distance = GetDistanceBetweenTwoVec2D(target:GetOrigin(), target.thtd_keine_03_origin)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/bosses/thtd_keine/ability_bosses_keine.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
|
||||
FindClearSpaceForUnit(target,target.thtd_keine_03_origin,false)
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
target.next_move_point = target.thtd_keine_03_next_move_point
|
||||
target.next_move_forward = target.thtd_keine_03_next_move_forward
|
||||
target.thtd_keine_03_origin = nil
|
||||
|
||||
local currentHealth = target:GetHealth()
|
||||
local decrease_health = target.thtd_keine_03_mark_health - currentHealth
|
||||
|
||||
target:SetHealth(target.thtd_keine_03_mark_health)
|
||||
|
||||
local ability = caster:FindAbilityByName("thtd_keine_04")
|
||||
if ability:GetLevel() >= 1 then
|
||||
if caster.thtd_keine_04_change == THTD_KEINE_04_SWORD then
|
||||
OnKeine04Sword(keys)
|
||||
elseif caster.thtd_keine_04_change == THTD_KEINE_04_JADE then
|
||||
OnKeine04Jade(keys,distance)
|
||||
elseif caster.thtd_keine_04_change == THTD_KEINE_04_MIRROR then
|
||||
OnKeine04Mirror(keys,decrease_health,currentHealth)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnKeine04Sword(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local info =
|
||||
{
|
||||
Target = keys.target,
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_keine/ability_keine_04_sword.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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
function OnKeine04SwordHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local ability = caster:FindAbilityByName("thtd_keine_04")
|
||||
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)
|
||||
end
|
||||
|
||||
function OnKeine04Jade(keys,distance)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local damage = caster:THTD_GetStarDamage() * (distance/100) * caster:GetAbilityValue("thtd_keine_04", "distance_damage")
|
||||
|
||||
local DamageTable = {
|
||||
ability = caster:FindAbilityByName("thtd_keine_04"),
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnKeine04Mirror(keys,decrease_health,currentHealth)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
target:SetHealth(currentHealth + decrease_health * math.max(0, (1 - caster:GetAbilityValue("thtd_keine_04", "hp_percent"))))
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_keine/ability_keine_04_mirror.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
THTD_KEINE_04_SWORD = 1
|
||||
THTD_KEINE_04_JADE = 2
|
||||
THTD_KEINE_04_MIRROR = 3
|
||||
|
||||
function OnKeine04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_keine_04_change == nil then
|
||||
caster.thtd_keine_04_change = THTD_KEINE_04_SWORD
|
||||
end
|
||||
|
||||
if caster.thtd_keine_04_change == THTD_KEINE_04_SWORD then
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_keine_04_jade", duration=5, params={count=1}, color="#0ff"} )
|
||||
caster.thtd_keine_04_change = THTD_KEINE_04_JADE
|
||||
elseif caster.thtd_keine_04_change == THTD_KEINE_04_JADE then
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_keine_04_mirror", duration=5, params={count=1}, color="#0ff"} )
|
||||
caster.thtd_keine_04_change = THTD_KEINE_04_MIRROR
|
||||
elseif caster.thtd_keine_04_change == THTD_KEINE_04_MIRROR then
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_keine_04_sword", duration=5, params={count=1}, color="#0ff"} )
|
||||
caster.thtd_keine_04_change = THTD_KEINE_04_SWORD
|
||||
end
|
||||
end
|
||||
75
scripts/vscripts/abilities/abilitykisume.lua
Executable file
75
scripts/vscripts/abilities/abilitykisume.lua
Executable file
@@ -0,0 +1,75 @@
|
||||
function OnSpellStartKisume01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then powerDamage = pv[1] end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + powerDamage)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/heroes_underlord/abyssal_underlord_firestorm_wave.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
function OnSpellStartKisume02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_kisume_02_debuff", nil)
|
||||
|
||||
local powerCount = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then powerCount = pv[2] end
|
||||
|
||||
if powerCount > 0 then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetAbsOrigin(), 600)
|
||||
local addTargets = {}
|
||||
local count = 0
|
||||
for k,v in pairs(targets) do
|
||||
if v ~= target then
|
||||
table.insert(addTargets, v)
|
||||
count = count + 1
|
||||
end
|
||||
if count >= powerCount then break end
|
||||
end
|
||||
targets = {}
|
||||
for k,v in pairs(addTargets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_kisume_02_debuff", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnKisume02Think(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local powerHp = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then powerHp = pv[1] end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
|
||||
DamageTable.damage = DamageTable.damage + target:GetHealth() * (keys.damage_hp + powerHp) / 100
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
104
scripts/vscripts/abilities/abilitykoakuma.lua
Executable file
104
scripts/vscripts/abilities/abilitykoakuma.lua
Executable file
@@ -0,0 +1,104 @@
|
||||
|
||||
thtd_koakuma_01 = class({})
|
||||
|
||||
function thtd_koakuma_01:OnSpellStart()
|
||||
local caster = self:GetCaster()
|
||||
local target = self:GetCursorTarget()
|
||||
|
||||
local ExtraData = {
|
||||
count=0
|
||||
}
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_koakuma_01")
|
||||
self:Koakuma01PassToNextUnit(caster,caster:GetOrigin(),target,ExtraData)
|
||||
end
|
||||
|
||||
|
||||
function thtd_koakuma_01:Koakuma01PassToNextUnit(target,target_1,target_2,data)
|
||||
local caster = self:GetCaster()
|
||||
|
||||
local info =
|
||||
{
|
||||
Target = target_2,
|
||||
Source = target,
|
||||
Ability = self,
|
||||
EffectName = "particles/units/heroes/hero_dragon_knight/dragon_knight_elder_dragon_fire.vpcf",
|
||||
iMoveSpeed = 1400,
|
||||
vSourceLoc= target_1, -- 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,
|
||||
iVisionRadius = 400,
|
||||
iVisionTeamNumber = caster:GetTeamNumber(),
|
||||
ExtraData = {
|
||||
count=data.count + 1
|
||||
}
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function thtd_koakuma_01:OnProjectileHit_ExtraData( hTarget, vLocation, data )
|
||||
local caster = self:GetCaster()
|
||||
local target = hTarget
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(self)
|
||||
local DamageTable = {
|
||||
ability = self,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = self:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
caster:EmitSound("Sound_THTD.thtd_koakuma_01.hit")
|
||||
|
||||
local range_damage = self:GetSpecialValueFor("range_damage")
|
||||
if range_damage > 0 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_ogre_magi/ogre_magi_fireblast.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local enemies = THTD_FindUnitsInRadius(caster,vLocation,self:GetSpecialValueFor("range2"))
|
||||
for k,v in pairs(enemies) do
|
||||
local DamageTable = {
|
||||
ability = self,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * range_damage/100,
|
||||
damage_type = self:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,vLocation,self:GetSpecialValueFor("range1"))
|
||||
local max_count = self:GetSpecialValueFor("max_count")
|
||||
for k,v in pairs(targets) do
|
||||
if v~=nil and v~=target and data.count < max_count then
|
||||
self:Koakuma01PassToNextUnit(target,vLocation,v,data)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function OnCreatedKoakuma02Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddMagicalResist(-keys.penetration)
|
||||
end
|
||||
|
||||
function OnDestroyKoakuma02Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddMagicalResist(keys.penetration)
|
||||
end
|
||||
87
scripts/vscripts/abilities/abilitykogasa.lua
Executable file
87
scripts/vscripts/abilities/abilitykogasa.lua
Executable file
@@ -0,0 +1,87 @@
|
||||
function OnKogasa01SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local powerRange = 0
|
||||
local powerDamage = 0
|
||||
local powerSpecial = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerRange = pv[1]
|
||||
powerDamage = pv[2]
|
||||
powerSpecial = pv[3]
|
||||
end
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_kogasa_01")
|
||||
|
||||
local special = 0
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") then
|
||||
special = caster.thtd_byakuren_buff_kogasa + powerSpecial
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + powerDamage)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius + powerRange)
|
||||
for k,v in pairs(targets) do
|
||||
if not v:HasModifier("modifier_kogasa_debuff") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_kogasa_debuff", {Duration = keys.duration_time})
|
||||
end
|
||||
if v.thtd_is_fearing ~= true then
|
||||
v.thtd_is_fearing = true
|
||||
local current_next_move_point = v.next_move_point
|
||||
v.next_move_point = FirstPointList[v.thtd_player_index]
|
||||
|
||||
local time = keys.duration_time
|
||||
v:SetContextThink(DoUniqueString("modifier_kogasa_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if not IsValidAlive(v) then
|
||||
return nil
|
||||
end
|
||||
if time <= 0 or THTD_IsValid(caster) == false then
|
||||
v.next_move_point = current_next_move_point
|
||||
v.thtd_is_fearing = false
|
||||
return nil
|
||||
end
|
||||
time = time - 0.1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
local realDamage = damage
|
||||
if special > 0 then
|
||||
if v.thtd_kogasa_01_special ~= true then
|
||||
v.thtd_kogasa_01_special = true
|
||||
UnitDamageHpRemove(caster, v, special)
|
||||
else
|
||||
realDamage = realDamage * special
|
||||
end
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = realDamage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/kogasa/ability_kogasa_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnCreatedKogasa02Debuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddPhysicalArmor(-keys.armor)
|
||||
end
|
||||
|
||||
function OnDestroyKogasa02Debuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddPhysicalArmor(keys.armor)
|
||||
end
|
||||
210
scripts/vscripts/abilities/abilitykoishi.lua
Executable file
210
scripts/vscripts/abilities/abilitykoishi.lua
Executable file
@@ -0,0 +1,210 @@
|
||||
function OnKoishi01Attack(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.__koishi_lock ~= true then
|
||||
caster.__koishi_lock = true
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),keys.range)
|
||||
|
||||
for i=1,#targets do
|
||||
local unit = targets[i]
|
||||
if unit~=nil and unit:IsNull()==false and unit~=target and unit:IsAlive() then
|
||||
caster:PerformAttack(unit,true,false,true,false,true,false,true)
|
||||
if RollPercentage(keys.chance) then
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = unit,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_dark_willow/dark_willow_bramble.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, unit, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,1.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
caster.__koishi_lock = false
|
||||
end
|
||||
end
|
||||
|
||||
function OnKoishi02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local modifer = caster:FindModifierByName("modifier_koishi_02_attack_speed") or keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_koishi_02_attack_speed", nil)
|
||||
|
||||
local max_count = keys.max_count
|
||||
if caster:HasModifier("passive_koishi_04_attack") then
|
||||
max_count = keys.count_bonus
|
||||
end
|
||||
|
||||
if modifer:GetStackCount() < max_count then
|
||||
modifer:IncrementStackCount()
|
||||
end
|
||||
modifer:SetDuration(keys.duration_time, false)
|
||||
end
|
||||
|
||||
function OnKoishi03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target:THTD_IsTower() and target:HasModifier("modifier_koishi_03_buff") == false then
|
||||
caster.thtd_last_cast_unit = target
|
||||
|
||||
local time = keys.duration_time
|
||||
if caster:FindAbilityByName("thtd_koishi_01"):GetLevel() > 1 then
|
||||
time = keys.combo_time
|
||||
end
|
||||
|
||||
local bonus = keys.power_bonus
|
||||
if target:GetUnitName() == "satori" then
|
||||
if target:IsPower999() then
|
||||
bonus = bonus * (keys.self_crit + 10)
|
||||
else
|
||||
bonus = bonus * keys.self_crit
|
||||
end
|
||||
elseif target:GetUnitName() == "koishi" then
|
||||
bonus = bonus * keys.self_crit
|
||||
end
|
||||
target.koishi_03_power_bonus = bonus
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster,target,"modifier_koishi_03_buff", {Duration = time})
|
||||
target:EmitSound("Hero_OgreMagi.Bloodlust.Target")
|
||||
else
|
||||
keys.ability:EndCooldown()
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedKoishi03Buff(keys)
|
||||
local target = keys.target
|
||||
local bonus = target.koishi_03_power_bonus
|
||||
target:THTD_AddBasePower(bonus, "thtd_koishi_03_bonus")
|
||||
target:THTD_AddBaseAttack(bonus, "thtd_koishi_03_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKoishi03Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddBasePower("thtd_koishi_03_bonus")
|
||||
target:THTD_AddBaseAttack("thtd_koishi_03_bonus")
|
||||
end
|
||||
|
||||
function OnKoishi04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster:HasModifier("passive_koishi_04_attack") then
|
||||
keys.ability:EndCooldown()
|
||||
keys.ability:StartCooldown(1.0)
|
||||
caster:GiveMana(caster:GetRealManaCost(keys.ability))
|
||||
return
|
||||
end
|
||||
|
||||
local time = keys.duration_time
|
||||
|
||||
caster:StartGesture(ACT_DOTA_CAST_ABILITY_4)
|
||||
caster:SetAttackCapability(DOTA_UNIT_CAP_MELEE_ATTACK)
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "passive_koishi_04_attack",nil)
|
||||
caster:EmitSound("Voice_Thdots_Koishi.AbilityKoishi041")
|
||||
caster:EmitSound("Hero_VengefulSpirit.WaveOfTerror")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/events/fall_major_2015/teleport_end_fallmjr_2015_lvl2_black.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,0.8)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_koishi04_buff_remove"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
caster:RemoveGesture(ACT_DOTA_CAST_ABILITY_4)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_koishi04_buff_remove"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:StartGesture(ACT_DOTA_CAST_ABILITY_4_END)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/events/fall_major_2015/teleport_end_fallmjr_2015_lvl2_black.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,0.25)
|
||||
caster:EmitSound("Voice_Thdots_Koishi.AbilityKoishi042")
|
||||
caster:EmitSound("Hero_VengefulSpirit.WaveOfTerror")
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_koishi04_buff_remove"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:RemoveGesture(ACT_DOTA_CAST_ABILITY_4_END)
|
||||
|
||||
caster:SetAttackCapability(DOTA_UNIT_CAP_RANGED_ATTACK)
|
||||
caster:RemoveModifierByName("passive_koishi_04_attack")
|
||||
return nil
|
||||
end,
|
||||
0.25)
|
||||
|
||||
return nil
|
||||
end,
|
||||
time)
|
||||
|
||||
return nil
|
||||
end,
|
||||
0.8)
|
||||
end
|
||||
|
||||
function OnKoishi04AttackStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local count = 3
|
||||
caster:SetContextThink(DoUniqueString("thtd_koishi03_buff_remove"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local num = RandomInt(1,6)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_koishi/ability_koishi_04_attack_0"..num..".vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, caster:GetOrigin() - Vector(0,0,20))
|
||||
ParticleManager:SetParticleControlForward(effectIndex , 0, caster:GetForwardVector()+Vector(0,0,num/12))
|
||||
ParticleManager:SetParticleControlForward(effectIndex , 1, caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_koishi/ability_koishi_04_attack_landed.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, target:GetOrigin() + Vector(0,0,-260))
|
||||
ParticleManager:SetParticleControl(effectIndex , 1, target:GetOrigin() + Vector(0,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex , 2, target:GetOrigin() + Vector(0,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex , 3, target:GetOrigin() + Vector(0,0,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
if count > 0 then
|
||||
count = count - 1
|
||||
return 0.1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
|
||||
function OnKoishi04Kill(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.unit
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/moluo/ability_moluo03_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex , 3, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnCreatedKoishi04Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddBasePower(keys.power_base, "thtd_koishi_04_bonus")
|
||||
target:THTD_AddBaseAttack(keys.power_base, "thtd_koishi_04_bonus")
|
||||
target:THTD_AddPowerPercentage(keys.power_up, "thtd_koishi_04_bonus")
|
||||
target:THTD_AddAttackPercentage(keys.power_up, "thtd_koishi_04_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKoishi04Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddBasePower("thtd_koishi_04_bonus")
|
||||
target:THTD_AddBaseAttack("thtd_koishi_04_bonus")
|
||||
target:THTD_AddPowerPercentage("thtd_koishi_04_bonus")
|
||||
target:THTD_AddAttackPercentage("thtd_koishi_04_bonus")
|
||||
end
|
||||
318
scripts/vscripts/abilities/abilitykokoro.lua
Executable file
318
scripts/vscripts/abilities/abilitykokoro.lua
Executable file
@@ -0,0 +1,318 @@
|
||||
function OnKokoro01SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
local targets = THTD_FindUnitsInRadius(caster, caster:GetAbsOrigin(), keys.ability:GetCastRange())
|
||||
if #targets == 0 then return end
|
||||
for k,v in pairs(targets) do
|
||||
local info =
|
||||
{
|
||||
Target = v,
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/units/heroes/hero_arc_warden/arc_warden_wraith_prj.vpcf",
|
||||
iMoveSpeed = 660,
|
||||
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 = { }
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
KokoroSetPvCrit(caster)
|
||||
KokoroSetMust(caster, 1)
|
||||
end
|
||||
|
||||
function OnProjectileHitUnitKokoro01(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
|
||||
local crit1 = 1
|
||||
local hasBuff1 = false
|
||||
if caster:HasModifier("modifier_kokoro_04_buff_1") then
|
||||
hasBuff1 = true
|
||||
end
|
||||
local damage_up_base = caster:GetAbilityValue("thtd_kokoro_04", "damage_up_base", true)
|
||||
local damage_up_per = caster:GetAbilityValue("thtd_kokoro_04", "damage_up_per", true)
|
||||
local damage_up_factor = 1
|
||||
if caster:IsPower666() then
|
||||
damage_up_factor = 4
|
||||
end
|
||||
local crit2 = KokoroGetPvCrit(caster)
|
||||
if hasBuff1 then
|
||||
crit1 = 1 + (damage_up_base + damage_up_per * (100 - target:GetHealthPercent())) * damage_up_factor
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage * crit1 * crit2,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnKokoro02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
KokoroSetPvCrit(caster)
|
||||
|
||||
local stun_time = keys.stun_time
|
||||
|
||||
local crit1 = 1
|
||||
local hasBuff1 = false
|
||||
if caster:HasModifier("modifier_kokoro_04_buff_1") then
|
||||
hasBuff1 = true
|
||||
end
|
||||
local damage_up_base = caster:GetAbilityValue("thtd_kokoro_04", "damage_up_base", true)
|
||||
local damage_up_per = caster:GetAbilityValue("thtd_kokoro_04", "damage_up_per", true)
|
||||
local damage_up_factor = 1
|
||||
if caster:IsPower666() then
|
||||
damage_up_factor = 4
|
||||
end
|
||||
local crit2 = KokoroGetPvCrit(caster)
|
||||
|
||||
local enemies = THTD_FindUnitsInRadius(caster, caster:GetAbsOrigin(), keys.ability:GetCastRange())
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(enemies) do
|
||||
local unit = CreateUnitByName(
|
||||
"kokoro_jin_yin",
|
||||
caster:GetAbsOrigin(),
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
if unit ~= nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_kokoro_02_rooted", {})
|
||||
-- unit:MoveToTargetToAttack(v)
|
||||
-- 设置朝向
|
||||
local vecForward = (v:GetOrigin() - caster:GetOrigin()):Normalized()
|
||||
unit:SetForwardVector(vecForward)
|
||||
-- local angles = VectorToAngles(vecForward)
|
||||
-- unit:SetAngles(angles.x,angles.y,angles.z)
|
||||
local scale = unit:GetModelScale()
|
||||
local count = 0
|
||||
unit:SetContextThink(
|
||||
DoUniqueString("kokoro02_move"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if v==nil or v:IsNull() or v:IsAlive()==false then
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
if caster==nil or caster:IsNull() or caster:IsAlive()==false or caster:THTD_IsHidden() then
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
|
||||
unit:SetModelScale(scale * (1 + 0.1 * count))
|
||||
unit:MoveToTargetToAttack(v)
|
||||
local vecMove=(unit:GetOrigin()-v:GetOrigin()):Normalized() * 100
|
||||
unit:SetAbsOrigin(GetGroundPosition(unit:GetOrigin()-vecMove, unit))
|
||||
if (unit:GetOrigin()-v:GetOrigin()):Length() < 50 then
|
||||
if hasBuff1 then
|
||||
crit1 = 1 + (damage_up_base + damage_up_per * (100 - v:GetHealthPercent())) * damage_up_factor
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit1 * crit2,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
UnitStunTarget(caster,v,stun_time)
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
|
||||
count = count + 1
|
||||
return 0.05
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
end
|
||||
|
||||
KokoroSetMust(caster, 2)
|
||||
end
|
||||
|
||||
function OnKokoro03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local range = keys.ability:GetCastRange()
|
||||
|
||||
KokoroSetPvCrit(caster)
|
||||
|
||||
-- local effect = "particles/econ/items/mars/mars_fall20_immortal_shield/mars_fall20_immortal_shield_bash.vpcf"
|
||||
local effect1 = "particles/econ/items/mars/mars_fall20_immortal_shield/mars_fall20_immortal_shield_bash_headmodel.vpcf"
|
||||
local effect2 = "particles/units/heroes/hero_mars/mars_shield_bash_model.vpcf"
|
||||
caster:EmitSound("Hero_Mars.Shield.Cast") --"Hero_Mars.Shield.Cast.Small"
|
||||
local casterPoint = caster:GetOrigin()
|
||||
local forward = caster:GetForwardVector()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle(effect1, PATTACH_WORLDORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, forward)
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
local effectIndex = ParticleManager:CreateParticle(effect2, PATTACH_WORLDORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(range, 0, 0))
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, forward)
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
|
||||
local rotate_angle = QAngle(0,45,0)
|
||||
local rotate_forward = (RotatePosition(casterPoint + forward * 300, rotate_angle, casterPoint) - casterPoint):Normalized()
|
||||
local effectIndex = ParticleManager:CreateParticle(effect1, PATTACH_WORLDORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, rotate_forward)
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
local effectIndex = ParticleManager:CreateParticle(effect2, PATTACH_WORLDORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(range, 0, 0))
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, rotate_forward)
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
|
||||
local rotate_angle = QAngle(0,-45,0)
|
||||
local rotate_forward = (RotatePosition(casterPoint + forward * 300, rotate_angle, casterPoint) - casterPoint):Normalized()
|
||||
local effectIndex = ParticleManager:CreateParticle(effect1, PATTACH_WORLDORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, rotate_forward)
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
local effectIndex = ParticleManager:CreateParticle(effect2, PATTACH_WORLDORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, casterPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(range, 0, 0))
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, rotate_forward)
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
|
||||
local crit1 = 1
|
||||
local hasBuff1 = false
|
||||
if caster:HasModifier("modifier_kokoro_04_buff_1") then
|
||||
hasBuff1 = true
|
||||
end
|
||||
local damage_up_base = caster:GetAbilityValue("thtd_kokoro_04", "damage_up_base", true)
|
||||
local damage_up_per = caster:GetAbilityValue("thtd_kokoro_04", "damage_up_per", true)
|
||||
local damage_up_factor = 1
|
||||
if caster:IsPower666() then
|
||||
damage_up_factor = 4
|
||||
end
|
||||
local crit2 = KokoroGetPvCrit(caster)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster, caster:GetAbsOrigin(), range)
|
||||
local damage = caster:THTD_GetAttack() * keys.crit_mult
|
||||
for k,v in pairs(targets) do
|
||||
if hasBuff1 then
|
||||
crit1 = 1 + (damage_up_base + damage_up_per * (100 - v:GetHealthPercent())) * damage_up_factor
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit1 * crit2,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
KokoroSetMust(caster, 3)
|
||||
end
|
||||
|
||||
function KokoroSetMust(caster, index)
|
||||
local ability4 = caster:FindAbilityByName("thtd_kokoro_04")
|
||||
if ability4:GetLevel() > 0 then
|
||||
caster:RemoveModifierByName("modifier_kokoro_04_buff_1")
|
||||
caster:RemoveModifierByName("modifier_kokoro_04_buff_2")
|
||||
caster:RemoveModifierByName("modifier_kokoro_04_buff_3")
|
||||
ability4:ApplyDataDrivenModifier(caster, caster, "modifier_kokoro_04_buff_"..index, nil)
|
||||
end
|
||||
end
|
||||
|
||||
function KokoroSetPvCrit(caster)
|
||||
local powerDamageUp = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_kokoro_04")
|
||||
if pv ~= nil then
|
||||
powerDamageUp = pv[1]
|
||||
end
|
||||
caster.thtd_kokoro_pv_crit = 1 + powerDamageUp * 66/100
|
||||
end
|
||||
|
||||
function KokoroGetPvCrit(caster)
|
||||
return caster.thtd_kokoro_pv_crit or 1
|
||||
end
|
||||
|
||||
function OnCreatedKokoro04Buff2(keys)
|
||||
local target = keys.target
|
||||
|
||||
local bonus = keys.bonus
|
||||
if target:IsPower666() then
|
||||
bonus = bonus * 4
|
||||
end
|
||||
target:THTD_AddPowerPercentage(bonus, "thtd_kokoro_04_buff2_bonus")
|
||||
target:THTD_AddAttackPercentage(bonus, "thtd_kokoro_04_buff2_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKokoro04Buff2(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddPowerPercentage("thtd_kokoro_04_buff2_bonus")
|
||||
target:THTD_AddAttackPercentage("thtd_kokoro_04_buff2_bonus")
|
||||
end
|
||||
|
||||
function OnCreatedKokoro04Buff3(keys)
|
||||
local target = keys.target
|
||||
|
||||
local bonus = keys.crit_damage
|
||||
if target:IsPower666() then
|
||||
bonus = bonus * 4
|
||||
end
|
||||
target:THTD_AddCritDamage(bonus, "thtd_kokoro_04_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKokoro04Buff3(keys)
|
||||
keys.target:THTD_AddCritDamage("thtd_kokoro_04_bonus")
|
||||
end
|
||||
|
||||
function OnKokoro04Think(keys)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local caster = keys.caster
|
||||
|
||||
local bonus = 0
|
||||
if caster:IsPower999() then
|
||||
bonus = 999
|
||||
end
|
||||
local targets = THTD_FindUnitsInRadius(caster, caster:GetAbsOrigin(), keys.ability:GetCastRange())
|
||||
for k,v in pairs(targets) do
|
||||
local hp = v:GetHealthPercent()
|
||||
if hp > 70 then
|
||||
bonus = bonus + hp - 70
|
||||
end
|
||||
if caster:IsPower999() then
|
||||
bonus = bonus + (100 - hp) * 1
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_kokoro_04_power_bonus == bonus then return end
|
||||
|
||||
if caster.thtd_kokoro_04_power_bonus ~= nil then
|
||||
caster:THTD_AddBasePower(-caster.thtd_kokoro_04_power_bonus)
|
||||
caster:THTD_AddBaseAttack(-caster.thtd_kokoro_04_power_bonus)
|
||||
end
|
||||
caster:THTD_AddBasePower(bonus)
|
||||
caster:THTD_AddBaseAttack(bonus)
|
||||
caster.thtd_kokoro_04_power_bonus = bonus
|
||||
end
|
||||
292
scripts/vscripts/abilities/abilitykomachi.lua
Executable file
292
scripts/vscripts/abilities/abilitykomachi.lua
Executable file
@@ -0,0 +1,292 @@
|
||||
function OnAttackKomachi01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/komachi/ability_komachi_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex , 1, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 1, caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, false)
|
||||
end
|
||||
|
||||
function OnAttackLandedKomachi01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local range = caster:Script_GetAttackRange()
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),range)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
end
|
||||
|
||||
function OnCreatedKomachi01Buff(keys)
|
||||
-- 被动需要加延时确保在初始化之后
|
||||
keys.target:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
keys.target:THTD_AddCritChance(keys.chance, "thtd_komachi_01_chance")
|
||||
return nil
|
||||
end,
|
||||
0.3)
|
||||
end
|
||||
|
||||
function OnThinkKomachi01(keys)
|
||||
local caster = keys.caster
|
||||
local range = caster:Script_GetAttackRange()
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),range)
|
||||
local crit = 0
|
||||
local chance = 0
|
||||
for k,v in pairs(targets) do
|
||||
local lostHp = 100 - v:GetHealthPercent()
|
||||
crit = crit + math.floor(lostHp/4) * keys.crit_bonus
|
||||
end
|
||||
caster:THTD_AddCritDamage(crit, "thtd_komachi_01_bonus")
|
||||
end
|
||||
|
||||
function OnSpellStartKomachi02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_dark_seer/dark_seer_vacuum.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(keys.radius,0, 0))
|
||||
|
||||
caster:EmitSound("Hero_Dark_Seer.Vacuum")
|
||||
|
||||
local time = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
local tick = 0.03
|
||||
caster:SetContextThink(DoUniqueString("thtd_komachi_02"),
|
||||
function()
|
||||
if THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, true)
|
||||
return nil
|
||||
end
|
||||
if time < 0 then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, true)
|
||||
caster:StopSound("Hero_Dark_Seer.Vacuum")
|
||||
|
||||
targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
for k, v in pairs(targets) do
|
||||
local distance = (v:GetAbsOrigin() - targetPoint):Length2D()
|
||||
local in_pull = 700
|
||||
local new_pos = GetGroundPosition(v:GetAbsOrigin(), v)
|
||||
if distance > 20 then
|
||||
local direction = (targetPoint - new_pos):Normalized()
|
||||
direction.z = 0.0
|
||||
new_pos = new_pos + direction * in_pull * tick
|
||||
end
|
||||
v:SetOrigin(new_pos)
|
||||
end
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnSpellStartKomachi03(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetUnit = keys.target
|
||||
|
||||
local targets = {}
|
||||
local count = 0
|
||||
local modifierName = "modifier_komachi_03_debuff"
|
||||
|
||||
if not targetUnit:HasModifier(modifierName) then
|
||||
table.insert(targets, targetUnit)
|
||||
count = count + 1
|
||||
end
|
||||
if count < keys.max_count then
|
||||
local rangeTargets = THTD_FindUnitsInRadius(caster,targetUnit:GetAbsOrigin(),1000)
|
||||
for k,v in pairs(rangeTargets) do
|
||||
if not v:HasModifier(modifierName) then
|
||||
table.insert(targets, v)
|
||||
count = count + 1
|
||||
if count >= keys.max_count then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #targets == 0 then
|
||||
keys.ability:EndCooldown()
|
||||
return
|
||||
end
|
||||
|
||||
for _,target in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, modifierName, {})
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedKomachi03Debuff(keys)
|
||||
keys.target:AddDamageIncomingAll(keys.damage_up, "thtd_komachi_02_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyKomachi03Debuff(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
target:AddDamageIncomingAll("thtd_komachi_02_damage_up")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/komachi/ability_komachi_03_explosion_2.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, target:GetOrigin() + Vector(0,0,128))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, false)
|
||||
end
|
||||
|
||||
function OnSpellStartKomachi04(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local vecCaster = caster:GetOrigin()
|
||||
|
||||
if target:HasModifier("modifier_komachi_04") then
|
||||
keys.ability:EndCooldown()
|
||||
return
|
||||
end
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_komachi_04",{Duration = 2.0})
|
||||
keys.ability:ApplyDataDrivenModifier(caster,target,"modifier_komachi_04",{Duration = 2.0})
|
||||
target.komachi_04_damage_lock = true
|
||||
|
||||
local rad = GetRadBetweenTwoVec2D(caster:GetOrigin(),target:GetOrigin())
|
||||
local tarForward = Vector(math.cos(rad),math.sin(rad),0)
|
||||
|
||||
target:SetForwardVector(tarForward)
|
||||
|
||||
-- 渐隐效果
|
||||
-- local effectIndex_start = ParticleManager:CreateParticle("particles/heroes/komachi/ability_komachi_04_start.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
-- ParticleManager:SetParticleControl(effectIndex_start, 0, vecCaster)
|
||||
-- ParticleManager:SetParticleControlForward(effectIndex_start, 0, tarForward)
|
||||
|
||||
-- caster:SetContextThink(DoUniqueString("OnKomachi04SpellStart"),
|
||||
-- function ()
|
||||
-- if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/komachi/ability_komachi_04_blink.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin()-tarForward*250)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, tarForward)
|
||||
|
||||
caster:SetOrigin(target:GetOrigin()-tarForward*150)
|
||||
caster:SetForwardVector(tarForward)
|
||||
caster:StartGesture(ACT_DOTA_CAST_ABILITY_4)
|
||||
|
||||
-- return nil
|
||||
-- end,
|
||||
-- 2.0)
|
||||
|
||||
local time = 2.0
|
||||
caster:SetContextThink(DoUniqueString("OnKomachi04SpellStart_stage_2"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if not THTD_IsValid(caster) then
|
||||
target.komachi_04_damage_lock = false
|
||||
target:RemoveModifierByName("modifier_komachi_04")
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, true)
|
||||
if caster ~= nil and caster:IsNull() == false then
|
||||
caster:RemoveModifierByName("modifier_komachi_04")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
if not THTD_IsValid(target) then
|
||||
caster:SetOrigin(vecCaster)
|
||||
caster:RemoveModifierByName("modifier_komachi_04")
|
||||
if target ~= nil and target:IsNull() == false then
|
||||
target:RemoveModifierByName("modifier_komachi_04")
|
||||
end
|
||||
caster:EmitSound("Hero_Axe.Culling_Blade_Success")
|
||||
|
||||
local bonusTime = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
local modifier = caster:FindModifierByName("modifier_komachi_04_buff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_komachi_04_buff",{Duration=bonusTime})
|
||||
else
|
||||
modifier:SetDuration(bonusTime, false)
|
||||
end
|
||||
|
||||
if keys.bonus_power > 0 then
|
||||
local skipedCount = 0
|
||||
if SpawnSystem.ReachToWave ~= nil then
|
||||
if caster.skiped_wave == nil then
|
||||
caster.skiped_wave = SpawnSystem.ReachToWave + 50 - SpawnSystem.CurWave - 1
|
||||
end
|
||||
elseif caster.skiped_wave ~= nil then
|
||||
skipedCount = caster.skiped_wave * 2
|
||||
caster.skiped_wave = nil
|
||||
end
|
||||
modifier = caster:FindModifierByName("modifier_komachi_04_kill_power_bonus")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_komachi_04_kill_power_bonus",{}):SetStackCount(1)
|
||||
caster:THTD_AddBasePower(keys.bonus_power)
|
||||
elseif modifier:GetStackCount() < 999 then
|
||||
local addCount = math.min(999 - modifier:GetStackCount(), 1 + skipedCount)
|
||||
modifier:SetStackCount(modifier:GetStackCount() + addCount)
|
||||
caster:THTD_AddBasePower(keys.bonus_power * addCount)
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
if time <= 0 then
|
||||
target.komachi_04_damage_lock = false
|
||||
caster:RemoveModifierByName("modifier_komachi_04")
|
||||
target:RemoveModifierByName("modifier_komachi_04")
|
||||
|
||||
local effectIndex_end = ParticleManager:CreateParticle("particles/heroes/komachi/ability_komachi_04_scythe.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControl(effectIndex_end, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex_end, 1, target:GetOrigin())
|
||||
|
||||
caster:SetOrigin(vecCaster)
|
||||
|
||||
if target:GetHealthPercent() <= keys.hp_kill then
|
||||
caster:NpcKill(target)
|
||||
else
|
||||
caster:AbilityKill(target, keys.ability)
|
||||
end
|
||||
time = -1
|
||||
return 0.1
|
||||
end
|
||||
|
||||
if time <= -1 then
|
||||
return nil
|
||||
end
|
||||
|
||||
time = time - 0.1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnCreatedKomachi04Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddAttackSpeed(keys.attack_speed, "thtd_komachi_04_bonus")
|
||||
target:AddDamageOutgoingAll(keys.damage_up, "thtd_komachi_04_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyKomachi04Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddAttackSpeed("thtd_komachi_04_bonus")
|
||||
target:AddDamageOutgoingAll("thtd_komachi_04_bonus")
|
||||
end
|
||||
304
scripts/vscripts/abilities/abilitykyouko.lua
Executable file
304
scripts/vscripts/abilities/abilitykyouko.lua
Executable file
@@ -0,0 +1,304 @@
|
||||
function OnSpellStartKyouko01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.ability:GetCursorPosition()
|
||||
local effects = {
|
||||
"particles/units/heroes/hero_queenofpain/queen_sonic_wave.vpcf",
|
||||
"particles/econ/items/queen_of_pain/qop_arcana/qop_arcana_sonic_wave.vpcf",
|
||||
"particles/econ/items/queen_of_pain/qop_arcana/qop_arcana_sonic_wave_v2.vpcf",
|
||||
}
|
||||
|
||||
local powerDamageUp = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_kyouko_01")
|
||||
if pv ~= nil then
|
||||
powerDamageUp = pv[1]
|
||||
end
|
||||
caster.thtd_kyouko_01_damage_up = keys.damage_up + powerDamageUp
|
||||
|
||||
if caster:IsPower999() then
|
||||
if caster.kyouko_power999_bonus ~= true then
|
||||
caster:THTD_AddCritChance(75)
|
||||
caster:THTD_AddCritDamage(500)
|
||||
caster.kyouko_power999_bonus = true
|
||||
end
|
||||
else
|
||||
if caster.kyouko_power999_bonus == true then
|
||||
caster:THTD_AddCritChance(-75)
|
||||
caster:THTD_AddCritDamage(-500)
|
||||
caster.kyouko_power999_bonus = nil
|
||||
end
|
||||
end
|
||||
|
||||
local direction = (targetPoint - caster:GetAbsOrigin()):Normalized()
|
||||
direction.z = 0
|
||||
|
||||
if caster:IsPower666() then
|
||||
local count = 3
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
count = count - 1
|
||||
if count < 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = effects[#effects - count],
|
||||
vSpawnOrigin = caster:GetAbsOrigin(),
|
||||
fDistance = keys.distance,
|
||||
fStartRadius = keys.starting_aoe,
|
||||
fEndRadius = keys.final_aoe,
|
||||
Source = caster,
|
||||
iSourceAttachment = "mouth",
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = direction * keys.speed,
|
||||
bProvidesVision = false,
|
||||
ExtraData = {}
|
||||
}
|
||||
ProjectileManager:CreateLinearProjectile(info)
|
||||
return 1.0
|
||||
end,
|
||||
0)
|
||||
else
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = effects[RandomInt(1, #effects)],
|
||||
vSpawnOrigin = caster:GetAbsOrigin(),
|
||||
fDistance = keys.distance,
|
||||
fStartRadius = keys.starting_aoe,
|
||||
fEndRadius = keys.final_aoe,
|
||||
Source = caster,
|
||||
iSourceAttachment = "mouth",
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = direction * keys.speed,
|
||||
bProvidesVision = false,
|
||||
ExtraData = {}
|
||||
}
|
||||
ProjectileManager:CreateLinearProjectile(info)
|
||||
end
|
||||
end
|
||||
|
||||
function OnProjectileHitUnitKyouko01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + (caster.thtd_byakuren_buff_kyouko or 0)/100)
|
||||
|
||||
local crit = 1.0
|
||||
local modifier = target:FindModifierByName("modifier_thtd_kyouko_01_debuff")
|
||||
if modifier ~= nil then
|
||||
local count = modifier:GetStackCount()
|
||||
crit = crit + count * caster.thtd_kyouko_01_damage_up/100
|
||||
modifier:SetStackCount(math.min(999, count+1))
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_thtd_kyouko_01_debuff", nil):SetStackCount(1)
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
|
||||
function OnSpellStartKyouko02(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
if caster:IsPower999() then
|
||||
if caster.kyouko_power999_bonus ~= true then
|
||||
caster:THTD_AddCritChance(75)
|
||||
caster:THTD_AddCritDamage(500)
|
||||
caster.kyouko_power999_bonus = true
|
||||
end
|
||||
else
|
||||
if caster.kyouko_power999_bonus == true then
|
||||
caster:THTD_AddCritChance(-75)
|
||||
caster:THTD_AddCritDamage(-500)
|
||||
caster.kyouko_power999_bonus = nil
|
||||
end
|
||||
end
|
||||
|
||||
caster.thtd_kyouko_02_first = true
|
||||
|
||||
if caster:IsPower666() then
|
||||
local count = 3
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if count == 2 then caster.thtd_kyouko_02_first = false end
|
||||
count = count - 1
|
||||
if count < 0 then
|
||||
return nil
|
||||
end
|
||||
OnSpellStartKyouko02Work(keys)
|
||||
return 0.9
|
||||
end,
|
||||
0)
|
||||
else
|
||||
OnSpellStartKyouko02Work(keys)
|
||||
end
|
||||
end
|
||||
|
||||
function OnSpellStartKyouko02Work(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effects = {
|
||||
[1] = {
|
||||
["start"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_start.vpcf",
|
||||
["ground"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_ground.vpcf",
|
||||
["proj"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_proj.vpcf",
|
||||
},
|
||||
[2] = {
|
||||
["start"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_start_v2.vpcf",
|
||||
["ground"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_ground_v2.vpcf",
|
||||
["proj"] = "particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_echoslam_proj_v2.vpcf",
|
||||
},
|
||||
}
|
||||
local effectTable = effects[RandomInt(1,2)]
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
|
||||
-- if #targets > 0 then
|
||||
-- EmitSoundOnLocationWithCaster(targetPoint, "Hero_EarthShaker.EchoSlam", caster)
|
||||
-- else
|
||||
-- EmitSoundOnLocationWithCaster(targetPoint, "Hero_EarthShaker.EchoSlamSmall", caster)
|
||||
-- end
|
||||
|
||||
-- caster:SetContextThink(DoUniqueString("OnSpellStartKyouko02"),
|
||||
-- function()
|
||||
-- if #targets == 2 then
|
||||
-- local random_response = RandomInt(1, 4)
|
||||
-- if random_response >= 3 then random_response = random_response + 1 end
|
||||
-- EmitSoundOnLocationWithCaster(targetPoint, "earthshaker_erth_ability_echo_0"..random_response, caster)
|
||||
-- elseif #targets >= 3 then
|
||||
-- EmitSoundOnLocationWithCaster(targetPoint, "earthshaker_erth_ability_echo_03", caster)
|
||||
-- elseif #targets == 0 then
|
||||
-- EmitSoundOnLocationWithCaster(targetPoint, "earthshaker_erth_ability_echo_0"..(RandomInt(6, 7)), caster)
|
||||
-- end
|
||||
-- return nil
|
||||
-- end,
|
||||
-- 0.5)
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_kyouko_02")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
caster.thtd_kyouko_02_damage = (keys.power_damage + powerDamage) * caster:THTD_GetStarDamage()
|
||||
|
||||
local effect_counter = 0
|
||||
|
||||
local count = 0
|
||||
for _, enemy in pairs(targets) do
|
||||
count = count + 1
|
||||
if count%5 == 0 then
|
||||
if effect_counter < 5 then
|
||||
effect_counter = effect_counter + 1
|
||||
end
|
||||
caster:SetContextThink(DoUniqueString("OnSpellStartKyouko02"),
|
||||
function()
|
||||
local echo_slam_death_pfx = ParticleManager:CreateParticle(effectTable["ground"], PATTACH_ABSORIGIN, enemy)
|
||||
ParticleManager:SetParticleControl(echo_slam_death_pfx, 6, Vector(math.min(effect_counter, 1), math.min(effect_counter, 1), math.min(effect_counter, 1)))
|
||||
ParticleManager:SetParticleControl(echo_slam_death_pfx, 10, Vector(keys.duration_time + 1, 0, 0)) -- earth particle duration
|
||||
ParticleManager:ReleaseParticleIndex(echo_slam_death_pfx)
|
||||
return nil
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
|
||||
local crit = 1.0
|
||||
local modifier = enemy:FindModifierByName("modifier_thtd_kyouko_01_debuff")
|
||||
if modifier ~= nil then
|
||||
crit = crit + modifier:GetStackCount() * caster.thtd_kyouko_01_damage_up/100
|
||||
end
|
||||
|
||||
if caster.thtd_kyouko_02_first == true then UnitStunTarget(caster,enemy,keys.duration_time) end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = enemy,
|
||||
attacker = caster,
|
||||
damage = caster.thtd_kyouko_02_damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
if enemy.is_random_boss == true then
|
||||
local pfx_screen = ParticleManager:CreateParticleForPlayer("particles/econ/items/earthshaker/earthshaker_arcana/earthshaker_arcana_aftershock_screen.vpcf", PATTACH_ABSORIGIN_FOLLOW, enemy, caster:GetPlayerOwner())
|
||||
ParticleManager:ReleaseParticleIndex(pfx_screen)
|
||||
end
|
||||
|
||||
local echo_enemies = THTD_FindUnitsInRadius(caster,enemy:GetAbsOrigin(),keys.range)
|
||||
|
||||
for _, echo_enemy in pairs(echo_enemies) do
|
||||
if echo_enemy ~= enemy then
|
||||
-- echo_enemy:EmitSound("Hero_EarthShaker.EchoSlamEcho")
|
||||
ProjectileManager:CreateTrackingProjectile(
|
||||
{
|
||||
Target = echo_enemy,
|
||||
Source = enemy,
|
||||
Ability = keys.ability,
|
||||
EffectName = effectTable["proj"],
|
||||
iMoveSpeed = 1100,
|
||||
vSourceLoc = enemy:GetAbsOrigin(),
|
||||
bDrawsOnMinimap = false,
|
||||
bDodgeable = false,
|
||||
bIsAttack = false,
|
||||
bVisibleToEnemies = true,
|
||||
bReplaceExisting = false,
|
||||
flExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bProvidesVision = false,
|
||||
ExtraData = {}
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local echo_slam_particle = ParticleManager:CreateParticle(effectTable["start"], PATTACH_ABSORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(echo_slam_particle, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(echo_slam_particle, 10, Vector(keys.duration_time + 1, 0, 0))
|
||||
ParticleManager:SetParticleControl(echo_slam_particle, 11, Vector(math.min(#targets, 1), math.min(#targets, 1), 0 ))
|
||||
ParticleManager:ReleaseParticleIndex(echo_slam_particle)
|
||||
|
||||
end
|
||||
|
||||
function OnProjectileHitUnitKyouko02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_kyouko_02_first == true then UnitStunTarget(caster,target,keys.duration_time) end
|
||||
|
||||
local crit = 1.0
|
||||
local modifier = target:FindModifierByName("modifier_thtd_kyouko_01_debuff")
|
||||
if modifier ~= nil then
|
||||
crit = crit + modifier:GetStackCount() * caster.thtd_kyouko_01_damage_up/100
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster.thtd_kyouko_02_damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
72
scripts/vscripts/abilities/abilityletty.lua
Executable file
72
scripts/vscripts/abilities/abilityletty.lua
Executable file
@@ -0,0 +1,72 @@
|
||||
function OnLetty01SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local powerCount = 0
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerCount = pv[1]
|
||||
powerDamage = pv[2]
|
||||
end
|
||||
|
||||
local maxCount = keys.max_count + powerCount
|
||||
local count_effect = maxCount
|
||||
local count = maxCount
|
||||
keys.ability:StartCooldown(maxCount - 1)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_letty01_spell_start_effect"),
|
||||
function()
|
||||
for i=1,20 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/letty/ability_letty_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint + Vector(math.cos(math.pi/4*i),math.sin(math.pi/4*i),0)*200 + RandomVector(100))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
count_effect = count_effect - 1
|
||||
caster:EmitSound("Sound_THTD.thtd_letty_01")
|
||||
if count_effect > 0 then
|
||||
return 1.0
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_letty01_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
local damage = (caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()) * 2^(maxCount - count)
|
||||
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
|
||||
|
||||
count = count - 1
|
||||
if count > 0 then
|
||||
return 1.0
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnCreatedLetty02Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddMagicalResist(-keys.magic_armor)
|
||||
end
|
||||
|
||||
function OnDestroyLetty02Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddMagicalResist(keys.magic_armor)
|
||||
end
|
||||
117
scripts/vscripts/abilities/abilitylily.lua
Executable file
117
scripts/vscripts/abilities/abilitylily.lua
Executable file
@@ -0,0 +1,117 @@
|
||||
function OnLily01SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
local ability = keys.ability
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster:GetMaxMana() ~= (caster.lily_max_mana or 100) then
|
||||
caster:SetMaxMana(caster.lily_max_mana or 100)
|
||||
end
|
||||
|
||||
if SpawnSystem.IsUnLimited == false and GameRules:GetCustomGameDifficulty() < FUNNY_MODE then
|
||||
local targets =
|
||||
FindUnitsInRadius(
|
||||
caster:GetTeamNumber(),
|
||||
targetPoint,
|
||||
nil,
|
||||
keys.radius,
|
||||
ability:GetAbilityTargetTeam(),
|
||||
ability:GetAbilityTargetType(),
|
||||
ability:GetAbilityTargetFlags(),
|
||||
FIND_CLOSEST,
|
||||
false
|
||||
)
|
||||
|
||||
local exp = caster:THTD_GetPower() * keys.power_factor
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if v ~= nil and v:IsNull() == false and v:THTD_IsTower() and v ~= caster and v:GetOwner() == caster:GetOwner() and v:THTD_GetLevel() < THTD_MAX_LEVEL then
|
||||
v:THTD_AddExp(exp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
local maxDamage = caster:GetKillDamage()
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = math.min(maxDamage, damage + v:GetHealth() * keys.hp_damage/100),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lily/ability_lily_01_a.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnLily01EffectThink(keys)
|
||||
local caster = keys.caster
|
||||
local ability = keys.ability
|
||||
|
||||
if SpawnSystem.IsUnLimited and caster.is_unlimited_mana_buff ~= true then
|
||||
caster.is_unlimited_mana_buff = true
|
||||
caster:AddManaCostReducePercent(keys.mana_down, "thtd_lily_01_unlimited_mana_buff")
|
||||
caster.lily_max_mana = 100 - caster:GetManaCostReducePercent()
|
||||
end
|
||||
|
||||
if caster:GetMaxMana() ~= (caster.lily_max_mana or 100) then
|
||||
caster:SetMaxMana(caster.lily_max_mana or 100)
|
||||
end
|
||||
|
||||
if ability:IsFullyCastable() then
|
||||
if caster.thtd_lily_01_effectIndex == nil then
|
||||
caster.thtd_lily_01_effectIndex = ParticleManager:CreateParticle("particles/heroes/lily/ability_lily_01_ready.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(caster.thtd_lily_01_effectIndex , 0, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
end
|
||||
elseif caster.thtd_lily_01_effectIndex ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_lily_01_effectIndex,true)
|
||||
caster.thtd_lily_01_effectIndex = nil
|
||||
end
|
||||
end
|
||||
|
||||
function OnLily02SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
if caster:GetMaxMana() ~= (caster.lily_max_mana or 100) then
|
||||
caster:SetMaxMana(caster.lily_max_mana or 100)
|
||||
end
|
||||
|
||||
local powerRange = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_lily_02")
|
||||
if pv ~= nil then
|
||||
powerRange = pv[1]
|
||||
end
|
||||
local range = powerRange + keys.radius
|
||||
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetAbsOrigin(),range)
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_lily_02_buff", nil)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lily/ability_lily_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(range, range, range))
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration)
|
||||
end
|
||||
|
||||
function OnCreatedLily02Buff(keys)
|
||||
local factor = 1
|
||||
if keys.target:GetUnitName() == "lily" then
|
||||
local date = string.sub(GameRules.GameData.server_time,6,10)
|
||||
if date >= "02-05" and date <= "05-05" then
|
||||
factor = keys.self_crit
|
||||
end
|
||||
end
|
||||
keys.target:AddDamageOutgoingAll(keys.damage_up * factor, "thtd_lily_02_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyLily02Buff(keys)
|
||||
keys.target:AddDamageOutgoingAll("thtd_lily_02_damage_up")
|
||||
end
|
||||
|
||||
169
scripts/vscripts/abilities/abilityluna.lua
Executable file
169
scripts/vscripts/abilities/abilityluna.lua
Executable file
@@ -0,0 +1,169 @@
|
||||
function OnLuna01Attack(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
local attackedTargets = {}
|
||||
OnLuna01Damage(keys,target,1)
|
||||
table.insert(attackedTargets, target)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local count = 1
|
||||
for k,v in pairs(targets) do
|
||||
if count > keys.max_count then
|
||||
break
|
||||
end
|
||||
if THTD_IsValid(v) and v ~= target then
|
||||
OnLuna01Damage(keys,v,1 + keys.damage_up/100)
|
||||
table.insert(attackedTargets, v)
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
local fairyArea = nil
|
||||
local hero = caster:GetOwner()
|
||||
if hero~=nil and hero:IsNull()==false then
|
||||
local fairyList = GetHeroFairyList(hero)
|
||||
for k,v in pairs(fairyList) do
|
||||
if v.luna == caster then
|
||||
fairyArea = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if fairyArea ~= nil then
|
||||
local pos1 = fairyArea.sunny:GetAbsOrigin()
|
||||
local pos2 = fairyArea.star:GetAbsOrigin()
|
||||
local pos3 = fairyArea.luna:GetAbsOrigin()
|
||||
local center, radius = GetCircleCenterAndRadius(pos1,pos2,pos3)
|
||||
local targetsTotal = {}
|
||||
local fairyTargets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
for _,v in pairs(fairyTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() and IsUnitInFairy(fairyArea,v) then
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
end
|
||||
for k,v in pairs(targetsTotal) do
|
||||
local isExist = false
|
||||
for k2,v2 in pairs(attackedTargets) do
|
||||
if v2 == v then
|
||||
isExist = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if isExist == false and THTD_IsValid(v) then
|
||||
OnLuna01Damage(keys,v,1 + keys.damage_up/100)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnLuna01Damage(keys,target,percentage)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_luna/ability_luna_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 5, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * percentage
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnLuna02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
local foward = (targetPoint - caster:GetAbsOrigin()):Normalized()
|
||||
|
||||
local targetsTotal = {}
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + foward*1000,
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
local fairyArea = nil
|
||||
local hero = caster:GetOwner()
|
||||
if hero~=nil and hero:IsNull()==false then
|
||||
local fairyList = GetHeroFairyList(hero)
|
||||
for k,v in pairs(fairyList) do
|
||||
if v.luna == caster then
|
||||
fairyArea = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if fairyArea ~= nil then
|
||||
local pos1 = fairyArea.sunny:GetAbsOrigin()
|
||||
local pos2 = fairyArea.star:GetAbsOrigin()
|
||||
local pos3 = fairyArea.luna:GetAbsOrigin()
|
||||
local center, radius = GetCircleCenterAndRadius(pos1,pos2,pos3)
|
||||
local fairyTargets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
for _,v in pairs(fairyTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() and IsUnitInFairy(fairyArea,v) then
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
targets = {}
|
||||
|
||||
if caster:HasModifier("modifier_luna_02_buff") then
|
||||
caster:RemoveModifierByName("modifier_luna_02_buff")
|
||||
end
|
||||
caster.luna_02_power_bonus = keys.bonus_power * table.count(targetsTotal)
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster, "modifier_luna_02_buff", {Duration = keys.duration_time})
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targetsTotal) 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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_luna/ability_luna_02_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, caster:GetOrigin() + foward*1000 + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, caster:GetOrigin() + foward*1000 + Vector(0,0,128))
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, caster:GetOrigin() + Vector(0,0,128))
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)
|
||||
end
|
||||
|
||||
function OnCreatedLuna02Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
local bonus = target.luna_02_power_bonus
|
||||
target:THTD_AddPowerPercentage(bonus, "thtd_luna_02_bonus")
|
||||
target:THTD_AddAttackPercentage(bonus, "thtd_luna_02_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyLuna02Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddPowerPercentage("thtd_luna_02_bonus")
|
||||
target:THTD_AddAttackPercentage("thtd_luna_02_bonus")
|
||||
end
|
||||
105
scripts/vscripts/abilities/abilitylunasa.lua
Executable file
105
scripts/vscripts/abilities/abilitylunasa.lua
Executable file
@@ -0,0 +1,105 @@
|
||||
|
||||
function OnLunasa01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_lunasa_01")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_lunasa_01_debuff", nil)
|
||||
|
||||
UpdatePrismriverComboName(caster,v)
|
||||
|
||||
local comboName = GetPrismriverComboName(v)
|
||||
if comboName == "lyricamerlinlunasa" then
|
||||
OnLyricaMerlinLunasa(keys,caster,v)
|
||||
ResetPrismriverComboName(v)
|
||||
elseif comboName == "merlinlyricalunasa" then
|
||||
OnMerlinLyricaLunasa(keys,caster,v)
|
||||
ResetPrismriverComboName(v)
|
||||
end
|
||||
|
||||
local time = keys.duration_time
|
||||
v:SetContextThink(DoUniqueString("thtd_lunasa01_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
if v==nil or v:IsNull() or v:IsAlive()==false then return nil end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.5
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
time = time - 0.5
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lunasa/ability_lunasa_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnLunasa02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local abilty_01 = caster:FindAbilityByName("thtd_lunasa_01")
|
||||
abilty_01:ApplyDataDrivenModifier(caster, target, "modifier_lunasa_01_debuff", nil)
|
||||
|
||||
local time = abilty_01:GetSpecialValueFor("duration_time")
|
||||
target:SetContextThink(DoUniqueString("thtd_lunasa02_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
if target==nil or target:IsNull() or target:IsAlive()==false then return nil end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.5
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
time = time - 0.5
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
|
||||
UpdatePrismriverComboName(caster,target)
|
||||
end
|
||||
|
||||
function OnLyricaMerlinLunasa(keys,caster,target)
|
||||
local modifier = target:FindModifierByName("modifier_lunasa_01_pause")
|
||||
if modifier ~= nil then
|
||||
modifier:SetDuration(keys.stun_time1,false)
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster,target,"modifier_lunasa_01_pause",{Duration = keys.stun_time1})
|
||||
end
|
||||
end
|
||||
|
||||
function OnMerlinLyricaLunasa(keys,caster,target)
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.radius)
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_lunasa_01_pause")
|
||||
if modifier ~= nil then
|
||||
modifier:SetDuration(keys.stun_time2,false)
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_lunasa_01_pause",{Duration = keys.stun_time2})
|
||||
end
|
||||
end
|
||||
end
|
||||
95
scripts/vscripts/abilities/abilitylyrica.lua
Executable file
95
scripts/vscripts/abilities/abilitylyrica.lua
Executable file
@@ -0,0 +1,95 @@
|
||||
|
||||
function OnLyrica01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local isEnabled = false
|
||||
if caster:FindAbilityByName("thtd_lyrica_02"):GetLevel() >= 1 then
|
||||
isEnabled = true
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
for k,v in pairs(targets) do
|
||||
UpdatePrismriverComboName(caster,v)
|
||||
|
||||
if isEnabled then
|
||||
if v:HasModifier("modifier_lunasa_01_debuff") then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lunasa/ability_lunasa_music_buff.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
if v:HasModifier("modifier_merlin_01_debuff") then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/merlin/ability_merlin_music_buff.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
|
||||
if caster:HasModifier("modifier_lyrica_lunasa_merlin_combo") then
|
||||
damage = damage * (1 + keys.damage_up/100)
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
if THTD_IsValid(v) then
|
||||
local count = GetCountPrismriver(v)
|
||||
local comboName = GetPrismriverComboName(v)
|
||||
if comboName == "merlinlunasalyrica" then
|
||||
OnMerlinLunasaLyrica(keys,caster,v,count)
|
||||
ResetPrismriverComboName(v)
|
||||
elseif comboName == "lunasamerlinlyrica" then
|
||||
OnLunasaMerlinLyrica(keys,caster,v,count)
|
||||
ResetPrismriverComboName(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_lyrica_01")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lyrica/ability_lyrica_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnMerlinLunasaLyrica(keys,caster,target,count)
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.radius)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2) * (1 + keys.damage_up/100) * (1 + count)
|
||||
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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/lyrica/ability_lyrica_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnLunasaMerlinLyrica(keys,caster,target,count)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 3) * (1 + keys.damage_up/100) * (1 + count)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
369
scripts/vscripts/abilities/abilitymarisa.lua
Executable file
369
scripts/vscripts/abilities/abilitymarisa.lua
Executable file
@@ -0,0 +1,369 @@
|
||||
local marisa_star_table =
|
||||
{
|
||||
"particles/heroes/thtd_marisa/ability_marisa_02.vpcf",
|
||||
"particles/heroes/thtd_marisa/ability_marisa_02_pink.vpcf",
|
||||
"particles/heroes/thtd_marisa/ability_marisa_02_blue.vpcf",
|
||||
"particles/heroes/thtd_marisa/ability_marisa_02_normal.vpcf",
|
||||
}
|
||||
|
||||
function OnMarisa01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.spelling_lock == true then return end
|
||||
caster.factor = 0
|
||||
|
||||
if caster.ability_dummy_unit~=nil then
|
||||
caster.ability_dummy_unit:RemoveSelf()
|
||||
keys.ability.effectcircle = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectcircle,true)
|
||||
keys.ability.effectIndex = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex,true)
|
||||
keys.ability.effectIndex_b = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex_b,true)
|
||||
end
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"npc_dota2x_unit_marisa04_spark"
|
||||
,caster:GetOrigin()
|
||||
,false
|
||||
,caster
|
||||
,caster
|
||||
,caster:GetTeam()
|
||||
)
|
||||
local ability_dummy_unit = unit:FindAbilityByName("ability_dummy_unit")
|
||||
ability_dummy_unit:SetLevel(1)
|
||||
|
||||
keys.ability.effectcircle = ParticleManager:CreateParticle("particles/heroes/marisa/marisa_04_spark_circle.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
keys.ability.effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/marisa/marisa_04_spark.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
keys.ability.effectIndex_b = ParticleManager:CreateParticle("particles/thd2/heroes/marisa/marisa_04_spark_wind_b.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
keys.ability:SetContextNum("ability_marisa_04_spark_unit",unit:GetEntityIndex(),0)
|
||||
|
||||
MarisaSparkParticleControl(caster,keys.ability,targetPoint)
|
||||
keys.ability:SetContextNum("ability_marisa_04_spark_lock",0,0)
|
||||
|
||||
caster.thtd_marisa_01_count = 1
|
||||
caster.thtd_marisa_01_last_distance = 10
|
||||
caster.thtd_marisa_01_currentForward = caster:GetForwardVector()
|
||||
caster.ability_dummy_unit = unit
|
||||
caster.spelling_lock = true
|
||||
local locktime = keys.channel_time
|
||||
caster:SetContextThink(DoUniqueString("thtd_marisa_lock"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster.spelling_lock == true then return nil end
|
||||
if caster == nil or caster:IsNull() or caster:IsAlive() == false then return nil end
|
||||
caster.spelling_lock = false
|
||||
return nil
|
||||
end,
|
||||
locktime)
|
||||
end
|
||||
|
||||
function MarisaSparkParticleControl(caster,ability,targetPoint)
|
||||
local unitIndex = ability:GetContext("ability_marisa_04_spark_unit")
|
||||
local unit = EntIndexToHScript(unitIndex)
|
||||
|
||||
if(ability.targetPoint == targetPoint)then
|
||||
return
|
||||
else
|
||||
ability.targetPoint = targetPoint
|
||||
end
|
||||
|
||||
if(unit == nil or ability.effectIndex == -1 or ability.effectcircle == -1)then
|
||||
return
|
||||
end
|
||||
|
||||
forwardRad = GetRadBetweenTwoVec2D(targetPoint,caster:GetOrigin())
|
||||
vecForward = Vector(math.cos(math.pi/2 + forwardRad),math.sin(math.pi/2 + forwardRad),0)
|
||||
unit:SetForwardVector(vecForward)
|
||||
vecUnit = caster:GetOrigin() + Vector(caster:GetForwardVector().x * 100,caster:GetForwardVector().y * 100,160)
|
||||
vecColor = Vector(255,255,255)
|
||||
unit:SetAbsOrigin(vecUnit)
|
||||
|
||||
ParticleManager:SetParticleControl(ability.effectcircle, 0, caster:GetOrigin())
|
||||
|
||||
local effect2ForwardRad = GetRadBetweenTwoVec2D(caster:GetOrigin(),targetPoint)
|
||||
local effect2VecForward = Vector(math.cos(effect2ForwardRad)*1400,math.sin(effect2ForwardRad)*1400,0) + caster:GetOrigin() + Vector(caster:GetForwardVector().x * 100,caster:GetForwardVector().y * 100,108)
|
||||
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 0, caster:GetOrigin() + Vector(caster:GetForwardVector().x * 92,caster:GetForwardVector().y * 92,150))
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 1, effect2VecForward)
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 2, vecColor)
|
||||
local forwardRadwind = forwardRad + math.pi
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 8, Vector(math.cos(forwardRadwind),math.sin(forwardRadwind),0))
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 9, caster:GetOrigin() + Vector(caster:GetForwardVector().x * 100,caster:GetForwardVector().y * 100,108))
|
||||
|
||||
ParticleManager:SetParticleControl(ability.effectIndex_b, 0, caster:GetOrigin() + Vector(caster:GetForwardVector().x * 92,caster:GetForwardVector().y * 92,150))
|
||||
ParticleManager:SetParticleControlForward(ability.effectIndex_b, 3, Vector(math.cos(forwardRadwind),math.sin(forwardRadwind),0))
|
||||
end
|
||||
|
||||
function OnMarisa01SpellRemove(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
caster:THTD_AddPowerPercentage("thtd_marisa_03_bonus")
|
||||
|
||||
local unitIndex = keys.ability:GetContext("ability_marisa_04_spark_unit")
|
||||
|
||||
local unit = EntIndexToHScript(unitIndex)
|
||||
if unit~=nil then
|
||||
unit:RemoveSelf()
|
||||
keys.ability.effectcircle = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectcircle,true)
|
||||
keys.ability.effectIndex = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex,true)
|
||||
keys.ability.effectIndex_b = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex_b,true)
|
||||
end
|
||||
keys.ability:SetContextNum("ability_marisa_04_spark_lock",1,0)
|
||||
|
||||
if keys.ability:GetAbilityName() == "thtd_marisa_03" then
|
||||
caster:StopSound("Sound_THTD.thtd_marisa_03")
|
||||
else
|
||||
caster:StopSound("Sound_THTD.thtd_marisa_01")
|
||||
end
|
||||
|
||||
caster.ability_dummy_unit = nil
|
||||
caster.spelling_lock = false
|
||||
end
|
||||
|
||||
function FindMarisa01MaxCountEnemeiesForward(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local forwardVector = caster.thtd_marisa_01_currentForward
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),keys.DamageLenth)
|
||||
|
||||
if #targets <= 0 then
|
||||
return nil,0
|
||||
end
|
||||
local maxCount = 0
|
||||
|
||||
for i=1,120 do
|
||||
local sparkRad = math.pi * i/60
|
||||
local count = 0
|
||||
for k,v in pairs(targets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
if IsRadInRect(v:GetOrigin(),caster:GetOrigin(),keys.DamageWidth,keys.DamageLenth,sparkRad) then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
if count > maxCount then
|
||||
forwardVector = Vector(math.cos(sparkRad),math.sin(sparkRad),forwardVector.z)
|
||||
maxCount = count
|
||||
end
|
||||
end
|
||||
|
||||
return forwardVector,maxCount
|
||||
end
|
||||
|
||||
function GetMarisa01ForwardMove(forward,nextForward,rad)
|
||||
local forwardVector = Vector(math.cos(rad)*forward.x - math.sin(rad)*forward.y,
|
||||
forward.y*math.cos(rad) + forward.x*math.sin(rad),
|
||||
0)
|
||||
return forwardVector
|
||||
end
|
||||
|
||||
function OnMarisa01SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
if(keys.ability:GetContext("ability_marisa_04_spark_lock")==1)then
|
||||
return
|
||||
end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
|
||||
if caster.factor == nil then
|
||||
caster.factor = 0
|
||||
end
|
||||
|
||||
if keys.ability:GetAbilityName() == "thtd_marisa_03" then
|
||||
local nextForward,maxCount = FindMarisa01MaxCountEnemeiesForward(keys)
|
||||
|
||||
if nextForward ~= nil then
|
||||
local forward = GetMarisa01ForwardMove(caster.thtd_marisa_01_currentForward,nextForward,caster.thtd_marisa_01_count * math.pi/180)
|
||||
local distance = GetDistanceBetweenTwoVec2D(forward, nextForward)
|
||||
|
||||
if caster.thtd_marisa_01_last_distance <= distance then
|
||||
caster.thtd_marisa_01_count = caster.thtd_marisa_01_count * -1
|
||||
end
|
||||
caster.thtd_marisa_01_last_distance = distance
|
||||
|
||||
local NowDamageTargets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + keys.DamageLenth * caster.thtd_marisa_01_currentForward,
|
||||
nil,
|
||||
keys.DamageWidth,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
local NowCount = 0
|
||||
|
||||
for k,v in pairs(NowDamageTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
NowCount = NowCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
if distance > math.sin(math.pi/18) and distance < 1.86 and NowCount~=maxCount then
|
||||
caster:SetForwardVector(forward)
|
||||
caster.thtd_marisa_01_currentForward = forward
|
||||
end
|
||||
else
|
||||
caster:SetForwardVector(caster.thtd_marisa_01_currentForward)
|
||||
end
|
||||
|
||||
if caster.factor == 100 then
|
||||
local powerUp = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_marisa_03")
|
||||
if pv ~= nil then
|
||||
powerUp = pv[2]
|
||||
end
|
||||
local bonus = keys.power_up + powerUp
|
||||
if caster:IsPower666() then
|
||||
bonus = bonus * 2
|
||||
end
|
||||
caster:THTD_AddPowerPercentage(bonus, "thtd_marisa_03_bonus")
|
||||
end
|
||||
end
|
||||
|
||||
local targetPoint = vecCaster + caster.thtd_marisa_01_currentForward
|
||||
|
||||
if caster.factor % 10 == 0 then
|
||||
local DamageTargets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + keys.DamageLenth * caster.thtd_marisa_01_currentForward,
|
||||
nil,
|
||||
keys.DamageWidth,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
if #DamageTargets > 0 then
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_marisa_03")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local deal_damage = (caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()) * 0.2
|
||||
if caster:FindAbilityByName("thtd_marisa_02"):GetLevel() > 1 then
|
||||
deal_damage = deal_damage * (1 + 0.01 * caster.factor)
|
||||
end
|
||||
if caster:IsPower666() then deal_damage = deal_damage * 2 end
|
||||
if caster:IsPower999() then deal_damage = deal_damage * 4 end
|
||||
for _,v in pairs(DamageTargets) do
|
||||
local info =
|
||||
{
|
||||
Target = v,
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = marisa_star_table[RandomInt(1,#marisa_star_table)],
|
||||
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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = deal_damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
end
|
||||
caster.factor = caster.factor + 1
|
||||
MarisaSparkParticleControl(caster,keys.ability,targetPoint)
|
||||
end
|
||||
|
||||
function OnMarisa02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local count = 2
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),caster:Script_GetAttackRange())
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_marisa02_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if #targets > 0 then
|
||||
local index = RandomInt(1,#targets)
|
||||
local info =
|
||||
{
|
||||
Target = targets[index],
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = marisa_star_table[RandomInt(1,#marisa_star_table)],
|
||||
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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
caster:EmitSound("Hero_Marisa.PreAttack")
|
||||
|
||||
if count > 0 then
|
||||
count = count - 1
|
||||
return 0.1
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
|
||||
function OnMarisa02SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
target:EmitSound("Hero_Marisa.ProjectileImpact")
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_marisa_02")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + powerDamage/100),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
if keys.ability:GetAbilityName() == "thtd_marisa_02" then
|
||||
caster:GiveMana(eys.mana)
|
||||
end
|
||||
end
|
||||
171
scripts/vscripts/abilities/abilitymedicine.lua
Executable file
171
scripts/vscripts/abilities/abilitymedicine.lua
Executable file
@@ -0,0 +1,171 @@
|
||||
-- 回头、方向旋转角度实现可参考
|
||||
function OnMedicine01AttackLandedOld(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local modifier = target:FindModifierByName("modifier_medicine_01_slow")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_medicine_01_slow", {Duration = keys.duration_time})
|
||||
|
||||
local time =keys.duration_time
|
||||
local tick = keys.tick_time
|
||||
target:AddPoison(1, caster)
|
||||
target:SetContextThink(DoUniqueString("thtd_medicine01_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if THTD_IsValid(target) == false then return nil end
|
||||
if time <= 0 then
|
||||
target:AddPoison(-1)
|
||||
return nil
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * tick
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
|
||||
if target.thtd_is_fearing ~= true then
|
||||
target.thtd_is_fearing = true
|
||||
local current_next_move_point = target.next_move_point
|
||||
target.next_move_point = RotatePosition(target:GetOrigin(), QAngle(0,RandomInt(-70, 70),0), target:GetOrigin() - target:GetForwardVector() * 500)
|
||||
local time = keys.fear_time
|
||||
target:SetContextThink(DoUniqueString("modifier_medicine_01_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if not IsValidAlive(target) then
|
||||
return nil
|
||||
end
|
||||
if time <= 0 or THTD_IsValid(caster) == false then
|
||||
target.next_move_point = current_next_move_point
|
||||
target.thtd_is_fearing = false
|
||||
return nil
|
||||
end
|
||||
|
||||
time = time - 0.1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
else
|
||||
modifier:SetDuration(keys.duration_time,false)
|
||||
end
|
||||
end
|
||||
|
||||
function OnMedicine01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local modifier = target:FindModifierByName("modifier_medicine_01_slow")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_medicine_01_slow", {Duration = keys.duration_time})
|
||||
else
|
||||
modifier:SetDuration(keys.duration_time,false)
|
||||
end
|
||||
|
||||
local time = keys.duration_time
|
||||
local tick = keys.tick_time
|
||||
target:AddPoison(1, caster)
|
||||
target:SetContextThink(DoUniqueString("thtd_medicine01_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if THTD_IsValid(target) == false then return nil end
|
||||
if time <= 0 then
|
||||
target:AddPoison(-1)
|
||||
return nil
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * tick * target:GetPoisonCount()
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnMedicine02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_medicine/ability_medicine_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, keys.duration_time)
|
||||
|
||||
local time = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
local tick = math.floor(keys.tick_time * 100 + 0.5) / 100
|
||||
-- print(keys.duration_time, time)
|
||||
-- print(keys.tick_time, tick)
|
||||
-- local startTime = GameRules:GetGameTime()
|
||||
caster:SetContextThink(DoUniqueString("modifier_medicine_02_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then
|
||||
-- print("----- ability end")
|
||||
-- print(GameRules:GetGameTime() - startTime)
|
||||
return nil
|
||||
end
|
||||
if THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * tick
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
if v.thtd_is_fearing ~= true then
|
||||
v.thtd_is_fearing = true
|
||||
|
||||
v:AddPoison(1, caster)
|
||||
local current_next_move_point = v.next_move_point
|
||||
v.next_move_point = targetPoint
|
||||
|
||||
v:SetContextThink(DoUniqueString("modifier_medicine_02_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
if not IsValidAlive(v) then
|
||||
return nil
|
||||
end
|
||||
if time <= 0 or THTD_IsValid(caster) == false then
|
||||
v.next_move_point = current_next_move_point
|
||||
v.thtd_is_fearing = false
|
||||
return nil
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
316
scripts/vscripts/abilities/abilitymeirin.lua
Executable file
316
scripts/vscripts/abilities/abilitymeirin.lua
Executable file
@@ -0,0 +1,316 @@
|
||||
local thtd_meirin_01_activity =
|
||||
{
|
||||
[1] =
|
||||
{
|
||||
["action"] = ACT_DOTA_ATTACK,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*800
|
||||
--caster:EmitSoundParams("Hero_KeeperOfTheLight.Illuminate.Discharge",1,0.1,2)
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + caster:GetForwardVector()*800,
|
||||
nil,
|
||||
300,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable_aoe = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable_aoe)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01_step_1.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster+Vector(0,0,32))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(0,0,32))
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, vecCaster+Vector(0,0,32))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
[2] =
|
||||
{
|
||||
["action"] = ACT_DOTA_ATTACK2,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*800
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
damage = damage * (1 + keys.damage_up)^1
|
||||
--caster:EmitSoundParams("Hero_Tusk.WalrusPunch.Target",1,0.3,2)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),800)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local vVec = v:GetOrigin()
|
||||
local vecRad = GetRadBetweenTwoVec2D(targetPoint,vecCaster)
|
||||
|
||||
if(IsPointInCircularSector(vVec.x,vVec.y,math.cos(vecRad),math.sin(vecRad),800,math.pi*2/3,vecCaster.x,vecCaster.y))then
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 1 , caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
[3] =
|
||||
{
|
||||
["action"] = ACT_DOTA_CAST_ABILITY_4,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*400
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
damage = damage * (1 + keys.damage_up)^2
|
||||
-- caster:EmitSoundParams("Hero_EarthShaker.EchoSlamSmall",1,0.5,2)
|
||||
caster:EmitSound("Hero_EarthShaker.EchoSlamSmall")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,400)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_meirin_01_slow_buff", {})
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01_step_2.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(800,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(255,140,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
[4] =
|
||||
{
|
||||
["action"] = ACT_DOTA_CAST_ABILITY_5,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*800
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
damage = damage * (1 + keys.damage_up)^3
|
||||
--caster:EmitSoundParams("Hero_Tusk.WalrusPunch.Target",1,0.35,2)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),800)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local vVec = v:GetOrigin()
|
||||
local vecRad = GetRadBetweenTwoVec2D(targetPoint,vecCaster)
|
||||
|
||||
if(IsPointInCircularSector(vVec.x,vVec.y,math.cos(vecRad),math.sin(vecRad),800,math.pi*2/3,vecCaster.x,vecCaster.y))then
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 1 , caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
[5] =
|
||||
{
|
||||
["action"] = ACT_DOTA_CAST_ABILITY_4,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*400
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
damage = damage * (1 + keys.damage_up)^4
|
||||
--caster:EmitSoundParams("Hero_Tusk.WalrusPunch.Damage",1,0.4,2)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,400)
|
||||
local stun_time = caster:GetAbilityValue("thtd_meirin_02", "level5_stun_time")
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
UnitStunTarget(caster,v,stun_time)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01_step_3.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(800,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(255,140,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
[6] =
|
||||
{
|
||||
["action"] = ACT_DOTA_CAST_ABILITY_6,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*800
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
damage = damage * (1 + keys.damage_up)^5
|
||||
--caster:EmitSoundParams("Hero_KeeperOfTheLight.Illuminate.Discharge",1,0.25,2)
|
||||
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + caster:GetForwardVector()*800,
|
||||
nil,
|
||||
300,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable_aoe = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable_aoe)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01_step_1.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster+Vector(0,0,32))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(0,0,32))
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, vecCaster+Vector(0,0,32))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
[7] =
|
||||
{
|
||||
["action"] = ACT_DOTA_CAST_ABILITY_4,
|
||||
["duration"] = 0.55,
|
||||
func = function(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector()*400
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
damage = damage * (1 + keys.damage_up)^6
|
||||
-- damage = damage * 3
|
||||
-- caster:EmitSoundParams("Hero_ElderTitan.EchoStomp",1,0.45,2)
|
||||
caster:EmitSound("Hero_ElderTitan.EchoStomp")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,400)
|
||||
local stun_time = caster:GetAbilityValue("thtd_meirin_02", "level7_stun_time")
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
UnitStunTarget(caster,v,stun_time)
|
||||
end
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_meirin/ability_meirin_01_step_4.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(800,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(221,160,221))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
},
|
||||
}
|
||||
|
||||
function OnMeirin01AttackThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if keys.ability:GetLevel() < 1 or caster:THTD_IsHidden() then return end
|
||||
|
||||
if caster.thtd_meirin_01_attack_step == nil then
|
||||
caster.thtd_meirin_01_attack_step = 1
|
||||
end
|
||||
|
||||
if caster:HasModifier("modifier_meirin_01_pause") == false then
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),500)
|
||||
if #targets > 0 and targets[1]~=nil and targets[1]:IsNull()==false and targets[1]:IsAlive() then
|
||||
keys.target = targets[1]
|
||||
local ability2 = caster:FindAbilityByName("thtd_meirin_02")
|
||||
local chance = 100
|
||||
local stun_time = 0
|
||||
local level = 3
|
||||
if ability2:IsActivated() then
|
||||
level = 7
|
||||
if caster.thtd_meirin_01_attack_step == 4 then
|
||||
chance = ability2:GetSpecialValueFor("level4_chance")
|
||||
elseif caster.thtd_meirin_01_attack_step == 6 then
|
||||
chance = ability2:GetSpecialValueFor("level6_chance")
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_meirin_01_attack_step <= level and RollPercentage(chance) then
|
||||
caster:StartGestureWithPlaybackRate(thtd_meirin_01_activity[caster.thtd_meirin_01_attack_step]["action"],1)
|
||||
local func = thtd_meirin_01_activity[caster.thtd_meirin_01_attack_step].func
|
||||
caster:EmitSound("Hero_Axe.PreAttack")
|
||||
caster:SetContextThink(DoUniqueString("modifier_meirin_01_attack"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if func then
|
||||
func(keys)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
thtd_meirin_01_activity[caster.thtd_meirin_01_attack_step]["duration"])
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_meirin_01_pause", {duration=thtd_meirin_01_activity[caster.thtd_meirin_01_attack_step]["duration"]})
|
||||
caster.thtd_meirin_01_attack_step = caster.thtd_meirin_01_attack_step + 1
|
||||
else
|
||||
caster.thtd_meirin_01_attack_step = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
87
scripts/vscripts/abilities/abilitymerlin.lua
Executable file
87
scripts/vscripts/abilities/abilitymerlin.lua
Executable file
@@ -0,0 +1,87 @@
|
||||
|
||||
function OnMerlin01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_merlin_01")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_merlin_01_debuff", nil)
|
||||
|
||||
UpdatePrismriverComboName(caster,v)
|
||||
|
||||
local comboName = GetPrismriverComboName(v)
|
||||
if comboName == "lunasalyricamerlin" then
|
||||
OnLunasaLyricaMerlin(keys,caster,v)
|
||||
ResetPrismriverComboName(v)
|
||||
elseif comboName == "lyricalunasamerlin" then
|
||||
OnLyricaLunasaMerlin(keys,caster,v)
|
||||
ResetPrismriverComboName(v)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/merlin/ability_merlin_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnMerlin01Created(keys)
|
||||
keys.target:AddDamageOutgoingAll(keys.outgoing_percent, "thtd_merlin_01_damage_up")
|
||||
end
|
||||
|
||||
function OnMerlin01Destroy(keys)
|
||||
keys.target:AddDamageOutgoingAll("thtd_merlin_01_damage_up")
|
||||
end
|
||||
|
||||
function OnMerlin02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local abilty_01 = caster:FindAbilityByName("thtd_merlin_01")
|
||||
abilty_01:ApplyDataDrivenModifier(caster, target, "modifier_merlin_01_debuff", nil)
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
UpdatePrismriverComboName(caster,target)
|
||||
end
|
||||
|
||||
function OnLunasaLyricaMerlin(keys,caster,target)
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetOrigin(),2500)
|
||||
for k,v in pairs(targets) do
|
||||
local unitName = v:GetUnitName()
|
||||
if unitName == "lunasa" or unitName == "merlin" or unitName == "lyrica" then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_merlin_01_buff", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnLyricaLunasaMerlin(keys,caster,target)
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetOrigin(),2500)
|
||||
for k,v in pairs(targets) do
|
||||
local unitName = v:GetUnitName()
|
||||
if unitName == "lunasa" or unitName == "merlin" or unitName == "lyrica" then
|
||||
v:GiveMana(keys.mana_regen)
|
||||
end
|
||||
end
|
||||
end
|
||||
339
scripts/vscripts/abilities/abilitymiko.lua
Executable file
339
scripts/vscripts/abilities/abilitymiko.lua
Executable file
@@ -0,0 +1,339 @@
|
||||
function OnMiko01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local forward = caster:GetForwardVector()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/miko/ability_miko_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+Vector(0,0,64))
|
||||
ParticleManager:SetParticleControlForward(effectIndex , 0, caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_miko_01_pose", {})
|
||||
|
||||
local bonus = math.floor(keys.power_damage2 * caster:THTD_GetStarDamage())
|
||||
for i=1,3 do
|
||||
local rollRad = (i-2)*math.pi/4
|
||||
local currentPoint = Vector(math.cos(rollRad)*forward.x - math.sin(rollRad)*forward.y,
|
||||
forward.y*math.cos(rollRad) + forward.x*math.sin(rollRad),
|
||||
0) * keys.range + caster:GetOrigin()
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
currentPoint,
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
|
||||
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)
|
||||
|
||||
if THTD_IsValid(v) then
|
||||
v:AddDamageBlockAll(-bonus, "thtd_miko_01_bonus")
|
||||
local modifier = v:FindModifierByName("modifier_miko_01_debuff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_miko_01_debuff", {})
|
||||
else
|
||||
modifier:SetDuration(keys.duration_time, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function OnDestroyMiko01DeBuff(keys)
|
||||
keys.target:AddDamageBlockAll("thtd_miko_01_bonus")
|
||||
end
|
||||
|
||||
function OnMiko02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if THTD_IsTempleOfGodCanBuffedTower(target) then
|
||||
if caster.thtd_miko_02_religious_count == nil then
|
||||
caster.thtd_miko_02_religious_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_miko_02_religious_count >= 6000 and target:HasModifier("modifier_miko_02_buff") == false then
|
||||
local unitName = target:GetUnitName()
|
||||
if unitName == "soga" then
|
||||
target.thtd_miko_buff_soga01 = keys.soga01_cd
|
||||
target.thtd_miko_buff_soga03 = keys.soga03_cd
|
||||
elseif unitName == "futo" then
|
||||
target.thtd_miko_buff_futo03 = keys.futo03_up
|
||||
elseif unitName == "yoshika" then
|
||||
target.thtd_miko_buff_yoshika = keys.yoshika
|
||||
elseif unitName == "seiga" then
|
||||
target.thtd_miko_buff_seiga = keys.seiga
|
||||
end
|
||||
caster:RemoveModifierByName("modifier_miko_02_ready")
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_miko_02_buff", {})
|
||||
caster.thtd_miko_02_religious_count = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnMiko02SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetOrigin(),1500)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if THTD_IsTempleOfGodCanBuffedTower(v) then
|
||||
if caster.thtd_miko_02_religious_count == nil then
|
||||
caster.thtd_miko_02_religious_count = 0
|
||||
end
|
||||
if caster.thtd_miko_02_religious_count < 6000 then
|
||||
caster.thtd_miko_02_religious_count = caster.thtd_miko_02_religious_count + 1
|
||||
SendOverheadEventMessage(caster:GetPlayerOwner(), OVERHEAD_ALERT_BONUS_POISON_DAMAGE, caster, caster.thtd_miko_02_religious_count, caster:GetPlayerOwner() )
|
||||
elseif caster:HasModifier("modifier_miko_02_ready") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_miko_02_ready", {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local count = 0
|
||||
local friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
for k,v in pairs(friends) do
|
||||
if THTD_IsTempleOfGodCanBuffedTower(v) then
|
||||
local modifier = v:FindModifierByName("modifier_miko_02_buff")
|
||||
if modifier ~= nil then
|
||||
if modifier:GetCaster() == caster then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if count > 0 then
|
||||
if count ~= caster.thtd_miko_03_count then
|
||||
caster:THTD_AddBasePower(keys.bonus_power * count, "thtd_miko_03_bonus")
|
||||
caster:THTD_AddBaseAttack(keys.bonus_power * count, "thtd_miko_03_bonus")
|
||||
caster:THTD_AddCritChance(keys.bonus_chance * count, "thtd_miko_03_bonus")
|
||||
caster:THTD_AddCritDamage(keys.bonus_crit * count, "thtd_miko_03_bonus")
|
||||
caster.thtd_miko_03_count = count
|
||||
end
|
||||
else
|
||||
caster:THTD_AddBasePower("thtd_miko_03_bonus")
|
||||
caster:THTD_AddBaseAttack("thtd_miko_03_bonus")
|
||||
caster:THTD_AddCritChance("thtd_miko_03_bonus")
|
||||
caster:THTD_AddCritDamage("thtd_miko_03_bonus")
|
||||
if count ~= caster.thtd_miko_03_count then
|
||||
caster.thtd_miko_03_count = count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnMiko03SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnMiko03SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),1200)
|
||||
|
||||
if #targets > 0 then
|
||||
local index = RandomInt(1,#targets)
|
||||
if IsValidAlive(targets[index]) then
|
||||
local info =
|
||||
{
|
||||
Target = targets[index],
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_miko/ability_miko_03.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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
|
||||
local friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
for k,believer in pairs(friends) do
|
||||
if believer:HasModifier("modifier_miko_02_buff") then
|
||||
local index_extra = RandomInt(1,#targets)
|
||||
if IsValidAlive(targets[index_extra]) then
|
||||
local info_extra =
|
||||
{
|
||||
Target = targets[index_extra],
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_miko/ability_miko_03.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
|
||||
}
|
||||
local projectile_extra = ProjectileManager:CreateTrackingProjectile(info_extra)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile_extra,false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnCreatedMiko04(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local forward = caster:GetForwardVector()
|
||||
local ability = caster:FindAbilityByName("thtd_miko_01")
|
||||
|
||||
local power_damage2 = ability:GetSpecialValueFor("power_damage2")
|
||||
local range = ability:GetSpecialValueFor("range")
|
||||
local duration_time = math.floor(ability:GetSpecialValueFor("duration_time") * 100 + 0.5) / 100
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/miko/ability_miko_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin()+Vector(0,0,64))
|
||||
ParticleManager:SetParticleControlForward(effectIndex , 0, caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local bonus = math.floor(power_damage2 * caster:THTD_GetStarDamage())
|
||||
for i=1,3 do
|
||||
local rollRad = (i-2)*math.pi/4
|
||||
local currentPoint = Vector(math.cos(rollRad)*forward.x - math.sin(rollRad)*forward.y,
|
||||
forward.y*math.cos(rollRad) + forward.x*math.sin(rollRad),
|
||||
0) * range + caster:GetOrigin()
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
currentPoint,
|
||||
nil,
|
||||
200,
|
||||
ability:GetAbilityTargetTeam(),
|
||||
ability:GetAbilityTargetType(),
|
||||
ability:GetAbilityTargetFlags()
|
||||
)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability, 1)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
if THTD_IsValid(v) then
|
||||
v:AddDamageBlockAll(-bonus, "thtd_miko_01_bonus")
|
||||
local modifier = v:FindModifierByName("modifier_miko_01_debuff")
|
||||
if modifier == nil then
|
||||
ability:ApplyDataDrivenModifier(caster, v, "modifier_miko_01_debuff", {})
|
||||
else
|
||||
modifier:SetDuration(duration_time, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnMiko04SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local inners = THTD_FindUnitsInner(caster)
|
||||
local friends = THTD_FindFriendlyUnitsAll(caster)
|
||||
|
||||
local castUnits = {}
|
||||
for k,v in pairs(friends) do
|
||||
if v == caster then
|
||||
table.insert(castUnits, v)
|
||||
elseif v:HasModifier("modifier_miko_02_buff") then
|
||||
local modifier = v:FindModifierByName("modifier_miko_04_pose")
|
||||
if modifier == nil then
|
||||
table.insert(castUnits, v)
|
||||
elseif modifier:GetCaster() == caster then
|
||||
table.insert(castUnits, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
|
||||
for index,believer in pairs(castUnits) do
|
||||
local modifier = believer:FindModifierByName("modifier_miko_04_pose")
|
||||
if modifier == nil then
|
||||
-- tick+0.1
|
||||
keys.ability:ApplyDataDrivenModifier(caster, believer, "modifier_miko_04_pose", {Duration = 0.5})
|
||||
else
|
||||
modifier:SetDuration(0.5, false)
|
||||
end
|
||||
if believer ~= caster then
|
||||
modifier = believer:FindModifierByName("modifier_miko_04_pose_other")
|
||||
if modifier == nil then
|
||||
-- tick+0.1
|
||||
keys.ability:ApplyDataDrivenModifier(caster, believer, "modifier_miko_04_pose_other", {Duration = 0.5})
|
||||
else
|
||||
modifier:SetDuration(0.5, false)
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(inners) do
|
||||
if RandomInt(1,3) == 1 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_miko/ability_thtd_miko_04_starfall.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, RandomVector(255))
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, Vector(255,255,255))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_miko_04_star_fall"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
return nil
|
||||
end,
|
||||
0.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
463
scripts/vscripts/abilities/abilityminamitsu.lua
Executable file
463
scripts/vscripts/abilities/abilityminamitsu.lua
Executable file
@@ -0,0 +1,463 @@
|
||||
local BasePoint =
|
||||
{
|
||||
[0] = Vector(-3880,1880,128),
|
||||
[1] = Vector(3880,1880,128),
|
||||
[2] = Vector(3880,-1880,128),
|
||||
[3] = Vector(-3880,-1880,128),
|
||||
}
|
||||
|
||||
local StartPoint1 =
|
||||
{
|
||||
[0] = Vector(-4300,1588,128),
|
||||
[1] = Vector(4300,1588,128),
|
||||
[2] = Vector(4300,-1588,128),
|
||||
[3] = Vector(-4300,-1588,128),
|
||||
}
|
||||
|
||||
local EndPoint1 =
|
||||
{
|
||||
[0] = Vector(-1750,1588,128),
|
||||
[1] = Vector(1750,1588,128),
|
||||
[2] = Vector(1750,-1588,128),
|
||||
[3] = Vector(-1750,-1588,128),
|
||||
}
|
||||
|
||||
local StartPoint2 =
|
||||
{
|
||||
[0] = Vector(-4150,4100,128),
|
||||
[1] = Vector(4150,4100,128),
|
||||
[2] = Vector(4150,-4100,128),
|
||||
[3] = Vector(-4150,-4100,128),
|
||||
}
|
||||
|
||||
local EndPoint2 =
|
||||
{
|
||||
[0] = Vector(-4150,1600,128),
|
||||
[1] = Vector(4150,1600,128),
|
||||
[2] = Vector(4150,-1600,128),
|
||||
[3] = Vector(-4150,-1600,128),
|
||||
}
|
||||
|
||||
function OnMinamitsu01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local hero = caster:GetOwner()
|
||||
local id = caster:GetPlayerOwnerID()
|
||||
|
||||
local targetPoint, forward
|
||||
local pos = caster:GetAbsOrigin()
|
||||
if math.abs(pos.x - BasePoint[id].x) > math.abs(pos.y - BasePoint[id].y) then
|
||||
targetPoint = StartPoint1[id]
|
||||
forward = (EndPoint1[id] - StartPoint1[id]):Normalized()
|
||||
caster.thtd_minamitsu_01_first = true
|
||||
caster.water_start_point = StartPoint1[id]
|
||||
caster.water_end_point = EndPoint1[id]
|
||||
else
|
||||
targetPoint = StartPoint2[id]
|
||||
forward = (EndPoint2[id] - StartPoint2[id]):Normalized()
|
||||
caster.thtd_minamitsu_01_first = false
|
||||
caster.water_start_point = StartPoint2[id]
|
||||
caster.water_end_point = EndPoint2[id]
|
||||
end
|
||||
|
||||
if caster.thtd_minamitsu_01_rect == nil then
|
||||
caster.thtd_minamitsu_01_rect = {}
|
||||
end
|
||||
|
||||
if caster.thtd_minamitsu_01_rect["effectIndexList"] ~= nil then
|
||||
for k,v in pairs(caster.thtd_minamitsu_01_rect["effectIndexList"]) do
|
||||
ParticleManager:DestroyParticleSystem(v,true)
|
||||
end
|
||||
end
|
||||
|
||||
caster.thtd_minamitsu_01_rect =
|
||||
{
|
||||
["rectOrigin"] = targetPoint,
|
||||
["rectForward"] = forward,
|
||||
["effectIndexList"] = {}
|
||||
}
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_minamitsu/ability_minamitsu_01_ship.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward*600)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
|
||||
local time = 4
|
||||
caster:SetContextThink(DoUniqueString("thtd_minamitsu_01_move_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time > 0 then
|
||||
time = time - 0.2
|
||||
local waterIndex = ParticleManager:CreateParticle("particles/heroes/thtd_minamitsu/ability_minamitsu_01_ship_water.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(waterIndex, 3, targetPoint+forward*600*(4 - time))
|
||||
table.insert(caster.thtd_minamitsu_01_rect["effectIndexList"],waterIndex)
|
||||
return 0.2
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnMinamitsu01DebuffThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_minamitsu_01_rect ~= nil and caster.thtd_minamitsu_01_rect["rectOrigin"] ~= nil then
|
||||
if caster:THTD_IsHidden() then
|
||||
for k,v in pairs(caster.thtd_minamitsu_01_rect["effectIndexList"]) do
|
||||
ParticleManager:DestroyParticleSystem(v,true)
|
||||
end
|
||||
caster.thtd_minamitsu_01_rect =
|
||||
{
|
||||
["rectOrigin"] = nil,
|
||||
["rectForward"] = nil,
|
||||
["effectIndexList"] = {}
|
||||
}
|
||||
else
|
||||
local enemies = FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster.thtd_minamitsu_01_rect["rectOrigin"],
|
||||
caster.thtd_minamitsu_01_rect["rectOrigin"]+caster.thtd_minamitsu_01_rect["rectForward"]*2500,
|
||||
nil,
|
||||
300,
|
||||
DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
0)
|
||||
for k,v in pairs(enemies) do
|
||||
local modifier = v:FindModifierByName("modifier_minamitsu_01_slow_buff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_minamitsu_01_slow_buff", {duration=0.2})
|
||||
else
|
||||
modifier:SetDuration(0.2,false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedMinamitsu02Buff(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
-- ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_minamitsu_attack", Vector(0,0,0), true)
|
||||
|
||||
local powerBonus = 0
|
||||
local powerCd = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerBonus = pv[1]
|
||||
powerCd = pv[2]
|
||||
end
|
||||
if powerCd > 0 then
|
||||
caster:ReCooldown(keys.ability, powerCd)
|
||||
end
|
||||
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_03_body.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 0, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 1, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 3, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 4, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex2, keys.ability_duration)
|
||||
|
||||
local bonus = keys.power_bonus + powerBonus
|
||||
target:THTD_AddPowerPercentage(bonus, "thtd_minamitsu_03_bonus")
|
||||
target:THTD_AddAttackPercentage(bonus, "thtd_minamitsu_03_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyMinamitsu02Buff(keys)
|
||||
local target = keys.target
|
||||
target:THTD_AddPowerPercentage("thtd_minamitsu_03_bonus")
|
||||
target:THTD_AddAttackPercentage("thtd_minamitsu_03_bonus")
|
||||
end
|
||||
|
||||
function OnMinamitsu02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local target = keys.target
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.Radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = keys.ability:GetAbilityTargetFlags()
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/kunkka/divine_anchor/hero_kunkka_dafx_weapon/kunkka_spell_tidebringer_fxset.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0, caster:GetForwardVector())
|
||||
ParticleManager:SetParticleControl(effectIndex, 18, vecCaster)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnMinamitsu03SpellStart(keys)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_minamitsu_01_rect == nil or caster.thtd_minamitsu_01_rect["rectOrigin"] == nil then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_water_area_use"})
|
||||
return
|
||||
end
|
||||
|
||||
local targetPoint = keys.target_points[1]
|
||||
local isValidPoint = false
|
||||
local id = caster:GetPlayerOwnerID()
|
||||
if caster.thtd_minamitsu_01_first == true then
|
||||
if math.abs(targetPoint.x - StartPoint1[id].x) + math.abs(targetPoint.x - EndPoint1[id].x) <= math.abs(StartPoint1[id].x - EndPoint1[id].x) + 10 and math.abs(targetPoint.y - StartPoint1[id].y) <= 250 then
|
||||
isValidPoint = true
|
||||
end
|
||||
else
|
||||
if math.abs(targetPoint.y - StartPoint2[id].y) + math.abs(targetPoint.y - EndPoint2[id].y) <= math.abs(StartPoint2[id].y - EndPoint2[id].y) + 10 and math.abs(targetPoint.x - StartPoint2[id].x) <= 250 then
|
||||
isValidPoint = true
|
||||
end
|
||||
end
|
||||
if isValidPoint then
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local distance = GetDistanceBetweenTwoVec2D(vecCaster,targetPoint)
|
||||
local speed = distance * 0.03
|
||||
local rad = GetRadBetweenTwoVec2D(vecCaster,targetPoint)
|
||||
local vecHook = caster:GetOrigin()
|
||||
local forwardVector = caster:GetForwardVector()
|
||||
local timeCount = 0
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_02_body.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vecHook)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 3, forwardVector)
|
||||
|
||||
caster:SetContextThink(
|
||||
DoUniqueString("ability_thdots_minamitsu_02_stage_01"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then
|
||||
return 0.03
|
||||
end
|
||||
timeCount = timeCount + 0.03
|
||||
distance = distance - speed
|
||||
if distance >= 0 then
|
||||
vecHook = vecHook + Vector(math.cos(rad)*speed,math.sin(rad)*speed,0)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vecHook)
|
||||
else
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/minamitsu/ability_minamitsu_02.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, vecHook)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 3, vecHook)
|
||||
Timer.Wait 'OnMinamitsu02Vortex' (0.5,
|
||||
function()
|
||||
caster:EmitSound("Voice_Thdots_Minamitsu.AbilityMinamitsu022")
|
||||
OnMinamitsu02Vortex(keys,caster.thtd_minamitsu_01_rect["rectOrigin"],caster.thtd_minamitsu_01_rect["rectForward"])
|
||||
end
|
||||
)
|
||||
Timer.Wait 'OnMinamitsu02Vortex' (3.2,
|
||||
function()
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, caster.thtd_minamitsu_01_rect["rectOrigin"]+caster.thtd_minamitsu_01_rect["rectForward"]*2500)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 3, caster.thtd_minamitsu_01_rect["rectOrigin"]+caster.thtd_minamitsu_01_rect["rectForward"]*2500)
|
||||
end
|
||||
)
|
||||
return nil
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03
|
||||
)
|
||||
else
|
||||
keys.ability:EndCooldown()
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_water_area_use"})
|
||||
end
|
||||
end
|
||||
|
||||
function OnMinamitsu02Vortex(keys,origin,forward)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = keys.target_points[1]
|
||||
local distance = GetDistanceBetweenTwoVec2D(vecCaster,targetPoint)
|
||||
local rad = GetRadBetweenTwoVec2D(vecCaster,targetPoint)
|
||||
local timeCount = 0
|
||||
caster.ability_minamitsu_02_group = {}
|
||||
local range = keys.range
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_thdots_minamitsu_02_stage_02"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
timeCount = timeCount + 0.15
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.15
|
||||
for k,v in pairs(targets) do
|
||||
if v:IsNull() == false and v~=nil then
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = keys.ability:GetAbilityTargetFlags()
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
table.insert(caster.ability_minamitsu_02_group,v)
|
||||
|
||||
if v:HasModifier("modifier_minamitsu02_vortex_pause_target") == false then
|
||||
keys.ability:ApplyDataDrivenModifier( caster, v, "modifier_minamitsu02_vortex_pause_target", {} )
|
||||
end
|
||||
if v:HasModifier("modifier_minamitsu02_vortex_target") == false then
|
||||
local vecTarget = v:GetOrigin()
|
||||
local distance = GetDistanceBetweenTwoVec2D(vecTarget,targetPoint)
|
||||
local targetRad = GetRadBetweenTwoVec2D(targetPoint,vecTarget)
|
||||
if distance > 150 then
|
||||
v:SetAbsOrigin(Vector(vecTarget.x - math.cos(targetRad - math.pi/3) * 55 * 1.5, vecTarget.y - math.sin(targetRad - math.pi/3) * 55 * 1.5, vecTarget.z))
|
||||
else
|
||||
-- v:AddNoDraw()
|
||||
keys.ability:ApplyDataDrivenModifier( caster, v, "modifier_minamitsu02_vortex_target", {} )
|
||||
v:SetAbsOrigin(targetPoint)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if timeCount >= 1.5 then
|
||||
Timer.Wait 'OnMinamitsu02Vortex_starge_2' (1.0,
|
||||
function()
|
||||
caster:EmitSound("Ability.Torrent")
|
||||
OnMinamitsu02VortexEnd(keys,origin,forward)
|
||||
end
|
||||
)
|
||||
return nil
|
||||
end
|
||||
return 0.15
|
||||
end,
|
||||
0.03)
|
||||
end
|
||||
|
||||
function OnMinamitsu02VortexEnd(keys,origin,forward)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = origin + forward * 2500
|
||||
local speed = 2
|
||||
local g = 0.18
|
||||
local timeCount = 0
|
||||
|
||||
for k,v in pairs(caster.ability_minamitsu_02_group) do
|
||||
if v:IsNull() == false and v~=nil then
|
||||
if v.thtd_is_minamitsu_03_damaged ~= true then
|
||||
v.thtd_is_minamitsu_03_damaged = true
|
||||
local random = RandomVector(150)
|
||||
v:SetAbsOrigin(targetPoint+random)
|
||||
FindClearSpaceForUnit(v, v:GetOrigin(), false)
|
||||
if caster.thtd_minamitsu_01_first == true then
|
||||
v.next_move_forward = v.first_move_forward
|
||||
v.next_move_point = v.first_move_point
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
caster:SetContextThink(
|
||||
DoUniqueString("ability_thdots_minamitsu_02_stage_02"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
timeCount = timeCount + 0.03
|
||||
speed = speed - g
|
||||
if caster.ability_minamitsu_02_group ~= nil then
|
||||
for k,v in pairs(caster.ability_minamitsu_02_group) do
|
||||
if v~=nil and v:IsNull() == false then
|
||||
if v:HasModifier("modifier_minamitsu02_vortex_target") then
|
||||
-- v:RemoveNoDraw()
|
||||
v:RemoveModifierByName("modifier_minamitsu02_vortex_target")
|
||||
end
|
||||
if v:HasModifier("modifier_minamitsu02_vortex_pause_target") then
|
||||
if v:GetOrigin().z >= GetGroundHeight(v:GetOrigin(),nil) then
|
||||
v:SetAbsOrigin(v:GetOrigin() + Vector(0,0,speed))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if timeCount >= 1.0 then
|
||||
for k2,v2 in pairs(caster.ability_minamitsu_02_group) do
|
||||
if v2:HasModifier("modifier_minamitsu02_vortex_pause_target") then
|
||||
v2:RemoveModifierByName("modifier_minamitsu02_vortex_pause_target")
|
||||
end
|
||||
FindClearSpaceForUnit(v2, v2:GetOrigin(), false)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03
|
||||
)
|
||||
end
|
||||
|
||||
function OnMinamitsu04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") then
|
||||
caster:ReCooldown(keys.ability, caster.thtd_byakuren_buff_minamitsu)
|
||||
end
|
||||
|
||||
if caster.thtd_minamitsu_01_rect == nil or caster.thtd_minamitsu_01_rect["rectOrigin"] == nil then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="only_water_area_use"})
|
||||
return
|
||||
end
|
||||
|
||||
local powerDamage = 0
|
||||
local powerCount = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
powerCount = pv[2]
|
||||
end
|
||||
|
||||
local origin = caster.thtd_minamitsu_01_rect["rectOrigin"]
|
||||
local forward = caster.thtd_minamitsu_01_rect["rectForward"]
|
||||
|
||||
local count = 1 + powerCount
|
||||
if caster:IsPower999() then count = count + 7 end
|
||||
caster:SetContextThink(DoUniqueString("thtd_minamitsu_04"),
|
||||
function()
|
||||
if not THTD_IsValid(caster) then return nil end
|
||||
if count <= 0 then return nil end
|
||||
count = count - 1
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_minamitsu/ability_minamitsu_01_ship.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, origin)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward*1200)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)
|
||||
|
||||
local time = 2
|
||||
caster:SetContextThink(DoUniqueString("thtd_minamitsu_04_move_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time > 0 then
|
||||
time = time - 0.2
|
||||
local targets = THTD_FindUnitsInRadius(caster,origin+forward*1200*(2 - time),300)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
if caster:IsPower666() then
|
||||
damage = damage + count * 20 * caster:THTD_GetStarDamage()
|
||||
end
|
||||
damage = damage * (1 + THTD_GetStarLotusTowerCount(caster) * keys.damage_up/100)
|
||||
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 0.2
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
end
|
||||
70
scripts/vscripts/abilities/abilityminoriko.lua
Executable file
70
scripts/vscripts/abilities/abilityminoriko.lua
Executable file
@@ -0,0 +1,70 @@
|
||||
function OnMinoriko02StarChange(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target:GetUnitName() == "minoriko" or target:GetUnitName() == "sizuha" then
|
||||
return
|
||||
end
|
||||
|
||||
if target:THTD_IsTower() and target:GetOwner() == caster:GetOwner() and target:GetUnitName() ~= caster:GetUnitName() then
|
||||
local hero = caster:GetOwner()
|
||||
if hero.thtd_minoriko_02_change == nil then
|
||||
hero.thtd_minoriko_02_change = 0
|
||||
end
|
||||
|
||||
if GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then
|
||||
if SpawnSystem.CurWave < 11 then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="minoriko_cannot_be_change"})
|
||||
return
|
||||
end
|
||||
if SpawnSystem.CurWave < 21 and hero.thtd_minoriko_02_change >= 1 then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="minoriko_change_one_tip"})
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if hero.thtd_minoriko_02_change >= keys.max_count then
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="minoriko_max_change", duration=5, params={count=1}, color="#0ff"} )
|
||||
return
|
||||
end
|
||||
hero.thtd_minoriko_02_change = hero.thtd_minoriko_02_change + 1
|
||||
|
||||
local star = target:THTD_GetStar()
|
||||
target:THTD_SetStar(caster:THTD_GetStar())
|
||||
target:THTD_SetLevel(THTD_MAX_LEVEL)
|
||||
|
||||
caster.thtd_is_changed = true
|
||||
caster.thtd_star = star
|
||||
caster:THTD_OpenAbility()
|
||||
caster:THTD_DestroyLevelEffect()
|
||||
caster:THTD_CreateLevelEffect()
|
||||
|
||||
if (target:GetUnitName() == "kaguya" and target:THTD_GetStar() < 4) then
|
||||
if target.thtd_kaguya_03_treasure_table ~= nil and target.thtd_kaguya_03_treasure_table[1] ~= nil and target.thtd_kaguya_03_treasure_table[1]["effectIndex"] ~= nil then
|
||||
local friends = THTD_FindFriendlyUnitsAll(target)
|
||||
local enemies = THTD_FindUnitsAll(target)
|
||||
|
||||
for i=1,4 do
|
||||
local buff = "modifier_kaguya_03_"..i.."_buff"
|
||||
local debuff = "modifier_kaguya_03_"..i.."_debuff"
|
||||
for k,v in pairs(friends) do
|
||||
if v:FindModifierByNameAndCaster(buff,target)~=nil then
|
||||
v:RemoveModifierByName(buff)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(enemies) do
|
||||
if v:FindModifierByNameAndCaster(debuff,target)~=nil then
|
||||
v:RemoveModifierByName(debuff)
|
||||
end
|
||||
end
|
||||
|
||||
if target.thtd_kaguya_03_treasure_table[i]["effectIndex"] ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(target.thtd_kaguya_03_treasure_table[i]["effectIndex"],true)
|
||||
target.thtd_kaguya_03_treasure_table[i]["effectIndex"] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
107
scripts/vscripts/abilities/abilitymokou.lua
Executable file
107
scripts/vscripts/abilities/abilitymokou.lua
Executable file
@@ -0,0 +1,107 @@
|
||||
function OnMokou01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_mokou_01_crit_chance == nil then
|
||||
caster.thtd_mokou_01_crit_chance = keys.base_chance
|
||||
end
|
||||
|
||||
if caster.thtd_mokou_01_crit_chance < keys.max_chance then
|
||||
caster.thtd_mokou_01_crit_chance = math.min(keys.max_chance, caster.thtd_mokou_01_crit_chance + keys.bonus_chance)
|
||||
end
|
||||
|
||||
local modifier = caster:FindModifierByName("passive_mokou_01_crit")
|
||||
if modifier ~= nil then
|
||||
modifier:SetStackCount(caster.thtd_mokou_01_crit_chance)
|
||||
modifier:SetDuration(keys.duration_time,false)
|
||||
else
|
||||
local modifier = keys.ability:ApplyDataDrivenModifier(caster, caster, "passive_mokou_01_crit", {Duration = keys.duration_time})
|
||||
modifier:SetStackCount(caster.thtd_mokou_01_crit_chance)
|
||||
end
|
||||
|
||||
local base_crit = caster:GetAbilityValue("thtd_mokou_02", "base_crit")
|
||||
local max_crit = caster:GetAbilityValue("thtd_mokou_02", "max_crit")
|
||||
if caster.thtd_mokou_01_crit_damage == nil then
|
||||
caster.thtd_mokou_01_crit_damage = base_crit
|
||||
end
|
||||
|
||||
if RollPercentage(caster.thtd_mokou_01_crit_chance) then
|
||||
caster.thtd_mokou_01_crit_damage = math.min(max_crit, caster.thtd_mokou_01_crit_damage * base_crit)
|
||||
|
||||
local radius = keys.range
|
||||
if caster:HasModifier("modifier_mokou_03_buff") then
|
||||
radius = radius + caster:GetAbilityValue("thtd_mokou_03", "bonus_range")
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),radius)
|
||||
local damage = caster:THTD_GetAttack() * caster.thtd_mokou_01_crit_damage
|
||||
SendOverheadEventMessage(caster:GetPlayerOwner(), OVERHEAD_ALERT_DAMAGE, caster, caster.thtd_mokou_01_crit_damage, caster:GetPlayerOwner())
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable_aoe = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable_aoe)
|
||||
end
|
||||
if caster:HasModifier("modifier_mokou_03_buff") then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/mouko/ability_mokou_01_boom.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
caster:EmitSound("Hero_OgreMagi.Fireblast.Target")
|
||||
else
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/mouko/ability_mokou_02_boom.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin()+Vector(0,0,64))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1,1,1))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
caster:EmitSound("Hero_OgreMagi.Fireblast.Target")
|
||||
end
|
||||
else
|
||||
caster.thtd_mokou_01_crit_damage = base_crit
|
||||
end
|
||||
|
||||
local modifier = caster:FindModifierByName("modifier_mokou_crit_buff")
|
||||
if modifier ~= nil then
|
||||
modifier:SetStackCount(caster.thtd_mokou_01_crit_damage)
|
||||
else
|
||||
local modifier = keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_mokou_crit_buff", nil)
|
||||
modifier:SetStackCount(caster.thtd_mokou_01_crit_damage)
|
||||
end
|
||||
end
|
||||
|
||||
function OnMokou01Remove(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
caster.thtd_mokou_01_crit_chance = keys.base_chance
|
||||
caster.thtd_mokou_01_crit_damage = caster:GetAbilityValue("thtd_mokou_02", "base_crit")
|
||||
|
||||
local modifier = caster:FindModifierByName("modifier_mokou_crit_buff")
|
||||
if modifier ~= nil then
|
||||
modifier:SetStackCount(caster.thtd_mokou_01_crit_damage)
|
||||
else
|
||||
local modifier = keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_mokou_crit_buff", nil)
|
||||
modifier:SetStackCount(caster.thtd_mokou_01_crit_damage)
|
||||
end
|
||||
end
|
||||
|
||||
function OnMokou03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/mouko/ability_mokou_04_wing.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time)
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster,caster,"modifier_mokou_03_buff", {duration = keys.duration_time})
|
||||
end
|
||||
|
||||
function OnCreatedMokou03Buff(keys)
|
||||
keys.target:THTD_AddBaseAttack(keys.bonus_attack, "thtd_mokou_03_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyMokou03Buff(keys)
|
||||
keys.target:THTD_AddBaseAttack("thtd_mokou_03_bonus")
|
||||
end
|
||||
140
scripts/vscripts/abilities/abilitymomiji.lua
Executable file
140
scripts/vscripts/abilities/abilitymomiji.lua
Executable file
@@ -0,0 +1,140 @@
|
||||
function OnMomiji01Spawn(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster.ability_momiji01_Spawn_unit == nil then
|
||||
caster.ability_momiji01_Spawn_unit = {}
|
||||
end
|
||||
|
||||
count = keys.max_count
|
||||
|
||||
for i=1,count do
|
||||
local unit = CreateUnitByName(
|
||||
"momiji_wolf"
|
||||
,caster:GetOrigin() + ( caster:GetForwardVector() + Vector(math.cos((i-1.5)*math.pi/3),math.sin((i-1.5)*math.pi/3),0) ) * 100
|
||||
,false
|
||||
,caster:GetOwner()
|
||||
,caster:GetOwner()
|
||||
,caster:GetTeam()
|
||||
)
|
||||
|
||||
if unit == nil then return end
|
||||
|
||||
unit:SetControllableByPlayer(caster:GetPlayerOwnerID(), false)
|
||||
unit:SetBaseDamageMax(caster:THTD_GetStarDamage() * keys.wolf_attack)
|
||||
unit:SetBaseDamageMin(caster:THTD_GetStarDamage() * keys.wolf_attack)
|
||||
unit.thtd_spawn_unit_owner = caster
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_momiji_01_buff", nil)
|
||||
|
||||
local hero = caster:GetOwner()
|
||||
if GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"] > 0 then
|
||||
unit.bb_buff_3016 = GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"]
|
||||
unit:AddNewModifier(unit, nil, "modifier_bb_buff_3016_effect", nil):SetStackCount(GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"])
|
||||
end
|
||||
|
||||
local oldSwpanUnit = caster.ability_momiji01_Spawn_unit[i]
|
||||
if oldSwpanUnit ~=nil and oldSwpanUnit:IsNull() == false then
|
||||
oldSwpanUnit:ForceKill(false)
|
||||
end
|
||||
caster.ability_momiji01_Spawn_unit[i] = unit
|
||||
|
||||
local duration = keys.ability:GetCooldownTime()
|
||||
unit:SetContextThink(DoUniqueString("thtd_momiji_01"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if GetDistanceBetweenTwoVec2D(caster:GetOrigin(), unit:GetOrigin()) > keys.range then
|
||||
local forward = (unit:GetAbsOrigin() - caster:GetAbsOrigin()):Normalized()
|
||||
unit:MoveToPosition(caster:GetOrigin() + forward * keys.range)
|
||||
end
|
||||
if duration > 0 then
|
||||
duration = duration - 0.5
|
||||
else
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
if not THTD_IsValid(caster) then
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
return nil
|
||||
end
|
||||
return 0.5
|
||||
end,
|
||||
0.5)
|
||||
end
|
||||
end
|
||||
|
||||
function OnMomiji02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target:GetPlayerOwnerID() ~= caster:GetPlayerOwnerID() then return end
|
||||
|
||||
if caster.ability_momiji_02_target == target then return end
|
||||
if caster == target then return end
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_momiji_02", nil)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_momiji/ability_momiji_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
caster.ability_momiji_02_target = target
|
||||
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("modifier_momiji_02"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster.ability_momiji_02_target ~= target then
|
||||
if target~=nil and target:IsNull()==false and target:HasModifier("modifier_momiji_02") then
|
||||
target:RemoveModifierByName("modifier_momiji_02")
|
||||
end
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0.1)
|
||||
|
||||
caster:SetContextThink("modifier_momiji_02_remove",
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster:THTD_IsHidden() or keys.ability:GetLevel()<1 then
|
||||
caster.ability_momiji_02_target = nil
|
||||
return nil
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0.1)
|
||||
end
|
||||
|
||||
function OnCreatedMomiji02Buff(keys)
|
||||
local target = keys.target
|
||||
local bonus = 0
|
||||
if target:GetUnitName() == "aya" then
|
||||
bonus = keys.aya_damage_up
|
||||
else
|
||||
bonus = keys.damage_up
|
||||
end
|
||||
target:AddDamageOutgoingPhysical(bonus, "thtd_momiji_02_damage_up")
|
||||
end
|
||||
|
||||
function OnUpgradeMomiji02Buff(keys)
|
||||
local caster = keys.caster
|
||||
local targets = {}
|
||||
if caster.ability_momiji_02_target ~= nil then
|
||||
table.insert(targets, caster.ability_momiji_02_target)
|
||||
end
|
||||
|
||||
for _,target in pairs(targets) do
|
||||
local bonus = 0
|
||||
if target:GetUnitName() == "aya" then
|
||||
bonus = keys.aya_damage_up
|
||||
else
|
||||
bonus = keys.damage_up
|
||||
end
|
||||
target:AddDamageOutgoingPhysical(bonus, "thtd_momiji_02_damage_up")
|
||||
end
|
||||
|
||||
targets = {}
|
||||
end
|
||||
|
||||
function OnDestroyMomiji02Buff(keys)
|
||||
keys.target:AddDamageOutgoingPhysical("thtd_momiji_02_damage_up")
|
||||
end
|
||||
40
scripts/vscripts/abilities/abilitymugiyousei.lua
Executable file
40
scripts/vscripts/abilities/abilitymugiyousei.lua
Executable file
@@ -0,0 +1,40 @@
|
||||
function OnMugiyousei01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local powerDamage = 0
|
||||
local powerDuration = 0
|
||||
local pv = caster:GetAbilityPowerValue(keys.ability:GetAbilityName())
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
powerDuration = pv[2]
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + powerDamage)
|
||||
local time = keys.damage_duration + powerDuration
|
||||
target:AddPoison(1, caster)
|
||||
target:SetContextThink(DoUniqueString("thtd_mugiyousei01_attack"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 or THTD_IsValid(target) == false then
|
||||
if target ~= nil and target:IsNull() == false then
|
||||
target:AddPoison(-1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
time = time - 1.0
|
||||
return 1.0
|
||||
end,
|
||||
0)
|
||||
end
|
||||
34
scripts/vscripts/abilities/abilitymystia.lua
Executable file
34
scripts/vscripts/abilities/abilitymystia.lua
Executable file
@@ -0,0 +1,34 @@
|
||||
function OnCreatedMystia01Debuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddPhysicalArmor(-keys.penetration)
|
||||
end
|
||||
|
||||
function OnDestroyMystia01Debuff(keys)
|
||||
local target = keys.target
|
||||
|
||||
target:AddPhysicalArmor(keys.penetration)
|
||||
end
|
||||
|
||||
function OnThinkMystia02Buff(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetAbsOrigin(),keys.radius)
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_mystia_02_buff")
|
||||
-- 持续时间比think大一点
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_mystia_02_buff", {Duration = 0.3})
|
||||
else
|
||||
modifier:SetDuration(0.3, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedMystia02Buff(keys)
|
||||
keys.target:THTD_AddAttackPercentage(keys.critdamage, "thtd_mystia_02_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyMystia02Buff(keys)
|
||||
keys.target:THTD_AddAttackPercentage("thtd_mystia_02_bonus")
|
||||
end
|
||||
33
scripts/vscripts/abilities/abilitynazrin.lua
Executable file
33
scripts/vscripts/abilities/abilitynazrin.lua
Executable file
@@ -0,0 +1,33 @@
|
||||
function OnNazrin01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if SpawnSystem.IsUnLimited then
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") then
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),400)
|
||||
local damage = caster:GetGold() * keys.nazrin/100
|
||||
damage = damage * (1 + caster:THTD_GetPower() * keys.damage_up/1000)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then return end
|
||||
|
||||
if RollPercentage(keys.BonusChance) then
|
||||
local gold = math.floor(keys.BonusGold + caster:THTD_GetPower() * keys.PowerPercent/100)
|
||||
THTD_ModifyGoldEx(caster:GetPlayerOwnerID(), gold , true, DOTA_ModifyGold_CreepKill)
|
||||
SendOverheadEventMessage(caster:GetPlayerOwner(), OVERHEAD_ALERT_GOLD, target, gold, caster:GetPlayerOwner() )
|
||||
caster:EmitSound("Sound_THTD.thtd_nazrin_01")
|
||||
end
|
||||
end
|
||||
101
scripts/vscripts/abilities/abilitynue.lua
Executable file
101
scripts/vscripts/abilities/abilitynue.lua
Executable file
@@ -0,0 +1,101 @@
|
||||
function GetNueExtraDamage(caster)
|
||||
local ability = caster:FindAbilityByName("thtd_nue_01")
|
||||
local basedamage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
local extradamage = caster:GetModifierStackCount("modifier_nue_01_extradamage", caster) or 0
|
||||
return math.max(1, extradamage) * basedamage
|
||||
end
|
||||
|
||||
function OnNue01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local cooldown = keys.ability:GetCooldownTime()
|
||||
caster.thtd_nue_01_duration = cooldown
|
||||
keys.ability:StartCooldown(cooldown)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_nue_01_extradamage", {Duration = cooldown})
|
||||
caster.modifier_extradamage_count = math.min(caster:GetModifierStackCount("modifier_nue_01_extradamage", caster) + 1, keys.max_count)
|
||||
caster:SetModifierStackCount("modifier_nue_01_extradamage", caster, caster.modifier_extradamage_count)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/nue/ability_nue_01_ball.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_ball", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, caster, 5, "attach_ball", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,cooldown)
|
||||
end
|
||||
|
||||
function OnNue01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if target.thtd_damage_lock == true then return end
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_templar_assassin/templar_assassin_meld_hit.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 3, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
|
||||
local DamageTable = {
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
ability = keys.ability,
|
||||
damage = GetNueExtraDamage(caster) * keys.attack_bonus,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = keys.ability:GetAbilityTargetFlags()
|
||||
}
|
||||
if target:HasModifier("modifier_minamitsu_01_slow_buff") then
|
||||
DamageTable.damage = DamageTable.damage * (1 + keys.damage_up/100)
|
||||
end
|
||||
UnitDamageTarget(DamageTable)
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") and THTD_IsValid(target) and target.thtd_damage_lock ~= true then
|
||||
if target:GetHealthPercent() < caster.thtd_byakuren_buff_nue and target:HasModifier("modifier_nue_killed") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_nue_killed", {Duration = 30.0})
|
||||
caster:AbilityKill(target, keys.ability)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- buff时间到减1/3层
|
||||
function OnNue01Destroy(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
caster.modifier_extradamage_count = math.floor(caster.modifier_extradamage_count * 2/3)
|
||||
if caster.modifier_extradamage_count > 0 then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_nue_01_extradamage", {Duration = caster.thtd_nue_01_duration})
|
||||
caster:SetModifierStackCount("modifier_nue_01_extradamage", caster, caster.modifier_extradamage_count)
|
||||
end
|
||||
end
|
||||
|
||||
function OnNue02SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if target.thtd_damage_lock == true then return end
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + GetNueExtraDamage(caster) * caster:GetAbilityValue("thtd_nue_01", "spell_bonus"),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = keys.ability:GetAbilityTargetFlags()
|
||||
}
|
||||
if target:HasModifier("modifier_minamitsu_01_slow_buff") then
|
||||
damage_table.damage = damage_table.damage * (1 + caster:GetAbilityValue("thtd_nue_01", "damage_up", true))
|
||||
end
|
||||
UnitDamageTarget(damage_table)
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") and THTD_IsValid(target) and target.thtd_damage_lock ~= true then
|
||||
if target:GetHealthPercent() < caster.thtd_byakuren_buff_nue and target:HasModifier("modifier_nue_killed") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_nue_killed", {Duration = 30.0})
|
||||
caster:AbilityKill(target, keys.ability)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnNue03Kill(keys)
|
||||
local caster = keys.attacker
|
||||
local target = keys.unit
|
||||
local ability = nil
|
||||
local level = keys.ability:GetLevel()
|
||||
|
||||
if level >= 1 then
|
||||
ability = caster:FindAbilityByName("thtd_nue_01")
|
||||
if ability~=nil then
|
||||
ability:EndCooldown()
|
||||
end
|
||||
ability = caster:FindAbilityByName("thtd_nue_02")
|
||||
if ability~=nil then
|
||||
ability:EndCooldown()
|
||||
end
|
||||
end
|
||||
end
|
||||
356
scripts/vscripts/abilities/abilitypatchouli.lua
Executable file
356
scripts/vscripts/abilities/abilitypatchouli.lua
Executable file
@@ -0,0 +1,356 @@
|
||||
local PATCHOULI_01_AGNI_SHINE = 0
|
||||
local PATCHOULI_01_BURY_IN_LAKE = 1
|
||||
local PATCHOULI_01_MERCURY_POISON = 2
|
||||
|
||||
function GetPatchouliDamageCrit(caster)
|
||||
local crit = 1
|
||||
if caster:HasModifier("modifier_patchouli_01_buff_fire") then
|
||||
crit = 2
|
||||
end
|
||||
if caster:IsPower999() then
|
||||
crit = crit * 5
|
||||
end
|
||||
return crit
|
||||
end
|
||||
|
||||
function OnPatchouli01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_power666_bonus ~= true then
|
||||
if caster:IsPower666() then
|
||||
caster.thtd_power666_bonus = true
|
||||
caster:THTD_AddBasePower(3000)
|
||||
end
|
||||
else
|
||||
if not caster:IsPower666() then
|
||||
caster:THTD_AddBasePower(-3000)
|
||||
caster.thtd_power666_bonus = nil
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_patchouli_02_type == nil then
|
||||
caster.thtd_patchouli_02_type = PATCHOULI_01_AGNI_SHINE
|
||||
end
|
||||
if caster.thtd_patchouli_02_cast_type == nil then
|
||||
caster.thtd_patchouli_02_cast_type = PATCHOULI_01_AGNI_SHINE
|
||||
end
|
||||
|
||||
if caster.thtd_patchouli_02_type == PATCHOULI_01_AGNI_SHINE then
|
||||
Patchouli01AgniShine(keys)
|
||||
caster.thtd_patchouli_02_cast_type = PATCHOULI_01_AGNI_SHINE
|
||||
elseif caster.thtd_patchouli_02_type == PATCHOULI_01_BURY_IN_LAKE then
|
||||
Patchouli01BuryInLake(keys)
|
||||
caster.thtd_patchouli_02_cast_type = PATCHOULI_01_BURY_IN_LAKE
|
||||
elseif caster.thtd_patchouli_02_type == PATCHOULI_01_MERCURY_POISON then
|
||||
Patchouli01MercuryPoison(keys)
|
||||
caster.thtd_patchouli_02_cast_type = PATCHOULI_01_MERCURY_POISON
|
||||
end
|
||||
end
|
||||
|
||||
function Patchouli01AgniShine(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local modifier = caster:FindModifierByName("modifier_patchouli_01_buff_fire")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_patchouli_01_buff_fire", {Duration=10.0})
|
||||
else
|
||||
modifier:SetDuration(10, false)
|
||||
end
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_patchouli_01")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range1)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1) * (1 + powerDamage/100) * GetPatchouliDamageCrit(caster)
|
||||
for k,v in pairs(targets) do
|
||||
local crit = 1
|
||||
if v:HasModifier("modifier_patchouli_01_debuff_gold") then
|
||||
crit = 2
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
caster:EmitSound("Hero_Invoker.Cataclysm.Ignite")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_agni_shine.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)
|
||||
end
|
||||
|
||||
function Patchouli01BuryInLake(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local modifier = caster:FindModifierByName("modifier_patchouli_01_buff_water")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_patchouli_01_buff_water", {Duration=10.0})
|
||||
else
|
||||
modifier:SetDuration(10, false)
|
||||
end
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_patchouli_01")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local isFirst = true
|
||||
local time = keys.duration_time2
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_patchouli_01_02")
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_patchouli01_buryinlake"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range2)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2) * (1 + powerDamage/100) * 0.25 * GetPatchouliDamageCrit(caster)
|
||||
for k,v in pairs(targets) do
|
||||
local crit = 1
|
||||
if v:HasModifier("modifier_patchouli_01_debuff_gold") then
|
||||
crit = 2
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
if isFirst and v ~= nil and v.thtd_damage_lock ~= true and v:IsNull() == false and v:IsAlive() and v:GetHealthPercent() < 30 then
|
||||
isFirst = false
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_bury_in_lake_bury.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
EmitSoundOnLocationForAllies(v:GetOrigin(),"Hero_Kunkka.Tidebringer.Attack",caster)
|
||||
caster:AbilityKill(v, keys.ability)
|
||||
end
|
||||
end
|
||||
time = time - 0.25
|
||||
return 0.25
|
||||
end,
|
||||
0)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_bury_in_lake.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time2)
|
||||
end
|
||||
|
||||
function Patchouli01MercuryPoison(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local time = keys.duration_time3
|
||||
|
||||
EmitSoundOnLocationForAllies(targetPoint,"Sound_THTD.thtd_patchouli_01_03",caster)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_patchouli01_mercuryposion"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range3)
|
||||
for k,v in pairs(targets) do
|
||||
if v:HasModifier("modifier_patchouli_01_mercury_poison_debuff") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_patchouli_01_mercury_poison_debuff", nil)
|
||||
end
|
||||
if v:HasModifier("modifier_patchouli_01_debuff_gold") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_patchouli_01_debuff_gold", {Duration = 10.0})
|
||||
end
|
||||
end
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli/ability_patchouli_01_mercury_poison.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time3)
|
||||
end
|
||||
|
||||
function OnPatchouli01MercuryPoisonThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_patchouli_01")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local crit = 1
|
||||
if target:HasModifier("modifier_patchouli_01_debuff_gold") then
|
||||
crit = 2
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 3) * (1 + powerDamage/100) * crit * 0.2 * GetPatchouliDamageCrit(caster),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnPatchouli01MercuryPoisonCreated(keys)
|
||||
local caster = keys.caster
|
||||
local unit = keys.target
|
||||
unit:AddPoison(1, caster)
|
||||
end
|
||||
|
||||
function OnPatchouli01MercuryPoisonDestroy(keys)
|
||||
local caster = keys.caster
|
||||
local unit = keys.target
|
||||
unit:AddPoison(-1)
|
||||
end
|
||||
|
||||
local BuffWaterEffect = {
|
||||
"particles/econ/items/treant_protector/ti7_shoulder/treant_ti7_livingarmor.vpcf",
|
||||
"particles/econ/items/treant_protector/ti7_shoulder/treant_ti7_crimson_livingarmor.vpcf",
|
||||
"particles/econ/items/treant_protector/ti7_shoulder/treant_ti7_golden_livingarmor.vpcf",
|
||||
}
|
||||
|
||||
function OnPatchouli01BuffWaterCreated(keys)
|
||||
local caster = keys.caster
|
||||
local effectIndex = ParticleManager:CreateParticle(BuffWaterEffect[RandomInt(1, #BuffWaterEffect)], PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, caster:GetAbsOrigin())
|
||||
caster.buff_water_effect = effectIndex
|
||||
caster:THTD_AddManaRegenPercentage(100, "thtd_patchouli_01_manaregn_bonus")
|
||||
end
|
||||
|
||||
function OnPatchouli01BuffWaterDestroy(keys)
|
||||
local caster = keys.caster
|
||||
if caster.buff_water_effect ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.buff_water_effect, true)
|
||||
caster.buff_water_effect = nil
|
||||
end
|
||||
caster:THTD_AddManaRegenPercentage("thtd_patchouli_01_manaregn_bonus")
|
||||
end
|
||||
|
||||
function OnPatchouli02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
caster:EmitSound("Hero_Invoker.Invoke")
|
||||
|
||||
if caster.thtd_patchouli_02_type == nil then
|
||||
caster.thtd_patchouli_02_type = PATCHOULI_01_AGNI_SHINE
|
||||
end
|
||||
|
||||
if caster.thtd_patchouli_02_type == PATCHOULI_01_AGNI_SHINE then
|
||||
caster.thtd_patchouli_02_type = PATCHOULI_01_BURY_IN_LAKE
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_patchouli_bury_in_lake", duration=1, params={count=1}, color="#0ff"} )
|
||||
elseif caster.thtd_patchouli_02_type == PATCHOULI_01_BURY_IN_LAKE then
|
||||
caster.thtd_patchouli_02_type = PATCHOULI_01_MERCURY_POISON
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_patchouli_mercury_poison", duration=1, params={count=1}, color="#0ff"} )
|
||||
elseif caster.thtd_patchouli_02_type == PATCHOULI_01_MERCURY_POISON then
|
||||
caster.thtd_patchouli_02_type = PATCHOULI_01_AGNI_SHINE
|
||||
CustomGameEventManager:Send_ServerToPlayer( caster:GetPlayerOwner() , "show_message", {msg="change_to_patchouli_agni_shine", duration=1, params={count=1}, color="#0ff"} )
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedPatchouli03Buff(keys)
|
||||
keys.target:AddDamageOutgoingMagical(keys.magic_outgoing, "thtd_patchouli_03_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyPatchouli03Buff(keys)
|
||||
keys.target:AddDamageOutgoingMagical("thtd_patchouli_03_damage_up")
|
||||
end
|
||||
|
||||
function OnPatchouli04SpellStart(keys)
|
||||
if keys.duration_time == 0 then return end
|
||||
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
|
||||
if caster.thtd_power666_bonus ~= true then
|
||||
if caster:IsPower666() then
|
||||
caster.thtd_power666_bonus = true
|
||||
caster:THTD_AddBasePower(2000)
|
||||
end
|
||||
else
|
||||
if not caster:IsPower666() then
|
||||
caster:THTD_AddBasePower(-2000)
|
||||
caster.thtd_power666_bonus = nil
|
||||
end
|
||||
end
|
||||
|
||||
local count = 4
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli_04/ability_patchouli_04.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster + Vector(0,0,256))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, vecCaster + Vector(0,0,256))
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vecCaster + Vector(0,0,256))
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_patchouli04_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
count = count * 2
|
||||
local radius = math.min(128,count)
|
||||
ParticleManager:SetParticleControl(effectIndex, 14, Vector(radius,0,0))
|
||||
if count > 100 then
|
||||
OnPatchouli04SpellThink(keys)
|
||||
ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,3.0)
|
||||
return nil
|
||||
end
|
||||
return 0.5
|
||||
end,
|
||||
0.5)
|
||||
end
|
||||
|
||||
function OnPatchouli04SpellThink(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local time = keys.duration_time
|
||||
local range = keys.range
|
||||
|
||||
THTD_SetSpellLock(caster, "thtd_patchouli_04_in_stun", time)
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_patchouli_04")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_patchouli04_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),range)
|
||||
local damage = (caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()) * 0.2 * GetPatchouliDamageCrit(caster)
|
||||
for k,v in pairs(targets) do
|
||||
local crit = 1
|
||||
if v:HasModifier("modifier_patchouli_01_debuff_gold") then
|
||||
crit = 2
|
||||
end
|
||||
UnitStunTarget(caster,v,0.2)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
157
scripts/vscripts/abilities/abilityran.lua
Executable file
157
scripts/vscripts/abilities/abilityran.lua
Executable file
@@ -0,0 +1,157 @@
|
||||
local ran_03_black_list =
|
||||
{
|
||||
"lily",
|
||||
"daiyousei",
|
||||
}
|
||||
|
||||
function IsInRan03BlackList(unit)
|
||||
for k,v in pairs(ran_03_black_list) do
|
||||
if unit:GetUnitName() == v then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local ran_03_ability_black_list =
|
||||
{
|
||||
"thtd_ran_01",
|
||||
}
|
||||
|
||||
function IsInRan03AbilityBlackList(ability)
|
||||
for k,v in pairs(ran_03_ability_black_list) do
|
||||
if ability:GetAbilityName() == v then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function Ran01_OnSpellStart(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/ran/ability_ran_03_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 9, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
|
||||
local target_point = target:GetOrigin()
|
||||
|
||||
local damage_table={
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
ability = keys.ability,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
|
||||
local target_unit = target
|
||||
local jump_count = 1
|
||||
local jumpAmount = keys.JumpCount
|
||||
|
||||
if target_unit ~= nil and target_unit:IsNull() == false and target_unit:IsAlive() and jumpAmount > 1 then
|
||||
caster:SetContextThink("ran01_lazer_jumping",
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local enemies = THTD_FindUnitsInRadius(caster,target_point,keys.JumpRadius)
|
||||
|
||||
local next_target=nil
|
||||
for _,v in pairs(enemies) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
if v~=target_unit then
|
||||
next_target=v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if next_target then
|
||||
-- target_unit:EmitSound("Hero_Tinker.Laser")
|
||||
effectIndex = ParticleManager:CreateParticle("particles/heroes/ran/ability_ran_03_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target_unit, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, next_target, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 9, target_unit, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
|
||||
target_unit = next_target
|
||||
target_point = next_target:GetOrigin()
|
||||
|
||||
local DamageTable={
|
||||
victim = target_unit,
|
||||
attacker = caster,
|
||||
ability = keys.ability,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
-- next_target:EmitSoundParams("Hero_Tinker.LaserImpact",1.0,0.4,2.0)
|
||||
end
|
||||
|
||||
jump_count=jump_count+1
|
||||
if jump_count >= jumpAmount or next_target == nil or next_target:IsNull() or next_target:IsAlive() == false then
|
||||
return nil
|
||||
end
|
||||
return keys.JumpInterval
|
||||
end,
|
||||
keys.JumpInterval)
|
||||
end
|
||||
end
|
||||
|
||||
function OnRan03SpellStart(keys)
|
||||
local buffCaster = EntIndexToHScript(keys.caster_entindex) --本buff来源者
|
||||
if keys.ability:GetLevel() < 1 then --本buff来源技能
|
||||
return
|
||||
end
|
||||
|
||||
local caster = keys.unit --本次触发的技能施放者
|
||||
local ability = keys.event_ability --本次触发的施放的技能
|
||||
local manaCost = caster:GetRealManaCost(ability)
|
||||
if manaCost <= 0 then
|
||||
return
|
||||
end
|
||||
if IsInRan03BlackList(keys.unit) or IsInRan03AbilityBlackList(keys.event_ability) then
|
||||
return
|
||||
end
|
||||
|
||||
if keys.mana_regen > 0 then
|
||||
caster:GiveMana(manaCost * keys.mana_regen/100)
|
||||
end
|
||||
|
||||
local ability01 = buffCaster:FindAbilityByName("thtd_ran_01")
|
||||
ability01:EndCooldown()
|
||||
buffCaster:GiveMana(buffCaster:GetRealManaCost(ability01))
|
||||
|
||||
local enemies = THTD_FindUnitsInRadius(buffCaster,buffCaster:GetOrigin(),buffCaster:GetAbilityValue("thtd_ran_01", "range"))
|
||||
if #enemies > 0 then
|
||||
local unit = nil
|
||||
for _,v in pairs(enemies) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
unit = v
|
||||
break
|
||||
end
|
||||
end
|
||||
if unit ~= nil then
|
||||
buffCaster:CastAbilityOnTarget(unit,ability01,buffCaster:GetPlayerOwnerID())
|
||||
end
|
||||
end
|
||||
|
||||
-- local effectIndex = ParticleManager:CreateParticle("particles/heroes/ran/ability_ran_04_buff.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
-- ParticleManager:SetParticleControlEnt(effectIndex , 0, keys.unit, 5, "follow_origin", Vector(0,0,0), true)
|
||||
-- ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,2.0)
|
||||
-- 太吵,改为只有蓝显示
|
||||
if buffCaster.thtd_ran_03_effect ~= true then
|
||||
buffCaster.thtd_ran_03_effect = true
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/ran/ability_ran_04_buff.vpcf", PATTACH_CUSTOMORIGIN, buffCaster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, buffCaster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,2.0)
|
||||
buffCaster:SetContextThink(DoUniqueString("thtd_ran_03"),
|
||||
function()
|
||||
buffCaster.thtd_ran_03_effect = nil
|
||||
return nil
|
||||
end,
|
||||
2.0)
|
||||
end
|
||||
end
|
||||
359
scripts/vscripts/abilities/abilityreimu.lua
Executable file
359
scripts/vscripts/abilities/abilityreimu.lua
Executable file
@@ -0,0 +1,359 @@
|
||||
function OnReimu01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
if caster.thtd_reimu_01_attack_count == nil then
|
||||
caster.thtd_reimu_01_attack_count = 0
|
||||
end
|
||||
|
||||
caster.thtd_reimu_01_attack_count = caster.thtd_reimu_01_attack_count + 1
|
||||
|
||||
if caster.thtd_reimu_01_attack_count >= keys.max_count then
|
||||
caster.thtd_reimu_01_attack_count = 0
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_reimu_01")
|
||||
|
||||
local count = 1
|
||||
caster:SetContextThink(DoUniqueString("ability_reimu_01_projectile"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count <= 3 then
|
||||
Reimu01Projectile(keys,count)
|
||||
count = count + 1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
return 0.2
|
||||
end,
|
||||
0.2)
|
||||
end
|
||||
end
|
||||
|
||||
function OnReimu01ProjectileHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage * Reimu02GetChance(caster),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function Reimu01Projectile(keys,count)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local rad = GetRadBetweenTwoVec2D(caster:GetOrigin(),target:GetOrigin())
|
||||
|
||||
local forward = Vector(math.cos(rad),math.sin(rad),caster:GetForwardVector().z)
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_reimu/ability_reimu_01_projectile.vpcf",
|
||||
vSpawnOrigin = caster:GetOrigin() + Vector(0,0,128),
|
||||
fDistance = 1000,
|
||||
fStartRadius = 150,
|
||||
fEndRadius = 150,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = forward * 1500,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
|
||||
for i=1,count do
|
||||
local iVec = Vector( math.cos(rad + math.pi/18*(i+0.5)) * 2000 , math.sin(rad + math.pi/18*(i+0.5)) * 2000 , caster:GetForwardVector().z )
|
||||
info.vVelocity = iVec
|
||||
projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
iVec = Vector( math.cos(rad - math.pi/18*(i+0.5)) * 2000 , math.sin(rad - math.pi/18*(i+0.5)) * 2000 , caster:GetForwardVector().z )
|
||||
info.vVelocity = iVec
|
||||
projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
end
|
||||
|
||||
function Reimu02GetChance(caster)
|
||||
if caster.thtd_reimu_04_ball_count == nil then
|
||||
caster.thtd_reimu_04_ball_count = 0
|
||||
end
|
||||
if caster.thtd_reimu_04_hot_duration == nil then
|
||||
caster.thtd_reimu_04_hot_duration = 0
|
||||
end
|
||||
|
||||
if RollPercentage(caster:GetAbilityValue("thtd_reimu_02", "chance")) then
|
||||
if caster.thtd_reimu_04_ball_count < 7 then
|
||||
caster:EmitSound("Sound_THTD.thtd_reimu_02")
|
||||
caster.thtd_reimu_04_ball_count = caster.thtd_reimu_04_ball_count + 1
|
||||
caster.thtd_reimu_04_hot_duration = 20.0
|
||||
end
|
||||
return 2.0
|
||||
end
|
||||
|
||||
return 1.0
|
||||
end
|
||||
|
||||
function OnReimu03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_reimu_03_01")
|
||||
|
||||
Reimu03ThrowBallToPoint(keys,caster:GetOrigin(),targetPoint,120,1)
|
||||
end
|
||||
|
||||
function Reimu03ThrowBallToPoint(keys,origin,targetpoint,vhigh,count)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local curOrigin = Vector(origin.x,origin.y,origin.z)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/reimu/reimu_01_ball.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, curOrigin)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1/count,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(500/count,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)
|
||||
caster:SetContextThink(DoUniqueString("ability_reimu_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/heroes/reimu/reimu_01_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, curOrigin)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 1, Vector(500/count,0,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,curOrigin,keys.range/count)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = math.floor((damage/count) * Reimu02GetChance(caster)),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
UnitStunTarget(caster,v,keys.stun_time/count)
|
||||
end
|
||||
|
||||
if count < keys.max_count then
|
||||
count = count + 1
|
||||
for i=1,count do
|
||||
Reimu03ThrowBallToPoint(keys,curOrigin,curOrigin+RandomVector(300-count*30),vhigh*400/442,count)
|
||||
end
|
||||
end
|
||||
caster:EmitSound("Sound_THTD.thtd_reimu_03_02")
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnReimu04SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
-- 初始化
|
||||
if caster.thtd_reimu_04_ball_count == nil then
|
||||
caster.thtd_reimu_04_ball_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_reimu_04_think_count == nil then
|
||||
caster.thtd_reimu_04_think_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_reimu_04_think_count < 72 then
|
||||
caster.thtd_reimu_04_think_count = caster.thtd_reimu_04_think_count + 1
|
||||
else
|
||||
caster.thtd_reimu_04_think_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_reimu_04_ball_table == nil then
|
||||
caster.thtd_reimu_04_ball_table = {}
|
||||
end
|
||||
|
||||
for i=1,7 do
|
||||
if caster.thtd_reimu_04_ball_table[i] == nil then
|
||||
caster.thtd_reimu_04_ball_table[i] = {}
|
||||
end
|
||||
caster.thtd_reimu_04_ball_table[i]["origin"] =
|
||||
caster:GetOrigin() +
|
||||
Vector(
|
||||
math.cos(i*2*math.pi/7 + caster.thtd_reimu_04_think_count * math.pi/36)*75,
|
||||
math.sin(i*2*math.pi/7 + caster.thtd_reimu_04_think_count * math.pi/36)*75,
|
||||
128)
|
||||
end
|
||||
|
||||
-- 根据积累数量初始化光球
|
||||
if caster.thtd_reimu_04_ball_count > 0 then
|
||||
for i=1,caster.thtd_reimu_04_ball_count do
|
||||
if caster.thtd_reimu_04_ball_table[i]["effectIndex"] == nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_reimu/ability_reimu_04.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1/12,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(500/12,0,0))
|
||||
caster.thtd_reimu_04_ball_table[i]["effectIndex"] = effectIndex
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 旋转光球
|
||||
for i=1,7 do
|
||||
if caster.thtd_reimu_04_ball_table[i]["effectIndex"] ~= nil then
|
||||
ParticleManager:SetParticleControl(caster.thtd_reimu_04_ball_table[i]["effectIndex"], 0, caster.thtd_reimu_04_ball_table[i]["origin"] )
|
||||
end
|
||||
end
|
||||
|
||||
if caster.thtd_reimu_04_ball_count == 7 and caster.thtd_reimu_04_ball_7_bonus == nil then
|
||||
caster.thtd_reimu_04_ball_7_bonus = keys.power_up
|
||||
if caster:IsPower999() then caster.thtd_reimu_04_ball_7_bonus = caster.thtd_reimu_04_ball_7_bonus * 7 end
|
||||
caster:THTD_AddPowerPercentage(caster.thtd_reimu_04_ball_7_bonus, "thtd_reimu_04_power_buff")
|
||||
caster:SetContextThink(DoUniqueString("thtd_reimu_04_power_bonus"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
caster:THTD_AddPowerPercentage("thtd_reimu_04_power_buff")
|
||||
caster.thtd_reimu_04_ball_7_bonus = nil
|
||||
return nil
|
||||
end,
|
||||
7.0)
|
||||
end
|
||||
|
||||
local tick_count = 36
|
||||
if caster:IsPower666() then tick_count = 12 end
|
||||
|
||||
-- 光球攻击行为
|
||||
if caster.thtd_reimu_04_ball_count == 7 and caster.thtd_reimu_04_think_count%tick_count == 0 then -- 原始为8,卡顿改善及伤害系数平衡
|
||||
if caster.thtd_reimu_04_think_count >= 72 then caster.thtd_reimu_04_think_count = 0 end -- 修复达到72后连续触发,0余数为0造成
|
||||
Reimu04AttackTargetPoint(keys)
|
||||
for i=1,7 do
|
||||
if caster.thtd_reimu_04_ball_table[i]["effectIndex"] ~= nil then
|
||||
ParticleManager:SetParticleControl(caster.thtd_reimu_04_ball_table[i]["effectIndex"], 3, Vector(1000/12,0,0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 保持热度时间,结束光球
|
||||
if caster.thtd_reimu_04_hot_duration == nil then
|
||||
caster.thtd_reimu_04_hot_duration = 0
|
||||
end
|
||||
|
||||
caster.thtd_reimu_04_hot_duration = caster.thtd_reimu_04_hot_duration - 0.02
|
||||
|
||||
if caster.thtd_reimu_04_hot_duration < 0 then
|
||||
Reimu04ReleaseBall(keys)
|
||||
end
|
||||
end
|
||||
|
||||
function Reimu04ReleaseBall(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster.thtd_reimu_04_ball_table ~= nil then
|
||||
caster.thtd_reimu_04_hot_duration = 0
|
||||
caster.thtd_reimu_04_ball_count = 0
|
||||
for i=1,7 do
|
||||
if caster.thtd_reimu_04_ball_table[i]["effectIndex"] ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_reimu_04_ball_table[i]["effectIndex"],true)
|
||||
caster.thtd_reimu_04_ball_table[i]["effectIndex"] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Reimu04AttackTargetPoint(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),1000)
|
||||
if targets[1]==nil then return end
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_reimu_04_01")
|
||||
|
||||
local target = targets[1]
|
||||
local vecCaster = caster.thtd_reimu_04_ball_table[RandomInt(1,7)]["origin"]
|
||||
local pointRad = GetRadBetweenTwoVec2D(vecCaster,target:GetOrigin())
|
||||
|
||||
local randomPi = RandomFloat(-2*math.pi,2*math.pi)
|
||||
local forwardVec = Vector(math.cos(pointRad+randomPi), math.sin(pointRad+randomPi),RandomFloat(0,1))
|
||||
|
||||
local BulletTable = {
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_reimu/ability_reimu_04_projectile.vpcf",
|
||||
vSpawnOrigin = vecCaster,
|
||||
vSpawnOriginNew = vecCaster,
|
||||
fDistance = 5000,
|
||||
fStartRadius = 60,
|
||||
fEndRadius = 60,
|
||||
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 = true,
|
||||
vVelocity = forwardVec,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 400,
|
||||
iVisionTeamNumber = caster:GetTeamNumber(),
|
||||
}
|
||||
|
||||
local speed = 2000
|
||||
local acc = 200
|
||||
local iVelo = 1000
|
||||
|
||||
CreateProjectileMoveToTarget(BulletTable,caster,target,speed,iVelo,-acc,
|
||||
function(unit,vec)
|
||||
local targetpoint = Vector(vec.x,vec.y,caster:GetOrigin().z)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetpoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * Reimu02GetChance(caster),
|
||||
ability = keys.ability,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_reimu_04_02")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_reimu/ability_reimu_04_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetpoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetpoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
)
|
||||
end
|
||||
987
scripts/vscripts/abilities/abilityreimu_pet.lua
Executable file
987
scripts/vscripts/abilities/abilityreimu_pet.lua
Executable file
@@ -0,0 +1,987 @@
|
||||
|
||||
local reimu_pet_sound =
|
||||
{
|
||||
"UI.Aowu",
|
||||
"Icewrack_Pup.Ult.Howl",
|
||||
"Icewrack_Pup.Flee",
|
||||
"Icewrack_Pup.idle_alt_bark",
|
||||
"Icewrack_Pup.Alert",
|
||||
"Icewrack_Pup.Happy",
|
||||
"Icewrack_Pup.Breath",
|
||||
}
|
||||
|
||||
local reimu_pet_model =
|
||||
{
|
||||
-- 默认
|
||||
h000 = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant.vmdl",
|
||||
h000b = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl2/courier_ti10_radiant_lvl2.vmdl",
|
||||
h000c = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl3/courier_ti10_radiant_lvl3.vmdl",
|
||||
h000d = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl4/courier_ti10_radiant_lvl4.vmdl",
|
||||
h000e = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl5/courier_ti10_radiant_lvl5.vmdl",
|
||||
h000f = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl6/courier_ti10_radiant_lvl6.vmdl",
|
||||
h000g = "models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl7/courier_ti10_radiant_lvl7.vmdl",
|
||||
h001 = "models/pets/icewrack_wolf/icewrack_wolf.vmdl",
|
||||
h002 = "models/heroes/invoker_kid/invoker_kid_trainer_dragon.vmdl",
|
||||
-- h001 = "models/props_gameplay/donkey.vmdl", -- 默认信使,小马,天辉
|
||||
-- h002 = "models/props_gameplay/donkey_dire.vmdl", -- 默认信使,小马,夜宴
|
||||
|
||||
|
||||
h003 = "models/pets/armadillo/armadillo.vmdl",
|
||||
h004 = "models/courier/baby_rosh/babyroshan_ti9.vmdl",
|
||||
|
||||
|
||||
--普通信使 beginner
|
||||
h101 = "models/courier/skippy_parrot/skippy_parrot.vmdl",
|
||||
h102 = "models/courier/smeevil_mammoth/smeevil_mammoth.vmdl",
|
||||
h103 = "models/items/courier/arneyb_rabbit/arneyb_rabbit.vmdl",
|
||||
h104 = "models/items/courier/axolotl/axolotl.vmdl",
|
||||
h105 = "models/items/courier/coco_the_courageous/coco_the_courageous.vmdl",
|
||||
h106 = "models/items/courier/coral_furryfish/coral_furryfish.vmdl",
|
||||
h107 = "models/items/courier/corsair_ship/corsair_ship.vmdl",
|
||||
h108 = "models/items/courier/duskie/duskie.vmdl",
|
||||
h109 = "models/items/courier/itsy/itsy.vmdl",
|
||||
h110 = "models/items/courier/jumo/jumo.vmdl",
|
||||
h111 = "models/items/courier/mighty_chicken/mighty_chicken.vmdl",
|
||||
h112 = "models/items/courier/nexon_turtle_05_green/nexon_turtle_05_green.vmdl",
|
||||
h113 = "models/items/courier/pumpkin_courier/pumpkin_courier.vmdl",
|
||||
h114 = "models/items/courier/pw_ostrich/pw_ostrich.vmdl",
|
||||
h115 = "models/items/courier/scuttling_scotty_penguin/scuttling_scotty_penguin.vmdl",
|
||||
h116 = "models/items/courier/shagbark/shagbark.vmdl",
|
||||
h117 = "models/items/courier/snaggletooth_red_panda/snaggletooth_red_panda.vmdl",
|
||||
h118 = "models/items/courier/snail/courier_snail.vmdl",
|
||||
h119 = "models/items/courier/teron/teron.vmdl",
|
||||
h120 = "models/items/courier/xianhe_stork/xianhe_stork.vmdl",
|
||||
h121 = "models/items/courier/starladder_grillhound/starladder_grillhound.vmdl",
|
||||
h122 = "models/items/courier/pw_zombie/pw_zombie.vmdl",
|
||||
h123 = "models/items/courier/raiq/raiq.vmdl",
|
||||
h124 = "models/courier/frog/frog.vmdl",
|
||||
h125 = "models/courier/godhorse/godhorse.vmdl",
|
||||
h126 = "models/courier/imp/imp.vmdl",
|
||||
h127 = "models/courier/mighty_boar/mighty_boar.vmdl",
|
||||
h128 = "models/items/courier/onibi_lvl_03/onibi_lvl_03.vmdl",
|
||||
h129 = "models/items/courier/echo_wisp/echo_wisp.vmdl", --蠕行水母
|
||||
h130 = "models/courier/sw_donkey/sw_donkey.vmdl", --驴法师new
|
||||
h131 = "models/items/courier/gnomepig/gnomepig.vmdl", --丰臀公主new
|
||||
h132 = "models/items/furion/treant/ravenous_woodfang/ravenous_woodfang.vmdl",--焚牙树精new
|
||||
h133 = "models/courier/mechjaw/mechjaw.vmdl",--机械咬人箱new
|
||||
h134 = "models/items/courier/mole_messenger/mole_messenger.vmdl",--1级矿车老鼠
|
||||
h135 = "models/items/courier/jumo_dire/jumo_dire.vmdl",
|
||||
h136 = "models/items/courier/courier_ti9/courier_ti9.vmdl",
|
||||
h137 = "models/items/courier/courier_ti9/courier_ti9_lvl2/courier_ti9_lvl2.vmdl",
|
||||
h138 = "models/props_gameplay/donkey.vmdl",
|
||||
h139 = "models/hy/huya.vmdl",
|
||||
|
||||
--小英雄信使 ameteur
|
||||
h201 = "models/courier/doom_demihero_courier/doom_demihero_courier.vmdl",
|
||||
h202 = "models/courier/huntling/huntling.vmdl",
|
||||
h203 = "models/courier/minipudge/minipudge.vmdl",
|
||||
h204 = "models/courier/seekling/seekling.vmdl",
|
||||
h205 = "models/items/courier/baekho/baekho.vmdl",
|
||||
h206 = "models/items/courier/basim/basim.vmdl",
|
||||
h207 = "models/items/courier/devourling/devourling.vmdl",
|
||||
h208 = "models/items/courier/faceless_rex/faceless_rex.vmdl",
|
||||
h209 = "models/items/courier/tinkbot/tinkbot.vmdl",
|
||||
h210 = "models/items/courier/lilnova/lilnova.vmdl",
|
||||
h211 = "models/items/courier/amphibian_kid/amphibian_kid.vmdl",
|
||||
h212 = "models/courier/venoling/venoling.vmdl",
|
||||
h213 = "models/courier/juggernaut_dog/juggernaut_dog.vmdl",
|
||||
h214 = "models/courier/otter_dragon/otter_dragon.vmdl",
|
||||
h215 = "models/items/courier/boooofus_courier/boooofus_courier.vmdl",
|
||||
h216 = "models/courier/baby_winter_wyvern/baby_winter_wyvern.vmdl",
|
||||
h217 = "models/courier/yak/yak.vmdl",
|
||||
h218 = "models/items/furion/treant/eternalseasons_treant/eternalseasons_treant.vmdl",
|
||||
h219 = "models/items/courier/blue_lightning_horse/blue_lightning_horse.vmdl",
|
||||
h220 = "models/items/courier/waldi_the_faithful/waldi_the_faithful.vmdl",
|
||||
h221 = "models/items/courier/bajie_pig/bajie_pig.vmdl",
|
||||
h222 = "models/items/courier/courier_faun/courier_faun.vmdl",
|
||||
h223 = "models/items/courier/livery_llama_courier/livery_llama_courier.vmdl",
|
||||
h224 = "models/items/courier/onibi_lvl_10/onibi_lvl_10.vmdl",
|
||||
h225 = "models/items/courier/little_fraid_the_courier_of_simons_retribution/little_fraid_the_courier_of_simons_retribution.vmdl", --胆小南瓜人
|
||||
h226 = "models/items/courier/hermit_crab/hermit_crab.vmdl", --螃蟹1
|
||||
h227 = "models/items/courier/hermit_crab/hermit_crab_boot.vmdl", --螃蟹2
|
||||
h228 = "models/items/courier/hermit_crab/hermit_crab_shield.vmdl", --螃蟹3
|
||||
h229 = "models/courier/donkey_unicorn/donkey_unicorn.vmdl", --竭智法师new
|
||||
h230 = "models/items/courier/white_the_crystal_courier/white_the_crystal_courier.vmdl", --蓝心白隼new
|
||||
h231 = "models/items/furion/treant/furion_treant_nelum_red/furion_treant_nelum_red.vmdl",--莲花人new
|
||||
h232 = "models/courier/beetlejaws/mesh/beetlejaws.vmdl",--甲虫咬人箱new
|
||||
h233 = "models/courier/smeevil_bird/smeevil_bird.vmdl",
|
||||
h234 = "models/items/courier/mole_messenger/mole_messenger_lvl4.vmdl",--蜡烛头矿车老鼠
|
||||
h235 = "models/items/courier/chocobo/chocobo.vmdl", --迅捷陆行鸟
|
||||
h236 = "models/items/courier/flightless_dod/flightless_dod.vmdl", --嘟嘟鸟
|
||||
h237 = "models/items/courier/frostivus2018_courier_serac_the_seal/frostivus2018_courier_serac_the_seal.vmdl",
|
||||
h238 = "models/items/courier/pangolier_squire/pangolier_squire.vmdl",
|
||||
h239 = "models/hujing_wangyu/hujing.vmdl",
|
||||
h240 = "models/items/courier/courier_ti9/courier_ti9_lvl3/courier_ti9_lvl3.vmdl",
|
||||
h241 = "models/items/courier/axolotl/axolotl.vmdl",
|
||||
h242 = "models/items/courier/snaggletooth_red_panda/snaggletooth_red_panda.vmdl",
|
||||
h243 = "models/items/courier/xianhe_stork/xianhe_stork.vmdl",
|
||||
|
||||
--珍藏信使 pro
|
||||
h301 = "models/items/courier/bookwyrm/bookwyrm.vmdl",
|
||||
h302 = "models/items/courier/captain_bamboo/captain_bamboo.vmdl",
|
||||
h303 = "models/items/courier/kanyu_shark/kanyu_shark.vmdl",
|
||||
h304 = "models/items/courier/tory_the_sky_guardian/tory_the_sky_guardian.vmdl",
|
||||
h305 = "models/items/courier/shroomy/shroomy.vmdl",
|
||||
h306 = "models/items/courier/courier_janjou/courier_janjou.vmdl",
|
||||
h307 = "models/items/courier/green_jade_dragon/green_jade_dragon.vmdl",
|
||||
h308 = "models/courier/drodo/drodo.vmdl",
|
||||
h309 = "models/courier/mech_donkey/mech_donkey.vmdl",
|
||||
h310 = "models/courier/donkey_crummy_wizard_2014/donkey_crummy_wizard_2014.vmdl",
|
||||
h311 = "models/courier/octopus/octopus.vmdl",
|
||||
h312 = "models/items/courier/scribbinsthescarab/scribbinsthescarab.vmdl",
|
||||
h313 = "models/courier/defense3_sheep/defense3_sheep.vmdl",
|
||||
h314 = "models/items/courier/snapjaw/snapjaw.vmdl",
|
||||
h315 = "models/items/courier/g1_courier/g1_courier.vmdl",
|
||||
h316 = "models/courier/donkey_trio/mesh/donkey_trio.vmdl",
|
||||
h317 = "models/items/courier/boris_baumhauer/boris_baumhauer.vmdl",
|
||||
h318 = "models/courier/baby_rosh/babyroshan.vmdl",
|
||||
h319 = "models/items/courier/bearzky/bearzky.vmdl",
|
||||
h320 = "models/items/courier/defense4_radiant/defense4_radiant.vmdl",
|
||||
h321 = "models/items/courier/defense4_dire/defense4_dire.vmdl",
|
||||
h322 = "models/items/courier/onibi_lvl_20/onibi_lvl_20.vmdl",
|
||||
h323 = "models/items/juggernaut/ward/fortunes_tout/fortunes_tout.vmdl", --招财猫
|
||||
h324 = "models/items/courier/hermit_crab/hermit_crab_necro.vmdl", --螃蟹4
|
||||
h325 = "models/items/courier/hermit_crab/hermit_crab_travelboot.vmdl", --螃蟹5
|
||||
h326 = "models/items/courier/hermit_crab/hermit_crab_lotus.vmdl", --螃蟹6
|
||||
h327 = "models/courier/donkey_ti7/donkey_ti7.vmdl",
|
||||
h328 = "models/items/courier/shibe_dog_cat/shibe_dog_cat.vmdl", --天猫地狗new
|
||||
h329 = "models/items/furion/treant/hallowed_horde/hallowed_horde.vmdl",--万圣树群new
|
||||
h330 = "models/courier/flopjaw/flopjaw.vmdl",--大嘴咬人箱new
|
||||
h331 = "models/courier/lockjaw/lockjaw.vmdl",--咬人箱洛克new
|
||||
h332 = "models/items/courier/butch_pudge_dog/butch_pudge_dog.vmdl",--布狗new
|
||||
h333 = "models/courier/turtle_rider/turtle_rider.vmdl",
|
||||
h334 = "models/courier/smeevil_crab/smeevil_crab.vmdl",
|
||||
h335 = "models/items/courier/mole_messenger/mole_messenger_lvl6.vmdl",--绿钻头矿车老鼠
|
||||
h336 = "models/items/courier/amaterasu/amaterasu.vmdl", --天照大神
|
||||
h337 = "models/qie/qie.vmdl",
|
||||
h338 = "models/courier/f2p_courier/f2p_courier.vmdl",
|
||||
h339 = "models/items/courier/azuremircourierfinal/azuremircourierfinal.vmdl",
|
||||
h340 = "models/items/courier/courier_ti9/courier_ti9_lvl6/courier_ti9_lvl6.vmdl",
|
||||
h341 = "models/bilibilitv/model/tv.vmdl",
|
||||
h342 = "models/courier/baby_rosh/babyroshan.vmdl",
|
||||
h343 = "models/courier/baby_rosh/babyroshan.vmdl",
|
||||
h344 = "models/courier/baby_rosh/babyroshan.vmdl",
|
||||
h345 = "models/courier/baby_winter_wyvern/baby_winter_wyvern.vmdl",
|
||||
h346 = "models/courier/beetlejaws/mesh/beetlejaws.vmdl",
|
||||
h347 = "models/courier/doom_demihero_courier/doom_demihero_courier.vmdl",
|
||||
h348 = "models/courier/huntling/huntling.vmdl",
|
||||
h349 = "models/courier/minipudge/minipudge.vmdl",
|
||||
h350 = "models/courier/seekling/seekling.vmdl",
|
||||
h351 = "models/courier/venoling/venoling.vmdl",
|
||||
h352 = "models/items/courier/axolotl/axolotl.vmdl",
|
||||
h353 = "models/items/courier/devourling/devourling.vmdl",
|
||||
h354 = "models/courier/baby_rosh/babyroshan_elemental.vmdl",
|
||||
h355 = "models/courier/baby_rosh/babyroshan_elemental.vmdl",
|
||||
|
||||
h399 = "models/courier/baby_rosh/babyroshan_winter18.vmdl",--姜饼肉山
|
||||
|
||||
--战队信使 master
|
||||
h401 = "models/courier/navi_courier/navi_courier.vmdl",
|
||||
h402 = "models/items/courier/courier_mvp_redkita/courier_mvp_redkita.vmdl",
|
||||
h403 = "models/items/courier/ig_dragon/ig_dragon.vmdl",
|
||||
h404 = "models/items/courier/lgd_golden_skipper/lgd_golden_skipper.vmdl",
|
||||
h405 = "models/items/courier/vigilante_fox_red/vigilante_fox_red.vmdl",
|
||||
h406 = "models/items/courier/virtus_werebear_t3/virtus_werebear_t3.vmdl",
|
||||
h407 = "models/items/courier/throe/throe.vmdl",
|
||||
h408 = "models/items/courier/vaal_the_animated_constructradiant/vaal_the_animated_constructradiant.vmdl",
|
||||
h409 = "models/items/courier/vaal_the_animated_constructdire/vaal_the_animated_constructdire.vmdl",
|
||||
h410 = "models/items/courier/carty/carty.vmdl",
|
||||
h411 = "models/items/courier/carty_dire/carty_dire.vmdl",
|
||||
h412 = "models/items/courier/dc_angel/dc_angel.vmdl",
|
||||
h413 = "models/items/courier/dc_demon/dc_demon.vmdl",
|
||||
h414 = "models/items/courier/vigilante_fox_green/vigilante_fox_green.vmdl",
|
||||
h415 = "models/items/courier/bts_chirpy/bts_chirpy.vmdl",
|
||||
h416 = "models/items/courier/krobeling/krobeling.vmdl",
|
||||
h417 = "models/items/courier/jin_yin_black_fox/jin_yin_black_fox.vmdl",
|
||||
h418 = "models/items/courier/jin_yin_white_fox/jin_yin_white_fox.vmdl",
|
||||
h419 = "models/items/courier/fei_lian_blue/fei_lian_blue.vmdl",
|
||||
h420 = "models/items/courier/gama_brothers/gama_brothers.vmdl",
|
||||
h421 = "models/items/courier/onibi_lvl_21/onibi_lvl_21.vmdl",
|
||||
h422 = "models/items/courier/wabbit_the_mighty_courier_of_heroes/wabbit_the_mighty_courier_of_heroes.vmdl", --小飞侠
|
||||
h423 = "models/items/courier/hermit_crab/hermit_crab_octarine.vmdl", --螃蟹7
|
||||
h424 = "models/items/courier/hermit_crab/hermit_crab_skady.vmdl", --螃蟹8
|
||||
h425 = "models/items/courier/hermit_crab/hermit_crab_aegis.vmdl", --螃蟹9
|
||||
h426 = "models/items/furion/treant_flower_1.vmdl",--绽放树精new
|
||||
h427 = "models/courier/smeevil_magic_carpet/smeevil_magic_carpet.vmdl",
|
||||
h428 = "models/items/courier/mole_messenger/mole_messenger_lvl7.vmdl",--绿钻头金矿车老鼠
|
||||
h499 = "models/items/courier/krobeling_gold/krobeling_gold.vmdl",--金dp
|
||||
h429 = "models/items/courier/nilbog/nilbog.vmdl",--贪小疯魔
|
||||
h430 = "models/courier/frull/frull_courier.vmdl", --灵犀弗拉尔
|
||||
h431 = "models/items/courier/sltv_10_courier/sltv_10_courier.vmdl", --黄油小生
|
||||
h432 = "models/items/courier/nian_courier/nian_courier.vmdl", --年兽宝宝
|
||||
h433 = "models/courier/baby_rosh/babyroshan_ti9.vmdl",
|
||||
h434 = "models/items/courier/courier_ti9/courier_ti9_lvl7/courier_ti9_lvl7.vmdl",
|
||||
h435 = "models/shudaixiong/model/shudaixiong/shudaixiong.vmdl",
|
||||
h436 = "models/courier/baby_rosh/babyroshan.vmdl",
|
||||
h437 = "models/courier/baby_rosh/babyroshan.vmdl",
|
||||
h438 = "models/courier/baby_winter_wyvern/baby_winter_wyvern.vmdl",
|
||||
h439 = "models/courier/flopjaw/flopjaw.vmdl",
|
||||
h440 = "models/courier/juggernaut_dog/juggernaut_dog.vmdl",
|
||||
h441 = "models/courier/smeevil_crab/smeevil_crab.vmdl",
|
||||
h442 = "models/items/courier/axolotl/axolotl.vmdl",
|
||||
h443 = "models/items/courier/fei_lian_blue/fei_lian_blue.vmdl",
|
||||
h444 = "models/items/courier/wabbit_the_mighty_courier_of_heroes/wabbit_the_mighty_courier_of_heroes.vmdl",
|
||||
h445 = "models/items/courier/wabbit_the_mighty_courier_of_heroes/wabbit_the_mighty_courier_of_heroes.vmdl",
|
||||
h446 = "models/items/courier/wabbit_the_mighty_courier_of_heroes/wabbit_the_mighty_courier_of_heroes.vmdl",
|
||||
}
|
||||
|
||||
local reimu_pet_skin =
|
||||
{
|
||||
h138 = 1,
|
||||
h436 = 1,
|
||||
h437 = 2,
|
||||
h342 = 3,
|
||||
h343 = 4,
|
||||
h344 = 5,
|
||||
h354 = 1,
|
||||
h355 = 2,
|
||||
h345 = 1,
|
||||
h438 = 2,
|
||||
h346 = 1,
|
||||
h347 = 1,
|
||||
h348 = 1,
|
||||
h440 = 1,
|
||||
h349 = 1,
|
||||
h350 = 1,
|
||||
h441 = 1,
|
||||
h351 = 1,
|
||||
|
||||
h241 = 1,
|
||||
h352 = 2,
|
||||
h442 = 3,
|
||||
h353 = 1,
|
||||
h242 = 1,
|
||||
h444 = 1,
|
||||
h445 = 2,
|
||||
h446 = 3,
|
||||
h243 = 1,
|
||||
h443 = 1,
|
||||
h439 = 1,
|
||||
}
|
||||
|
||||
local reimu_pet_size =
|
||||
{
|
||||
h000 = 1,
|
||||
|
||||
h001 = 1,
|
||||
h002 = 1,
|
||||
--普通信使 beginner
|
||||
h101 = 1.1,
|
||||
h102 = 1.1,
|
||||
h103 = 1.1,
|
||||
h104 = 1,
|
||||
h105 = 1,
|
||||
h106 = 1,
|
||||
h107 = 1.2,
|
||||
h108 = 1,
|
||||
h109 = 1.1,
|
||||
h110 = 1.1,
|
||||
h111 = 1.1,
|
||||
h112 = 1.2,
|
||||
h113 = 1,
|
||||
h114 = 1.2,
|
||||
h115 = 1.2,
|
||||
h116 = 1,
|
||||
h117 = 1.3,
|
||||
h118 = 1.1,
|
||||
h119 = 1.3,
|
||||
h120 = 1.3,
|
||||
h121 = 1.1,
|
||||
h122 = 1.1,
|
||||
h123 = 1.2,
|
||||
h124 = 1,
|
||||
h125 = 1,
|
||||
h126 = 1,
|
||||
h127 = 1,
|
||||
h128 = 1.1,
|
||||
h129 = 1.2, --蠕行水母
|
||||
h130 = 1, --驴法师new
|
||||
h131 = 1, --丰臀公主new
|
||||
h132 = 0.7,--焚牙树精new
|
||||
h133 = 1.1,--机械咬人箱new
|
||||
h134 = 1.1,--1级矿车老鼠
|
||||
h135 = 1.1,
|
||||
h136 = 1.1,
|
||||
h137 = 1.15,
|
||||
h138 = 1.15,
|
||||
h139 = 2.5,
|
||||
|
||||
h199 = 1.5,
|
||||
--小英雄信使 ameteur
|
||||
h201 = 1.2,
|
||||
h202 = 1.2,
|
||||
h203 = 1.2,
|
||||
h204 = 1.2,
|
||||
h205 = 1.2,
|
||||
h206 = 1.2,
|
||||
h207 = 1.2,
|
||||
h208 = 1.3,
|
||||
h209 = 1.2,
|
||||
h210 = 1.25,
|
||||
|
||||
h211 = 1.2,
|
||||
h212 = 1.1,
|
||||
h213 = 1,
|
||||
h214 = 1.25,
|
||||
h215 = 1.2,
|
||||
h216 = 1.25,
|
||||
h217 = 1.2,
|
||||
h218 = 1.1,
|
||||
h219 = 1.2,
|
||||
h220 = 1.25,
|
||||
h221 = 1.25,
|
||||
h222 = 1.3,
|
||||
h223 = 1.15,
|
||||
h224 = 1.25,
|
||||
h225 = 1.3, --胆小南瓜人
|
||||
h226 = 1.3, --螃蟹1
|
||||
h227 = 1.3, --螃蟹2
|
||||
h228 = 1.2, --螃蟹3
|
||||
|
||||
h229 = 1.2, --竭智法师new
|
||||
h230 = 1.3, --蓝心白隼new
|
||||
h231 = 0.8,--莲花人new
|
||||
h232 = 1.2,--甲虫咬人箱new
|
||||
h233 = 1.2,
|
||||
h234 = 1.2,--蜡烛头矿车老鼠
|
||||
h235 = 1.2, --迅捷陆行鸟
|
||||
h236 = 1.2, --嘟嘟鸟
|
||||
h237 = 1.2,
|
||||
h238 = 0.8,
|
||||
h239 = 1.4,
|
||||
h240 = 1.25,
|
||||
h241 = 1.1,
|
||||
h242 = 1.4,
|
||||
h243 = 1.4,
|
||||
|
||||
--珍藏信使 pro
|
||||
h301 = 1.3,
|
||||
h302 = 1.3,
|
||||
h303 = 1.3,
|
||||
h304 = 1.35,
|
||||
h305 = 1.3,
|
||||
h306 = 1.3,
|
||||
h307 = 1.3,
|
||||
h308 = 1.3,
|
||||
h309 = 1.2,
|
||||
|
||||
h310 = 1.2,
|
||||
h311 = 1.25,
|
||||
h312 = 1.3,
|
||||
h313 = 1.3,
|
||||
h314 = 1.3,
|
||||
h315 = 1.25,
|
||||
h316 = 1.3,
|
||||
h317 = 1.4,
|
||||
h318 = 1.3,
|
||||
h319 = 1.3,
|
||||
h320 = 1.3,
|
||||
h321 = 1.3,
|
||||
h322 = 1.3,
|
||||
h323 = 1.1, --招财猫
|
||||
h324 = 1.3, --螃蟹4
|
||||
h325 = 1.25, --螃蟹5
|
||||
h326 = 1.25, --螃蟹6
|
||||
h327 = 1.25,
|
||||
|
||||
h328 = 1.3, --天猫地狗new
|
||||
h329 = 0.9,--万圣树群new
|
||||
h330 = 1.3,--大嘴咬人箱new
|
||||
h331 = 1.25,--咬人箱洛克new
|
||||
h332 = 1.3,--布狗new
|
||||
h333 = 1.3,
|
||||
h334 = 1.3,
|
||||
h335 = 1.1,--绿钻头矿车老鼠
|
||||
h336 = 1.15, --天照大神
|
||||
h337 = 1.4,
|
||||
h338 = 1.3,
|
||||
h339 = 1.4,
|
||||
h340 = 1.3,
|
||||
h341 = 2.3,
|
||||
h342 = 1.3,
|
||||
h343 = 1.3,
|
||||
h344 = 1.3,
|
||||
h354 = 1.3,
|
||||
h355 = 1.3,
|
||||
h345 = 1.35,
|
||||
h346 = 1.3,
|
||||
h347 = 1.3,
|
||||
h348 = 1.3,
|
||||
h349 = 1.3,
|
||||
h350 = 1.3,
|
||||
h351 = 1.2,
|
||||
h352 = 1.2,
|
||||
h353 = 1.3,
|
||||
|
||||
h399 = 1.2,--姜饼肉山
|
||||
|
||||
--战队信使 master
|
||||
h401 = 1.4,
|
||||
h402 = 1.4,
|
||||
h403 = 1.4,
|
||||
h404 = 1.55,
|
||||
h405 = 1.4,
|
||||
h406 = 1.5,
|
||||
h407 = 1.3,
|
||||
|
||||
h408 = 1.35,
|
||||
h409 = 1.35,
|
||||
h410 = 1.3,
|
||||
h411 = 1.3,
|
||||
h412 = 1.3,
|
||||
h413 = 1.3,
|
||||
h414 = 1.4,
|
||||
h415 = 1.35,
|
||||
h416 = 1.4,
|
||||
h417 = 1.4,
|
||||
h418 = 1.4,
|
||||
h419 = 1.4,
|
||||
h420 = 1.2,
|
||||
h421 = 1.35,
|
||||
h422 = 1.4, --小飞侠
|
||||
h423 = 1.3, --螃蟹7
|
||||
h424 = 1.3, --螃蟹8
|
||||
h425 = 1.3, --螃蟹9
|
||||
|
||||
h426 = 1.1,--绽放树精new
|
||||
h427 = 1.55,
|
||||
h428 = 1.2,--绿钻头金矿车老鼠
|
||||
|
||||
h499 = 1.55,--金dp
|
||||
h429 = 1.3,--贪小疯魔
|
||||
|
||||
h430 = 1.3, --灵犀弗拉尔
|
||||
h431 = 1.2, --黄油小生
|
||||
h432 = 1.3, --年兽宝宝
|
||||
h433 = 1.35,
|
||||
h434 = 1.4,
|
||||
h435 = 1.0,
|
||||
h438 = 1.45,
|
||||
h439 = 1.35,
|
||||
h440 = 1.2,
|
||||
h441 = 1.4,
|
||||
h442 = 1.3,
|
||||
h444 = 1.4,
|
||||
h445 = 1.4,
|
||||
h446 = 1.4,
|
||||
h443 = 1.4,
|
||||
h436 = 1.4,
|
||||
h437 = 1.4,
|
||||
}
|
||||
|
||||
local reimu_pet_effect =
|
||||
{
|
||||
-- 未包含的
|
||||
-- "e316", -- 一圈蓝色五角星
|
||||
-- "e999", -- 皇冠
|
||||
|
||||
"e000", -- 无特效
|
||||
|
||||
"e101",
|
||||
"e102",
|
||||
"e103",
|
||||
"e104",
|
||||
"e107",
|
||||
"e108",
|
||||
"e111",
|
||||
"e112",
|
||||
"e113",
|
||||
"e114",
|
||||
"e201",
|
||||
"e202",
|
||||
"e203",
|
||||
"e205",
|
||||
"e210",
|
||||
"e213",
|
||||
"e214",
|
||||
"e301",
|
||||
"e302",
|
||||
"e303",
|
||||
"e304",
|
||||
"e305",
|
||||
"e306",
|
||||
"e308",
|
||||
"e309",
|
||||
"e311",
|
||||
"e312",
|
||||
"e313",
|
||||
"e315",
|
||||
"e317",
|
||||
"e319",
|
||||
"e320",
|
||||
"e321",
|
||||
"e322",
|
||||
"e401",
|
||||
"e402",
|
||||
"e403",
|
||||
"e404",
|
||||
"e405",
|
||||
"e406",
|
||||
"e407",
|
||||
"e408",
|
||||
"e409",
|
||||
"e410",
|
||||
"e451",
|
||||
"e452",
|
||||
"e453",
|
||||
"e454",
|
||||
"e455",
|
||||
"e456",
|
||||
"e457",
|
||||
"e458",
|
||||
"e459",
|
||||
}
|
||||
|
||||
local courier_flyup_effect_list =
|
||||
{
|
||||
h208 = "effect/xukong/cour_rex_flying.vpcf",
|
||||
h432 = "effect/nianshou/courier_nian_ambient.vpcf",
|
||||
h499 = "effect/jin_dp/courier_krobeling_gold_ambient.vpcf",
|
||||
h399 = "effect/jiangbing/1.vpcf",
|
||||
h308 = "effect/drodo/1.vpcf",
|
||||
h199 = "effect/gewugu/3.vpcf",
|
||||
h239 = "effect/wangyu/1.vpcf",
|
||||
h303 = "effect/douyu/2.vpcf",
|
||||
h433 = "effect/roshan_ti9/1.vpcf",
|
||||
h341 = "effect/music/1.vpcf",
|
||||
h354 = "effect/lava_roshan/1.vpcf",
|
||||
h355 = "effect/frost_roshan/ambient.vpcf",
|
||||
h342 = "effect/darkmoon_roshan/1.vpcf",
|
||||
h343 = "effect/sand_roshan/baby_roshan_desert_sands_ambient.vpcf",
|
||||
h344 = "effect/biyu_roshan/1.vpcf",
|
||||
h436 = "effect/golden_roshan/ambient.vpcf",
|
||||
h437 = "effect/platinum_roshan/ambient.vpcf",
|
||||
h438 = "effect/golden_ww/1.vpcf",
|
||||
h439 = "effect/gold_angel/angels.vpcf",
|
||||
h440 = "effect/liansai_dog/1.vpcf",
|
||||
h441 = "effect/liansai_dog2/1.vpcf",
|
||||
h446 = "effect/wabbit/lvl3.vpcf",
|
||||
}
|
||||
|
||||
local courier_ground_effect_list =
|
||||
{
|
||||
h199 = "effect/gewugu/2.vpcf",
|
||||
h303 = "particles/gem/brewmaster_drunken_haze_debuff_bubbles_2.vpcf",
|
||||
}
|
||||
|
||||
function SetDefaultSkin(caster, index)
|
||||
local skin =
|
||||
{
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl1_ambient.vpcf",
|
||||
},
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl2/courier_ti10_radiant_lvl2.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl2_ambient.vpcf",
|
||||
},
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl3/courier_ti10_radiant_lvl3.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl3_ambient.vpcf",
|
||||
},
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl4/courier_ti10_radiant_lvl4.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl4_ambient.vpcf",
|
||||
},
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl5/courier_ti10_radiant_lvl5.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl5_ambient.vpcf",
|
||||
},
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl6/courier_ti10_radiant_lvl6.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl6_ambient.vpcf",
|
||||
},
|
||||
{
|
||||
"models/items/courier/courier_ti10_radiant/courier_ti10_radiant_lvl7/courier_ti10_radiant_lvl7.vmdl",
|
||||
"particles/econ/courier/courier_ti10/courier_ti10_lvl7_ambient.vpcf",
|
||||
}
|
||||
}
|
||||
if index == nil or index < 1 or index > #skin then
|
||||
index = RandomInt(1, #skin)
|
||||
end
|
||||
local model = skin[index][1]
|
||||
local effect = skin[index][2]
|
||||
caster:SetOriginalModel(model)
|
||||
caster:SetModel(model)
|
||||
caster:SetModelScale(1.0)
|
||||
|
||||
if caster.effect_name ~= nil then
|
||||
caster:RemoveAbility(caster.effect_name)
|
||||
caster:RemoveModifierByName('modifier_texiao_star')
|
||||
caster.effect_name = nil
|
||||
end
|
||||
if caster.default_effect ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.default_effect, true)
|
||||
caster.default_effect = nil
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle(effect, PATTACH_ABSORIGIN_FOLLOW, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
caster.default_effect = effectIndex
|
||||
-- ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
-- PATTACH_ABSORIGIN_FOLLOW
|
||||
-- PATTACH_POINT_FOLLOW
|
||||
-- PATTACH_WORLDORIGIN
|
||||
end
|
||||
|
||||
function OnSpellStartReimuPet01(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
if caster.is_init ~= true then
|
||||
caster.is_init = true
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_reimu_pet_01_state", nil)
|
||||
local playerid = caster:GetPlayerOwnerID()
|
||||
local petLevel = GameRules.PlayerData[playerid].pet_level
|
||||
caster.pet_level = petLevel
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_reimu_pet_01_level", nil):SetStackCount(petLevel)
|
||||
caster:CreatureLevelUp(petLevel - 1)
|
||||
|
||||
local keyTotal = GameRules.PlayerData[playerid].key_total or 0
|
||||
if keyTotal > 0 then
|
||||
local item = CreateItem("item_3121", nil, nil)
|
||||
if item ~= nil then
|
||||
item.owner_player_id = playerid
|
||||
item:SetPurchaser(caster:GetOwner())
|
||||
item:SetCurrentCharges(keyTotal)
|
||||
caster:GetOwner():AddItem(item)
|
||||
end
|
||||
end
|
||||
|
||||
local key = GameRules.PlayerData[playerid].pet_model
|
||||
if reimu_pet_model[key] == nil then
|
||||
GameRules.PlayerData[playerid].pet_model = "h000"
|
||||
key = "h000"
|
||||
end
|
||||
caster.pet_model = key
|
||||
|
||||
if key == "h000" then
|
||||
SetDefaultSkin(caster)
|
||||
elseif string.sub(key,1,4) == "h000" then
|
||||
SetDefaultSkin(caster, table.keyindex(reimu_pet_model, key))
|
||||
else
|
||||
local model = reimu_pet_model[key]
|
||||
caster:SetOriginalModel(model)
|
||||
caster:SetModel(model)
|
||||
caster:SetSkin(reimu_pet_skin[key] or 0)
|
||||
caster:SetModelScale(math.min(2.5, (reimu_pet_size[key] or 1) * (1 + 0.05 * petLevel)))
|
||||
|
||||
local effect = GameRules.PlayerData[playerid].pet_effect or "e000"
|
||||
if table.hasvalue(reimu_pet_effect, effect) then
|
||||
caster.effect_name = effect
|
||||
AddAbilityAndSetLevel(caster, effect)
|
||||
if courier_flyup_effect_list[effect] ~= nil then
|
||||
ShowCourierEffect(caster,1)
|
||||
else
|
||||
ShowCourierEffect(caster,2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local index = (table.keyindex(reimu_pet_model, caster.pet_model) or 0) + 1
|
||||
if index > math.min(caster.pet_level or 1, table.count(reimu_pet_model)) then
|
||||
index = 1
|
||||
end
|
||||
|
||||
if caster.default_effect ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.default_effect,true)
|
||||
caster.default_effect = nil
|
||||
end
|
||||
|
||||
local key = table.getkey(reimu_pet_model, index)
|
||||
caster.pet_model = key
|
||||
|
||||
if string.sub(key,1,4) == "h000" then
|
||||
SetDefaultSkin(caster, index)
|
||||
else
|
||||
local model = reimu_pet_model[key]
|
||||
caster:SetOriginalModel(model)
|
||||
caster:SetModel(model)
|
||||
caster:SetSkin(reimu_pet_skin[key] or 0)
|
||||
caster:SetModelScale(math.min(2.5, (reimu_pet_size[key] or 1) * (1 + 0.05 * caster.pet_level)))
|
||||
end
|
||||
|
||||
if tostring(PlayerResource:GetSteamID(caster:GetPlayerOwnerID())) == GameRules.GameData.admin then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner() , "show_message", {msg="change_to_pet_model", duration=5, params={key = caster.pet_model}, color="#ff0"} )
|
||||
end
|
||||
end
|
||||
|
||||
function OnSpellStartReimuPet02(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
if string.sub(caster.pet_model,1,4) ~= "h000" and caster.default_effect ~= nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.default_effect,true)
|
||||
caster.default_effect = nil
|
||||
end
|
||||
|
||||
if caster.effect_name ~= nil then
|
||||
caster:RemoveAbility(caster.effect_name)
|
||||
caster:RemoveModifierByName('modifier_texiao_star')
|
||||
end
|
||||
|
||||
local index = 0
|
||||
if caster.effect_name == nil then
|
||||
index = 1
|
||||
else
|
||||
for k,v in ipairs(reimu_pet_effect) do
|
||||
if v == caster.effect_name then
|
||||
index = k + 1
|
||||
break
|
||||
end
|
||||
end
|
||||
if index > math.min(caster.pet_level or 1, #reimu_pet_effect) then
|
||||
index = 1
|
||||
end
|
||||
end
|
||||
|
||||
local effect = reimu_pet_effect[index]
|
||||
caster.effect_name = effect
|
||||
AddAbilityAndSetLevel(caster, effect)
|
||||
if courier_flyup_effect_list[effect] ~= nil then
|
||||
ShowCourierEffect(caster,1)
|
||||
else
|
||||
ShowCourierEffect(caster,2)
|
||||
end
|
||||
|
||||
if tostring(PlayerResource:GetSteamID(caster:GetPlayerOwnerID())) == GameRules.GameData.admin then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner() , "show_message", {msg="change_to_pet_effect", duration=5, params={key = caster.effect_name}, color="#ff0"} )
|
||||
end
|
||||
end
|
||||
|
||||
function OnSpellStartReimuPet03(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
local playerid = caster:GetPlayerOwnerID()
|
||||
GameRules.PlayerData[playerid].pet_model = caster.pet_model
|
||||
GameRules.PlayerData[playerid].pet_effect = caster.effect_name
|
||||
Service:SavePetCustom(playerid)
|
||||
|
||||
UnitStunTarget(caster,caster,6.0)
|
||||
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local count = 4
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_patchouli_04/ability_patchouli_04.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster + Vector(0,0,256))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, vecCaster + Vector(0,0,256))
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vecCaster + Vector(0,0,256))
|
||||
|
||||
caster:SetContextThink(DoUniqueString("OnSpellStartReimuPet03"),
|
||||
function()
|
||||
count = count * 2
|
||||
local radius = math.min(128,count)
|
||||
ParticleManager:SetParticleControl(effectIndex, 14, Vector(radius,0,0))
|
||||
if count > 100 then
|
||||
ParticleManager:DestroyParticleSystemTimeFalse(effectIndex,3.0)
|
||||
return nil
|
||||
end
|
||||
return 0.5
|
||||
end,
|
||||
0.5)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/remilia/ability_remilia_04_laser.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster+Vector(0,0,700))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, vecCaster+Vector(800,0,800))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, vecCaster+Vector(0,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vecCaster+Vector(-800,0,800))
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, vecCaster+Vector(0,0,1600))
|
||||
ParticleManager:SetParticleControl(effectIndex, 6, vecCaster)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local effectIndexSmoke = ParticleManager:CreateParticle("particles/heroes/remilia/ability_remilia_04_laser_rocket.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 0, vecCaster+Vector(0,0,700))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 1, Vector(1,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 2, Vector(-1,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 3, Vector(0,0,0.5))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 4, Vector(0,0,-1))
|
||||
ParticleManager:DestroyParticleSystem(effectIndexSmoke,false)
|
||||
end
|
||||
|
||||
function OnSpellStartReimuPet04(keys)
|
||||
local caster = keys.caster
|
||||
local playerid = caster:GetPlayerOwnerID()
|
||||
local hero = caster:GetOwner()
|
||||
|
||||
if hero:GetNumItemsInInventory() >= THTD_MAX_ITEM_SLOT then
|
||||
CustomGameEventManager:Send_ServerToPlayer(hero:GetPlayerOwner(), "display_custom_error", {msg="not_enough_item_slot"})
|
||||
return
|
||||
end
|
||||
|
||||
if tostring(PlayerResource:GetSteamID(caster:GetPlayerOwnerID())) == GameRules.GameData.admin then
|
||||
local item = hero:FindItemInInventory("item_3121")
|
||||
if item ~= nil then
|
||||
item:SetCurrentCharges(item:GetCurrentCharges() + 1)
|
||||
else
|
||||
item = CreateItem("item_3121", nil, nil)
|
||||
if item ~= nil then
|
||||
item.owner_player_id = playerid
|
||||
item:SetPurchaser(hero)
|
||||
hero:AddItem(item)
|
||||
-- local vHitLoc = caster:GetAttachmentOrigin(caster:ScriptLookupAttachment("attach_hitloc"))
|
||||
-- local drop = CreateItemOnPositionSync(vHitLoc, item)
|
||||
-- item:LaunchLootInitialHeight(false, vHitLoc.z, vHitLoc.z+200, 1.0, GetGroundPosition(caster:GetOwner():GetAbsOrigin() + caster:GetOwner():GetForwardVector() * 100, caster:GetOwner()))
|
||||
end
|
||||
end
|
||||
caster:EmitSound(reimu_pet_sound[RandomInt(1, #reimu_pet_sound)])
|
||||
CustomGameEventManager:Send_ServerToPlayer(hero:GetPlayerOwner(), "show_message", {msg="key_made_tip", duration=3, params={}, color="#ff0"})
|
||||
|
||||
ParticleManager:DestroyParticleSystem(hero.thtd_emoji_effect,true)
|
||||
hero.thtd_emoji_effect = ParticleManager:CreateParticle("particles/thtd/emoji/thtd_msg_hongliange.vpcf", PATTACH_OVERHEAD_FOLLOW, hero)
|
||||
ParticleManager:SetParticleControlEnt(hero.thtd_emoji_effect , 0, hero, PATTACH_OVERHEAD_FOLLOW, "attach_hitloc", Vector(0,0,0), true) --灵梦用 attach_emoji
|
||||
ParticleManager:SetParticleControl(hero.thtd_emoji_effect, 3, Vector(1,0,0))
|
||||
ParticleManager:DestroyParticleSystemTime(hero.thtd_emoji_effect,5.0)
|
||||
return
|
||||
end
|
||||
|
||||
if GameRules.PlayerData[playerid]["point"] == nil or GameRules.PlayerData[playerid]["point"] < keys.point then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner() , "display_custom_error", {msg="not_enough_game_point"} )
|
||||
return
|
||||
end
|
||||
|
||||
caster:EmitSound(reimu_pet_sound[RandomInt(1, #reimu_pet_sound)])
|
||||
Service:BuyMagicKey(playerid, 1)
|
||||
end
|
||||
|
||||
local model_tree =
|
||||
{
|
||||
-- "maps/journey_assets/props/trees/journey_armandpine/journey_armandpine_01.vmdl",
|
||||
-- "maps/journey_assets/props/trees/journey_armandpine/journey_armandpine_02.vmdl",
|
||||
-- "maps/journey_assets/props/trees/journey_maple/journey_maple02.vmdl",
|
||||
-- "maps/jungle_assets/trees/kapok/export/kapok_002.vmdl",
|
||||
-- "maps/jungle_assets/trees/kapok/export/kapok_003.vmdl",
|
||||
-- "maps/jungle_assets/trees/kapok/export/kapok_004.vmdl",
|
||||
-- "models/props_tree/dire_tree006.vmdl",
|
||||
-- "models/props_tree/palm_01.vmdl",
|
||||
-- "models/props_tree/palm_02b.vmdl",
|
||||
-- "models/props_tree/palm_02c.vmdl",
|
||||
-- "models/props_tree/palm_03_inspector.vmdl",
|
||||
"models/props_tree/frostivus_tree.vmdl", -- 圣诞树
|
||||
-- "models/props_tree/newbloom_tree.vmdl", -- 新春树
|
||||
}
|
||||
|
||||
function OnSpellStartReimuPet05(keys)
|
||||
local caster = keys.caster
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
caster:EmitSound("UI.Aowu")
|
||||
|
||||
if targetPoint.y > 415 and targetPoint.y < 2000 then
|
||||
local y = 2000
|
||||
if (2000-targetPoint.y) > (targetPoint.y-415) then y = 415 end
|
||||
targetPoint = Vector(targetPoint.x, y, targetPoint.z)
|
||||
elseif targetPoint.y > -2000 and targetPoint.y < -415 then
|
||||
local y = -2000
|
||||
if math.abs(-2000-targetPoint.y) > math.abs(-415-targetPoint.y) then y = -415 end
|
||||
targetPoint = Vector(targetPoint.x, y, targetPoint.z)
|
||||
end
|
||||
if targetPoint.x > 3755 and targetPoint.x < 4470 then
|
||||
targetPoint = Vector(3755, targetPoint.y, targetPoint.z)
|
||||
elseif targetPoint.x < -3755 and targetPoint.x > -4470 then
|
||||
targetPoint = Vector(-3755, targetPoint.y, targetPoint.z)
|
||||
end
|
||||
|
||||
if GetDistanceBetweenTwoVec2D(caster:GetAbsOrigin(), targetPoint) <= 200 then
|
||||
caster.pet_point = nil
|
||||
if caster.pet_tree ~= nil then UTIL_Remove(caster.pet_tree) end
|
||||
caster.pet_tree = nil
|
||||
else
|
||||
caster.pet_point = targetPoint
|
||||
if caster.pet_tree ~= nil then UTIL_Remove(caster.pet_tree) end
|
||||
caster.pet_tree = CreateTempTreeWithModel(targetPoint, 36000, model_tree[RandomInt(1, #model_tree)])
|
||||
end
|
||||
end
|
||||
|
||||
function ShowCourierEffect(hero,type)
|
||||
if hero.flyup_effect ~= nil then
|
||||
ParticleManager:DestroyParticle(hero.flyup_effect,true)
|
||||
end
|
||||
if hero.ground_effect ~= nil then
|
||||
ParticleManager:DestroyParticle(hero.ground_effect,true)
|
||||
end
|
||||
|
||||
local key = table.getkey(reimu_pet_model, hero.model_index)
|
||||
|
||||
if type == 1 then
|
||||
--陆地特效
|
||||
if key ~= nil and courier_ground_effect_list[key] ~= nil then
|
||||
--陆地特效
|
||||
local ground_effect = courier_ground_effect_list[key]
|
||||
hero.ground_effect = PlayParticleOnUnitUntilDeath({
|
||||
caster = hero,
|
||||
p = ground_effect,
|
||||
})
|
||||
end
|
||||
end
|
||||
if type == 2 then
|
||||
--飞行特效
|
||||
if key ~= nil and courier_flyup_effect_list[key] ~= nil then
|
||||
--飞行特效
|
||||
local flyup_effect = courier_flyup_effect_list[key]
|
||||
hero.flyup_effect = PlayParticleOnUnitUntilDeath({
|
||||
caster = hero,
|
||||
p = flyup_effect,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PlayParticleOnUnitUntilDeath(keys)
|
||||
local p = keys.p
|
||||
local u = keys.caster
|
||||
if u == nil then
|
||||
return
|
||||
end
|
||||
local pos = keys.pos or PATTACH_ABSORIGIN_FOLLOW
|
||||
local pp = ParticleManager:CreateParticle(p, pos, u)
|
||||
ParticleManager:SetParticleControlEnt( pp, 0, u, pos, nil, u:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( pp, 1, u, pos, nil, u:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( pp, 2, u, pos, nil, u:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( pp, 3, u, pos, nil, u:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( pp, 4, u, pos, nil, u:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( pp, 5, u, pos, nil, u:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( pp, 6, u, pos, nil, u:GetOrigin(), true );
|
||||
|
||||
u:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if u == nil or u:IsNull() == true or u:IsAlive() == false then
|
||||
if pp ~= nil then
|
||||
ParticleManager:DestroyParticle(pp,true)
|
||||
end
|
||||
return
|
||||
end
|
||||
if pp == nil then
|
||||
return
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0.1)
|
||||
|
||||
return pp
|
||||
end
|
||||
|
||||
|
||||
function SetCourier(hero, onduty_hero, onduty_hero_effect)
|
||||
local onduty_hero_model = GameRules:GetGameModeEntity().sm_hero_list[onduty_hero]
|
||||
local onduty_hero_skin = GameRules:GetGameModeEntity().sm_hero_list_skin[onduty_hero] or 0
|
||||
hero:SetOriginalModel(onduty_hero_model)
|
||||
hero:SetModel(onduty_hero_model)
|
||||
hero:SetSkin(onduty_hero_skin)
|
||||
hero.init_model_scale = GameRules:GetGameModeEntity().sm_hero_size[onduty_hero] or 1
|
||||
hero:SetModelScale(hero.init_model_scale)
|
||||
hero.ori_model = onduty_hero_model
|
||||
hero.ori_skin = onduty_hero_skin
|
||||
if hero.effect ~= nil then
|
||||
hero:RemoveAbility(hero.effect)
|
||||
hero:RemoveModifierByName('modifier_texiao_star')
|
||||
end
|
||||
if onduty_hero_effect ~= 'e000' then
|
||||
if string.find(GameRules:GetGameModeEntity().effect_list,onduty_hero_effect) then
|
||||
AddAbilityAndSetLevel(hero,onduty_hero_effect)
|
||||
hero.effect = onduty_hero_effect
|
||||
end
|
||||
end
|
||||
ShowCourierEffect(hero,1)
|
||||
hero.onduty_hero = onduty_hero
|
||||
end
|
||||
146
scripts/vscripts/abilities/abilityreisen.lua
Executable file
146
scripts/vscripts/abilities/abilityreisen.lua
Executable file
@@ -0,0 +1,146 @@
|
||||
function OnReisen01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
ReisenRepelUnit(caster, target)
|
||||
end
|
||||
|
||||
function ReisenRepelUnit(caster, target)
|
||||
if target.thtd_is_fearing == true then return end
|
||||
if target.next_move_point ~= nil and target.thtd_is_feared_by_reisen_01 ~= true then
|
||||
|
||||
target.thtd_is_feared_by_reisen_01 = true
|
||||
target.thtd_is_fearing = true
|
||||
local current_next_move_point = target.next_move_point
|
||||
|
||||
target.next_move_point = target:GetOrigin() - target:GetForwardVector() * 500
|
||||
|
||||
target:EmitSound("Hero_Sniper.ProjectileImpact")
|
||||
|
||||
local count = 20
|
||||
target:SetContextThink(DoUniqueString("thtd_reisen01_move_next_point"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if not IsValidAlive(target) then
|
||||
return nil
|
||||
end
|
||||
count = count - 1
|
||||
if count <= 0 or THTD_IsValid(caster) == false then
|
||||
target.next_move_point = current_next_move_point
|
||||
target.thtd_is_fearing = false
|
||||
return nil
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
|
||||
function OnReisen02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_reisen_02_illusion_count == nil then
|
||||
caster.thtd_reisen_02_illusion_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_reisen_02_illusion_count < keys.max_count and RollPercentage(keys.chance) then
|
||||
caster:EmitSound("Sound_THTD.thtd_reisen_02")
|
||||
local illusion = CreateUnitByName(
|
||||
"reisen_illusion",
|
||||
caster:GetOrigin() + RandomVector(150),
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
illusion.thtd_spawn_unit_owner = caster
|
||||
illusion:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
||||
local count = 0
|
||||
keys.ability:ApplyDataDrivenModifier(caster, illusion, "modifier_reisen_02_illusion", nil)
|
||||
illusion:SetBaseDamageMax(caster:THTD_GetAttack())
|
||||
illusion:SetBaseDamageMin(caster:THTD_GetAttack())
|
||||
illusion:MoveToPositionAggressive(illusion:GetOrigin() + illusion:GetForwardVector() * 100)
|
||||
illusion:SetContextThink(DoUniqueString("thtd_reisen02_illusion"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count > 20 then
|
||||
illusion:AddNoDraw()
|
||||
illusion:ForceKill(true)
|
||||
caster.thtd_reisen_02_illusion_count = caster.thtd_reisen_02_illusion_count - 1
|
||||
return nil
|
||||
end
|
||||
count = count + 1
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
caster.thtd_reisen_02_illusion_count = caster.thtd_reisen_02_illusion_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
function OnReisen03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_reisen_03")
|
||||
|
||||
if caster.thtd_reisen_02_illusion_count == nil then
|
||||
caster.thtd_reisen_02_illusion_count = 0
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + caster.thtd_reisen_02_illusion_count * keys.damage_up/100)
|
||||
local playerid = caster:GetPlayerOwnerID()
|
||||
if GameRules.player_bb_buff[playerid]["item_3030"] > 0 then
|
||||
damage = damage * (1 + GameRules.player_bb_buff[playerid]["item_3030"]/100)
|
||||
end
|
||||
for k,v in pairs(targets) do
|
||||
Reisen03RepelUnit(caster, v)
|
||||
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
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_reisen/ability_reisen_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,2.0)
|
||||
end
|
||||
|
||||
function Reisen03RepelUnit(caster, target)
|
||||
if target.thtd_is_fearing == true then return end
|
||||
if target.next_move_point ~= nil then
|
||||
target.thtd_is_feared_by_reisen_01 = true
|
||||
target.thtd_is_fearing = true
|
||||
local current_next_move_point = target.next_move_point
|
||||
|
||||
target.next_move_point = target:GetOrigin() - target:GetForwardVector() * 500
|
||||
|
||||
target:EmitSound("Hero_Sniper.ProjectileImpact")
|
||||
|
||||
local count = 20
|
||||
target:SetContextThink(DoUniqueString("thtd_reisen01_move_next_point"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if not IsValidAlive(target) then
|
||||
return nil
|
||||
end
|
||||
count = count - 1
|
||||
if count <= 0 or THTD_IsValid(caster) == false then
|
||||
target.next_move_point = current_next_move_point
|
||||
target.thtd_is_fearing = false
|
||||
return nil
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
254
scripts/vscripts/abilities/abilityremilia.lua
Executable file
254
scripts/vscripts/abilities/abilityremilia.lua
Executable file
@@ -0,0 +1,254 @@
|
||||
function OnRemilia01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local ability = keys.ability
|
||||
local targetPoint = keys.target:GetOrigin()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_remilia/ability_remilia_03_end.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
effectIndex = ParticleManager:CreateParticle("particles/heroes/moluo/abiilty_moluo_014.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
|
||||
local powerBonus = #targets * keys.power_bonus
|
||||
local duration_time = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
|
||||
for k,target in pairs(targets) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/moluo/ability_moluo01_explosion_vip.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 2, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 2, caster:GetForwardVector())
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 5, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 7, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 10, caster, 5, "follow_origin", Vector(0,0,0), true)
|
||||
|
||||
local crit = 1
|
||||
if target:HasModifier("modifier_remilia_03_debuff") then
|
||||
crit = 10
|
||||
end
|
||||
|
||||
local damage_table={
|
||||
ability = ability,
|
||||
victim=target,
|
||||
attacker=caster,
|
||||
damage=damage * crit,
|
||||
damage_type=ability:GetAbilityDamageType(),
|
||||
damage_flags=ability:GetAbilityTargetFlags()
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
OnRemilia02SpellStart(caster)
|
||||
end
|
||||
|
||||
if powerBonus > 0 then
|
||||
caster:THTD_AddBasePower(powerBonus)
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:THTD_AddBasePower(-powerBonus)
|
||||
return nil
|
||||
end,
|
||||
duration_time)
|
||||
end
|
||||
end
|
||||
|
||||
function OnRemilia02SpellStart(caster)
|
||||
local step = caster:GetAbilityValue("thtd_remilia_02", "damage_up")
|
||||
local maxUp = caster:GetAbilityValue("thtd_remilia_02", "max_up")
|
||||
local duration = caster:GetAbilityValue("thtd_remilia_02", "duration_time")
|
||||
|
||||
if caster.thtd_remilia_02_outgoing == nil then
|
||||
caster.thtd_remilia_02_outgoing = 0
|
||||
end
|
||||
|
||||
local count = math.min(step, maxUp - caster.thtd_remilia_02_outgoing)
|
||||
if count > 0 then
|
||||
caster:AddDamageOutgoingMagical(count)
|
||||
caster.thtd_remilia_02_outgoing = caster.thtd_remilia_02_outgoing + count
|
||||
caster:SetContextThink(DoUniqueString("modifier_reimilia_02_buff_count"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
caster:AddDamageOutgoingMagical(-count)
|
||||
caster.thtd_remilia_02_outgoing = caster.thtd_remilia_02_outgoing - count
|
||||
return nil
|
||||
end,
|
||||
duration)
|
||||
end
|
||||
end
|
||||
|
||||
function OnRemilia03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = keys.target_points[1]
|
||||
local forward = (keys.target_points[1] - caster:GetOrigin()):Normalized()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/remilia/ability_remilia_03_spark.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin() + Vector(forward.x * 92,forward.y * 92,150))
|
||||
ParticleManager:SetParticleControl(effectIndex, 8, Vector(forward.x,forward.y,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_remilia/ability_remilia_03_end.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/remilia/ability_remilia_01.vpcf",
|
||||
vSpawnOrigin = caster:GetOrigin()+Vector(0,0,30),
|
||||
fDistance = keys.distance,
|
||||
fStartRadius = 300,
|
||||
fEndRadius = 300,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = forward * 4000,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
function OnRemilia03SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/remilia/ability_remilia_01_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 5, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
if caster.thtd_remilia_03_chance_count == nil then
|
||||
caster.thtd_remilia_03_chance_count = 0
|
||||
end
|
||||
|
||||
local chance = caster:GetAbilityValue("thtd_remilia_04", "chance")
|
||||
local success = RollPercentage(chance)
|
||||
if caster.thtd_remilia_03_chance_count >= 100/chance then
|
||||
success = true
|
||||
end
|
||||
if success then
|
||||
caster.thtd_remilia_03_chance_count = 0
|
||||
else
|
||||
caster.thtd_remilia_03_chance_count = caster.thtd_remilia_03_chance_count + 1
|
||||
end
|
||||
|
||||
local damage = 0
|
||||
local ability4 = caster:FindAbilityByName("thtd_remilia_04")
|
||||
if ability4:GetLevel() > 0 and success then
|
||||
damage = ability4:GetSpecialValueFor("power_damage_03") * caster:THTD_GetStarDamage()
|
||||
if not target:HasModifier("modifier_remilia_03_debuff") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_remilia_03_debuff",nil)
|
||||
end
|
||||
else
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
end
|
||||
|
||||
local crit = 1
|
||||
if target:HasModifier("modifier_remilia_03_debuff") then
|
||||
crit = 10
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
amage_flags = keys.ability:GetAbilityTargetFlags()
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
OnRemilia02SpellStart(caster)
|
||||
end
|
||||
|
||||
function OnRemilia03Created(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
target:RemoveMagicalResist()
|
||||
target:RemovePhysicalArmor()
|
||||
|
||||
local bonus = caster:GetAbilityValue("thtd_remilia_04", "damage_up")
|
||||
target:AddDamageIncomingPhysical(bonus, "thtd_remilia_03_damage_up")
|
||||
target:AddDamageIncomingMagical(bonus, "thtd_remilia_03_damage_up")
|
||||
end
|
||||
|
||||
function OnRemilia03Destroy(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.unit
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/remilia/ability_remilia_04_laser.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint+Vector(0,0,700))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(800,0,800))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, targetPoint+Vector(0,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetPoint+Vector(-800,0,800))
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, targetPoint+Vector(0,0,1600))
|
||||
ParticleManager:SetParticleControl(effectIndex, 6, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local effectIndexSmoke = ParticleManager:CreateParticle("particles/heroes/remilia/ability_remilia_04_laser_rocket.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 0, targetPoint+Vector(0,0,700))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 1, Vector(1,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 2, Vector(-1,0,0))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 3, Vector(0,0,0.5))
|
||||
ParticleManager:SetParticleControl(effectIndexSmoke, 4, Vector(0,0,-1))
|
||||
ParticleManager:DestroyParticleSystem(effectIndexSmoke,false)
|
||||
|
||||
local ability = caster:FindAbilityByName("thtd_remilia_04")
|
||||
local time = math.floor(ability:GetSpecialValueFor("duration_time") * 100 + 0.5) / 100
|
||||
local tick = math.floor(ability:GetSpecialValueFor("tick_time") * 100 + 0.5) / 100
|
||||
local range = ability:GetSpecialValueFor("range")
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_remilia_04")
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_remilia_03_effect_destroy"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
if not THTD_IsValid(caster) then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndexSmoke,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(ability)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,range)
|
||||
for k,v in pairs(targets) do
|
||||
local crit = 1
|
||||
if v:HasModifier("modifier_remilia_03_debuff") then
|
||||
crit = 10
|
||||
end
|
||||
local damage_table={
|
||||
ability = ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = ability:GetAbilityDamageType(),
|
||||
damage_flags = ability:GetAbilityTargetFlags()
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
OnRemilia02SpellStart(caster)
|
||||
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
111
scripts/vscripts/abilities/abilityrin.lua
Executable file
111
scripts/vscripts/abilities/abilityrin.lua
Executable file
@@ -0,0 +1,111 @@
|
||||
function OnRin01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target:GetOrigin()
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_rin_01")
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/rin/ability_rin_01.vpcf",
|
||||
vSpawnOrigin = targetPoint,
|
||||
fDistance = 1000,
|
||||
fStartRadius = 400,
|
||||
fEndRadius = 400,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = -keys.target:GetForwardVector() * 1500,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
|
||||
Rin01Wheel(keys)
|
||||
end
|
||||
|
||||
function Rin01Wheel(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local origin = keys.target:GetOrigin()
|
||||
local forward = -keys.target:GetForwardVector()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/rin/ability_rin_01_projectile.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, origin)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0 , forward)
|
||||
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("ability_rin_01_wheel_move"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count < 23 then
|
||||
origin = origin + forward * 45
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, origin)
|
||||
count = count + 1
|
||||
else
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
return nil
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03)
|
||||
end
|
||||
|
||||
function OnRin01ProjectileHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
if target~=nil and target:IsNull()== false and target:IsAlive() and target:HasModifier("modifier_rin_01_debuff")==false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_rin_01_debuff", nil)
|
||||
end
|
||||
end
|
||||
|
||||
function OnRin01Death(keys)
|
||||
if keys.caster_entindex==nil then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.unit
|
||||
|
||||
if caster:FindAbilityByName("thtd_rin_02"):GetLevel() < 1 then return end
|
||||
|
||||
target:EmitSound("Hero_Nevermore.Shadowraze")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/moluo/abiilty_moluo_014.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local hp_damage = caster:GetAbilityValue("thtd_rin_02", "hp_damage", true)
|
||||
local power_damage = caster:GetAbilityValue("thtd_rin_02", "power_damage")
|
||||
local range = caster:GetAbilityValue("thtd_rin_02", "range")
|
||||
|
||||
local damage = math.min(target:GetMaxHealth() * hp_damage, caster:THTD_GetStarDamage()*power_damage)
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),range)
|
||||
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
|
||||
end
|
||||
343
scripts/vscripts/abilities/abilityrumia.lua
Executable file
343
scripts/vscripts/abilities/abilityrumia.lua
Executable file
@@ -0,0 +1,343 @@
|
||||
function OnRumia01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnRumia01Kill(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.rumia_01_bonus == nil then
|
||||
caster.rumia_01_bonus = 0
|
||||
end
|
||||
|
||||
if caster:IsPower999() then
|
||||
if caster.rumia_01_bonus < keys.max_bonus * 10 then
|
||||
caster.rumia_01_bonus = caster.rumia_01_bonus + 1
|
||||
caster:THTD_AddBasePower(1)
|
||||
end
|
||||
else
|
||||
if caster.rumia_01_bonus < keys.max_bonus then
|
||||
caster.rumia_01_bonus = caster.rumia_01_bonus + 1
|
||||
caster:THTD_AddBasePower(1)
|
||||
elseif caster.rumia_01_bonus > keys.max_bonus then
|
||||
caster:THTD_AddBasePower(-(caster.rumia_01_bonus - keys.max_bonus))
|
||||
caster.rumia_01_bonus = keys.max_bonus
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnRumia02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
if caster.rumia_02_attack_count == nil then
|
||||
caster.rumia_02_attack_count = 0
|
||||
end
|
||||
|
||||
local powerCount = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_rumia_02")
|
||||
if pv ~= nil then
|
||||
powerCount = pv[1]
|
||||
end
|
||||
|
||||
caster.rumia_02_attack_count = caster.rumia_02_attack_count + 1
|
||||
|
||||
if caster.rumia_02_attack_count >= (keys.max_count - powerCount) then
|
||||
RumiaProjectileStart(keys)
|
||||
caster.rumia_02_attack_count = 0
|
||||
end
|
||||
end
|
||||
|
||||
function RumiaProjectileStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_rumia_01")
|
||||
|
||||
for i=1,12 do
|
||||
local forwardCos = caster:GetForwardVector().x
|
||||
local forwardSin = caster:GetForwardVector().y
|
||||
local angle = (39 - 6.5 * i) / 180 * math.pi
|
||||
local forward = Vector( math.cos(angle)*forwardCos - math.sin(angle)*forwardSin,
|
||||
forwardSin*math.cos(angle) + forwardCos*math.sin(angle),0)
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/rumia/ability_rumia_02_projectile.vpcf",
|
||||
vSpawnOrigin = caster:GetOrigin() + forward * 500 - caster:GetForwardVector() * 500 + Vector(0,0,128),
|
||||
fDistance = 800,
|
||||
fStartRadius = 150,
|
||||
fEndRadius = 150,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = true,
|
||||
vVelocity = caster:GetForwardVector() * 1800,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
if caster:THTD_IsTowerEx() == true then
|
||||
info.EffectName = "particles/heroes/rumia/ability_rumia_02_ex_projectile.vpcf"
|
||||
end
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
end
|
||||
|
||||
function OnRumiaProjectileHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 1)
|
||||
|
||||
if caster:THTD_IsTowerEx() == true then
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability, 2)
|
||||
end
|
||||
|
||||
if caster:IsPower666() then damage = damage * 10 end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnRumia03AttackLanded(keys)
|
||||
if keys.ability:GetLevel()<1 then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
if target.thtd_damage_lock == true then return end
|
||||
|
||||
if target:GetHealthPercent() > 70 and RollPercentage(keys.chance) then
|
||||
local targetPoint = target:GetOrigin()
|
||||
keys.ability:ApplyDataDrivenModifier(caster,target,"modifier_rumia_03_pause",{})
|
||||
local pointRad = GetRadBetweenTwoVec2D(caster:GetOrigin(),targetPoint)
|
||||
local randomPi = -2*math.pi
|
||||
|
||||
if RandomInt(0,1) == 0 then
|
||||
randomPi = -2*math.pi
|
||||
else
|
||||
randomPi = 2*math.pi
|
||||
end
|
||||
|
||||
local forwardVec = Vector(math.cos(pointRad+randomPi), math.sin(pointRad+randomPi),RandomFloat(0,1))
|
||||
local projectileTable = {
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_rumia/ability_rumia_03.vpcf",
|
||||
vSpawnOrigin = caster:GetOrigin(),
|
||||
vSpawnOriginNew = caster:GetOrigin(),
|
||||
fDistance = 5000,
|
||||
fStartRadius = 60,
|
||||
fEndRadius = 60,
|
||||
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 = true,
|
||||
vVelocity = forwardVec,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 400,
|
||||
iVisionTeamNumber = caster:GetTeamNumber(),
|
||||
}
|
||||
|
||||
local speed = 4000
|
||||
local acceleration = -400
|
||||
local iVelocity = 1000
|
||||
local ishit = false
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle(projectileTable.EffectName, PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControlForward(effectIndex,3,(projectileTable.vVelocity*iVelocity/50 + speed/50 * (targetPoint - caster:GetOrigin()):Normalized()):Normalized())
|
||||
|
||||
local ability = projectileTable.Ability
|
||||
local targets = {}
|
||||
local targets_remove = {}
|
||||
local totalDistance = 0
|
||||
local time = 0
|
||||
local high = 0
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_caster_projectile"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
-- 向心力单位向量
|
||||
local vecCentripetal = (projectileTable.vSpawnOriginNew - targetPoint):Normalized()
|
||||
|
||||
-- 向心力
|
||||
local forceCentripetal = speed/50
|
||||
|
||||
-- 初速度单位向量
|
||||
local vecInVelocity = projectileTable.vVelocity
|
||||
|
||||
-- 初始力
|
||||
local forceIn = iVelocity/50
|
||||
|
||||
-- 投射物矢量
|
||||
local vecProjectile = vecInVelocity * forceIn + forceCentripetal * vecCentripetal
|
||||
|
||||
local vec = projectileTable.vSpawnOriginNew + vecProjectile + Vector(0,0,high)
|
||||
|
||||
-- 投射物单位向量
|
||||
local particleForward = vecProjectile:Normalized()
|
||||
|
||||
-- 目标和投射物距离
|
||||
local dis = GetDistanceBetweenTwoVec2D(targetPoint,vec)
|
||||
|
||||
ParticleManager:SetParticleControlForward(effectIndex,3,particleForward)
|
||||
|
||||
totalDistance = totalDistance + math.sqrt(forceIn*forceIn + forceCentripetal*forceCentripetal)
|
||||
|
||||
if(dis<400)then
|
||||
if ishit == false then
|
||||
ishit = true
|
||||
target:StartGesture(ACT_DOTA_FLAIL)
|
||||
end
|
||||
high = high + 25
|
||||
target:SetAbsOrigin(projectileTable.vSpawnOriginNew+400*Vector(forwardVec.x,forwardVec.y,0)-Vector(0,0,50))
|
||||
end
|
||||
|
||||
if(dis<projectileTable.fEndRadius)then
|
||||
if(projectileTable.bDeleteOnHit)then
|
||||
OnRumia03AbilityEnd(caster,target,keys.ability,effectIndex,time)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
if(totalDistance<projectileTable.fDistance and dis>=projectileTable.fEndRadius)then
|
||||
ParticleManager:SetParticleControl(effectIndex,3,vec)
|
||||
projectileTable.vSpawnOriginNew = vec
|
||||
speed = speed + acceleration
|
||||
time = time + 0.02
|
||||
return 0.02
|
||||
else
|
||||
if func then func(projectileTable.vSpawnOriginNew) end
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0.02)
|
||||
end
|
||||
end
|
||||
|
||||
function OnRumia03AbilityEnd(caster,target,ability,effectIndex,time)
|
||||
caster:SetContextThink(DoUniqueString("ability_caster_projectile_END"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
target:RemoveModifierByName("modifier_rumia_03_pause")
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
local effectIndexEnd = ParticleManager:CreateParticle("particles/heroes/thtd_rumia/ability_rumia_04_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndexEnd, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndexEnd, 3, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndexEnd,false)
|
||||
target:SetContextThink(DoUniqueString("ability_caster_projectile_END"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if THTD_IsValid(target) then
|
||||
FindClearSpaceForUnit(target, target:GetOrigin(), false)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
0.2)
|
||||
caster:AbilityKill(target, ability)
|
||||
if caster.rumia_01_bonus == nil then
|
||||
caster.rumia_01_bonus = 0
|
||||
end
|
||||
if caster.rumia_01_bonus < caster:GetAbilityValue("thtd_rumia_01", "max_bonus") then
|
||||
caster.rumia_01_bonus = caster.rumia_01_bonus + 1
|
||||
caster:THTD_AddBasePower(1)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
1.5 - time)
|
||||
end
|
||||
|
||||
function Rumia04AttackTargetPoint(keys)
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local pointRad = GetRadBetweenTwoVec2D(vecCaster,target:GetOrigin())
|
||||
|
||||
local randomPi = RandomFloat(-2*math.pi,2*math.pi)
|
||||
local forwardVec = Vector(math.cos(pointRad+randomPi), math.sin(pointRad+randomPi),RandomFloat(0,1))
|
||||
|
||||
local BulletTable = {
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_rumia/ability_rumia_04.vpcf",
|
||||
vSpawnOrigin = vecCaster,
|
||||
vSpawnOriginNew = vecCaster,
|
||||
fDistance = 5000,
|
||||
fStartRadius = 60,
|
||||
fEndRadius = 60,
|
||||
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 = true,
|
||||
vVelocity = forwardVec,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 400,
|
||||
iVisionTeamNumber = caster:GetTeamNumber(),
|
||||
}
|
||||
|
||||
local speed = 2000
|
||||
local acc = 200
|
||||
local iVelo = 1000
|
||||
|
||||
CreateProjectileMoveToPoint(BulletTable,caster,target:GetOrigin(),speed,iVelo,-acc,
|
||||
function(vec)
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_rumia_04")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
local targetpoint = Vector(vec.x,vec.y,caster:GetOrigin().z)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetpoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
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)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_rumia/ability_rumia_04_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetpoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetpoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
)
|
||||
end
|
||||
239
scripts/vscripts/abilities/abilitysakuya.lua
Executable file
239
scripts/vscripts/abilities/abilitysakuya.lua
Executable file
@@ -0,0 +1,239 @@
|
||||
function OnSakuya01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_sakuya_01")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
caster.power_damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
|
||||
if caster:IsPower666() then
|
||||
caster.power_damage = caster.power_damage * 4
|
||||
end
|
||||
|
||||
if caster:IsPower999() then
|
||||
caster.power_damage = caster.power_damage * 12
|
||||
end
|
||||
|
||||
if caster.thtd_sakuya_03_casted == true then
|
||||
caster.power_damage = caster.power_damage * (1 - caster:GetAbilityValue("thtd_sakuya_03", "damage_down")/100)
|
||||
end
|
||||
|
||||
local rad = GetRadBetweenTwoVec2D(caster:GetOrigin(),targetPoint)
|
||||
local forward = Vector(math.cos(rad),math.sin(rad),caster:GetForwardVector().z)
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/thd2/heroes/sakuya/ability_sakuya_01.vpcf",
|
||||
vSpawnOrigin = caster:GetOrigin() + Vector(0,0,128),
|
||||
fDistance = 1000,
|
||||
fStartRadius = 150,
|
||||
fEndRadius = 150,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = forward * 2000,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
|
||||
local count = keys.max_count
|
||||
|
||||
for i=1,count do
|
||||
local iVec = Vector( math.cos(rad + math.pi/36*(i+0.5)) * 2000 , math.sin(rad + math.pi/36*(i+0.5)) * 2000 , caster:GetForwardVector().z )
|
||||
info.vVelocity = iVec
|
||||
projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
iVec = Vector( math.cos(rad - math.pi/36*(i+0.5)) * 2000 , math.sin(rad - math.pi/36*(i+0.5)) * 2000 , caster:GetForwardVector().z )
|
||||
info.vVelocity = iVec
|
||||
projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
end
|
||||
|
||||
function OnSakuya01ProjectileHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster.power_damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
local sakuya_02_black_list =
|
||||
{
|
||||
"thtd_lily_01",
|
||||
"thtd_daiyousei_01",
|
||||
"thtd_koishi_04",
|
||||
"thtd_sakuya_02",
|
||||
"thtd_sakuya_03",
|
||||
"thtd_yuuka_04",
|
||||
"thtd_yukari_03",
|
||||
"thtd_yukari_04",
|
||||
"thtd_flandre_01",
|
||||
"thtd_mokou_03",
|
||||
"thtd_eirin_03",
|
||||
"thtd_patchouli_04",
|
||||
"thtd_hatate_02",
|
||||
"thtd_sanae_03",
|
||||
"thtd_minamitsu_02",
|
||||
"thtd_minamitsu_03",
|
||||
"thtd_toramaru_01",
|
||||
"thtd_toramaru_02",
|
||||
"thtd_toramaru_03",
|
||||
"thtd_kanako_04",
|
||||
"thtd_sanae_04",
|
||||
"thtd_miko_04",
|
||||
"thtd_keine_01",
|
||||
"thtd_keine_03",
|
||||
"thtd_suika_04",
|
||||
"thtd_yuugi_03",
|
||||
"thtd_alice_03",
|
||||
"shinki_dragon_01",
|
||||
"thtd_kagerou_03",
|
||||
"death_prophet_exorcism",
|
||||
"thtd_letty_01",
|
||||
"thtd_suwako_04",
|
||||
"thtd_komachi_04",
|
||||
"thtd_junko_03",
|
||||
"thtd_junko_04",
|
||||
"thtd_clownpiece_03",
|
||||
"thtd_kyouko_02",
|
||||
"thtd_shikieiki_04",
|
||||
"thtd_shinki_03",
|
||||
|
||||
}
|
||||
|
||||
function IsInSakuya02BlackList(ability)
|
||||
for k,v in pairs(sakuya_02_black_list) do
|
||||
if ability:GetAbilityName() == v then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function OnSakuya02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = keys.target:GetOrigin()
|
||||
-- local cooldown = keys.ability:GetCooldown(keys.ability:GetLevel() - 1) --获取当前等级的冷却时间
|
||||
local cooldown = keys.ability:GetCooldownTimeRemaining() -- 或者 keys.ability:GetCooldownTime() 技能当前实际冷却时间
|
||||
if keys.ability:GetLevel() >= 2 then
|
||||
local unitName = target:GetUnitName()
|
||||
if unitName == "remilia" or unitName == "flandre" or unitName == "patchouli" or unitName == "sakuya" or unitName == "koakuma" or unitName == "meirin" then
|
||||
cooldown = cooldown * 0.5
|
||||
keys.ability:EndCooldown()
|
||||
keys.ability:StartCooldown(cooldown)
|
||||
end
|
||||
end
|
||||
|
||||
if target:THTD_IsTower() and target:HasModifier("modifier_sakuya_02_buff") == false then
|
||||
caster.thtd_last_cast_unit = target
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_sakuya_02_buff", {duration=cooldown})
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/items/item_pocket_watch.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
for i=2,5 do
|
||||
local ability = target:GetAbilityByIndex(i)
|
||||
if ability~=nil and IsInSakuya02BlackList(ability) == false then
|
||||
ability:EndCooldown()
|
||||
target:GiveMana(target:GetRealManaCost(ability))
|
||||
end
|
||||
end
|
||||
|
||||
if caster == target then
|
||||
target:THTD_AddManaRegenPercentage(keys.mana_reg)
|
||||
caster:SetContextThink(DoUniqueString("ability_reimu_03"),
|
||||
function()
|
||||
if target~=nil and target:IsNull()==false and target:IsAlive() then
|
||||
target:THTD_AddManaRegenPercentage(-keys.mana_reg)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
cooldown-0.2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnSakuya03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local powerCd = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_sakuya_03")
|
||||
if pv ~= nil then
|
||||
powerCd = pv[1]
|
||||
end
|
||||
if powerCd > 0 then
|
||||
caster:ReCooldown(keys.ability, powerCd)
|
||||
end
|
||||
|
||||
local duration = math.floor(100 * keys.duration_time + 0.5) / 100
|
||||
local range = keys.range
|
||||
local pauseUnit = {}
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/muyue/ability_muyue_014_aeons.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(range,range,range))
|
||||
|
||||
caster.thtd_sakuya_03_casted = true
|
||||
caster:SetContextThink(DoUniqueString("ability_reimu_03"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
|
||||
if duration < 0 or THTD_IsValid(caster) == false then
|
||||
for k,v in pairs(pauseUnit) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
v:RemoveModifierByName("modifier_sakuya_03_time_pause_debuff")
|
||||
end
|
||||
end
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
pauseUnit = {}
|
||||
caster.thtd_sakuya_03_casted = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),range)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
if v:HasModifier("modifier_sakuya_03_time_pause_debuff") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_sakuya_03_time_pause_debuff", nil)
|
||||
pauseUnit[v:GetEntityIndex()] = v
|
||||
end
|
||||
end
|
||||
|
||||
if caster:GetMana() < caster:GetMaxMana() then
|
||||
caster:SetMana(caster:GetMaxMana())
|
||||
end
|
||||
|
||||
local ability = caster:FindAbilityByName("thtd_sakuya_01")
|
||||
local unit = targets[1]
|
||||
if unit ~= nil and unit:IsNull() == false and ability:IsFullyCastable() then
|
||||
caster:CastAbilityOnPosition(unit:GetOrigin(), ability, caster:GetPlayerOwnerID())
|
||||
end
|
||||
|
||||
duration = duration - 0.1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
271
scripts/vscripts/abilities/abilitysanae.lua
Executable file
271
scripts/vscripts/abilities/abilitysanae.lua
Executable file
@@ -0,0 +1,271 @@
|
||||
thtd_sanae_01 = class({})
|
||||
|
||||
LinkLuaModifier("modifier_sanae_01", "abilities/abilitySanae", LUA_MODIFIER_MOTION_NONE)
|
||||
|
||||
function thtd_sanae_01:OnSpellStart()
|
||||
local caster = self:GetCaster()
|
||||
local target = self:GetCursorTarget()
|
||||
|
||||
-- AI需要改动的地方
|
||||
caster.thtd_last_cast_unit = target
|
||||
|
||||
local ExtraData = {
|
||||
count=0
|
||||
}
|
||||
|
||||
self:Sanae01PassToNextUnit(caster,caster:GetOrigin(),target,ExtraData)
|
||||
end
|
||||
|
||||
|
||||
function thtd_sanae_01:Sanae01PassToNextUnit(source,loction,target,data)
|
||||
local caster = self:GetCaster()
|
||||
|
||||
local info =
|
||||
{
|
||||
Target = target,
|
||||
Source = source,
|
||||
Ability = self,
|
||||
EffectName = "particles/heroes/sanae/ability_sanae_01.vpcf",
|
||||
iMoveSpeed = 1400,
|
||||
vSourceLoc= loction, -- 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,
|
||||
iVisionRadius = 400,
|
||||
iVisionTeamNumber = caster:GetTeamNumber(),
|
||||
ExtraData = {
|
||||
count = data.count + 1
|
||||
}
|
||||
}
|
||||
projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
end
|
||||
|
||||
|
||||
function thtd_sanae_01:OnProjectileHit_ExtraData(hTarget, vLocation, data)
|
||||
local caster = self:GetCaster()
|
||||
local target = hTarget
|
||||
|
||||
if target:THTD_IsTower() and target.thtd_sanae_01_power_bonus == nil then
|
||||
local duration_time = self:GetSpecialValueFor("duration_time")
|
||||
target.thtd_sanae_01_power_bonus = math.max(1, math.floor(self:GetSpecialValueFor("power_bonus") * (1 - self:GetSpecialValueFor("down_percent")/100)^(data.count - 1)))
|
||||
target:AddNewModifier(caster, self, "modifier_sanae_01", {duration = duration_time})
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/sanae/ability_sanae_01_effect.vpcf", PATTACH_CUSTOMORIGIN, target)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, duration_time)
|
||||
end
|
||||
|
||||
if data.count < self:GetSpecialValueFor("max_count") then
|
||||
local targets =
|
||||
FindUnitsInRadius(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
nil,
|
||||
self:GetSpecialValueFor("range"),
|
||||
self:GetAbilityTargetTeam(),
|
||||
self:GetAbilityTargetType(),
|
||||
self:GetAbilityTargetFlags(),
|
||||
FIND_ANY_ORDER,
|
||||
false
|
||||
)
|
||||
for k,v in pairs(targets) do
|
||||
if v~=nil and v~=target and v:THTD_IsTower() and v:HasModifier("modifier_sanae_01") == false then
|
||||
self:Sanae01PassToNextUnit(target,vLocation,v,data)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
modifier_sanae_01 = class({})
|
||||
|
||||
function modifier_sanae_01:OnCreated( kv )
|
||||
if IsServer() then
|
||||
local target = self:GetParent()
|
||||
target:THTD_AddBasePower(target.thtd_sanae_01_power_bonus)
|
||||
end
|
||||
end
|
||||
|
||||
function modifier_sanae_01:OnDestroy()
|
||||
if IsServer() then
|
||||
local target = self:GetParent()
|
||||
target:THTD_AddBasePower(-target.thtd_sanae_01_power_bonus)
|
||||
target.thtd_sanae_01_power_bonus = nil
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function OnSanae02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_sanae/ability_sanae_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, keys.duration_time)
|
||||
|
||||
effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_sanae/ability_sanae_02_p.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, keys.duration_time)
|
||||
|
||||
local time = keys.duration_time
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_patchouli04_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster, targetPoint, keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_sanae_debuff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_sanae_debuff", {duration=0.2})
|
||||
else
|
||||
modifier:SetDuration(0.2,false)
|
||||
end
|
||||
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
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnSanae03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local time = keys.duration_time
|
||||
|
||||
local vec = targetPoint + RandomVector(keys.range)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_sanae_03/ability_sanae_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 5, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 6, vec)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_patchouli04_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,vec,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + caster:THTD_GetFaith() * keys.damage_up/100)
|
||||
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)
|
||||
UnitStunTarget(caster,v, keys.stun_time * (1 + caster:THTD_GetFaith() * keys.stun_up/100))
|
||||
end
|
||||
vec = targetPoint + RandomVector(keys.range)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_sanae_03/ability_sanae_03.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 5, vec)
|
||||
ParticleManager:SetParticleControl(effectIndex, 6, vec)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnSanae04SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/sanae/ability_sanea_04_effect_b.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex, keys.duration_time)
|
||||
|
||||
if keys.ability:GetLevel() < 2 then return end
|
||||
|
||||
local hero = GameRules.HeroList[caster:GetPlayerOwnerID()]
|
||||
if hero == nil then return end
|
||||
for k,v in pairs(hero.thtd_hero_tower_list) do
|
||||
local unitName = v:GetUnitName()
|
||||
if unitName == "sanae" or unitName == "kanako" or unitName == "suwako" then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_sanae_04_buff", nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedSanae04Buff(keys)
|
||||
keys.target:THTD_AddBasePower(keys.power_bonus * keys.target:THTD_GetFaith()/3, "thtd_sanae_04_buff")
|
||||
end
|
||||
|
||||
function OnDestroySanae04Buff(keys)
|
||||
keys.target:THTD_AddBasePower("thtd_sanae_04_buff")
|
||||
end
|
||||
|
||||
function OnSanae04Created(keys)
|
||||
-- local caster = EntIndexToHScript(keys.caster_entindex) 与下面一样
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
local unitName = target:GetUnitName()
|
||||
if unitName == "sanae" or unitName == "kanako" or unitName == "suwako" then
|
||||
if not target:HasModifier("modifier_sanae_04_combo_buff") then
|
||||
local modifier = keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_sanae_04_combo_buff", nil)
|
||||
local hero = GameRules.HeroList[caster:GetPlayerOwnerID()]
|
||||
if hero ~= nil and hero.thtd_ss_faith ~= nil and hero.thtd_ss_faith > 0 then
|
||||
modifier:SetStackCount(hero.thtd_ss_faith)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnSanae04Destroy(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
local unitName = target:GetUnitName()
|
||||
if unitName == "sanae" or unitName == "kanako" or unitName == "suwako" then
|
||||
if target:HasModifier("modifier_sanae_04_combo_buff") then
|
||||
target:RemoveModifierByName("modifier_sanae_04_combo_buff")
|
||||
end
|
||||
if target:HasModifier("modifier_sanae_04_buff") then
|
||||
target:RemoveModifierByName("modifier_sanae_04_buff")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedSanae04ComboBuff(keys)
|
||||
keys.target:THTD_AddBasePower(math.floor(keys.target:THTD_GetFaith()/3), "thtd_sanae_04_combo_buff", "thtd_sanae_04_combo_buff")
|
||||
end
|
||||
|
||||
function OnDestroySanae04ComboBuff(keys)
|
||||
keys.target:THTD_AddBasePower("thtd_sanae_04_combo_buff")
|
||||
end
|
||||
|
||||
function OnSanaeKill(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
caster:THTD_AddFaith()
|
||||
end
|
||||
77
scripts/vscripts/abilities/abilitysatori.lua
Executable file
77
scripts/vscripts/abilities/abilitysatori.lua
Executable file
@@ -0,0 +1,77 @@
|
||||
local thtd_satori_02 =
|
||||
{
|
||||
[4] = 0.4,
|
||||
[5] = 1.0,
|
||||
}
|
||||
|
||||
function OnSatori01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_satori_02")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
if caster:IsPower666() then
|
||||
powerDamage = powerDamage + 400
|
||||
end
|
||||
local limit = 100 * (1 + powerDamage/100)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_satori_01")
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_satori_01_debuff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_satori_01_debuff", {Duration=keys.duration_time})
|
||||
else
|
||||
modifier:SetDuration(keys.duration_time,false)
|
||||
end
|
||||
|
||||
local ability_02 = caster:FindAbilityByName("thtd_satori_02")
|
||||
if ability_02 ~= nil and ability_02:GetLevel() > 0 and v.thtd_satori_02_debuff ~= true then
|
||||
v.thtd_satori_02_debuff = true
|
||||
local health = v:GetHealth()
|
||||
local time = 3.0
|
||||
v:SetContextThink(DoUniqueString("thtd_satori02_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if not THTD_IsValid(v) then return nil end
|
||||
if time <= 0 then
|
||||
local damage = math.min(limit * caster:THTD_GetStarDamage(), (health - v:GetHealth()) * ability_02:GetSpecialValueFor("damage_percent") / 100)
|
||||
local DamageTable = {
|
||||
ability = ability_02,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = ability_02:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
v.thtd_satori_02_debuff = false
|
||||
return nil
|
||||
end
|
||||
time = time - 0.1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnSatori01ModifierCreated(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster:HasModifier("modifier_thtd_satori_02_combo_buff") and target.thtd_satori_01_debuff ~= true then
|
||||
target.thtd_satori_01_debuff = true
|
||||
local bonus = caster:GetAbilityValue("thtd_satori_02", "damage_up")
|
||||
target:AddDamageIncomingPhysical(bonus, "thtd_satori_01_damage_up")
|
||||
end
|
||||
end
|
||||
|
||||
function OnSatori01ModifierDestroy(keys)
|
||||
keys.target:AddDamageIncomingPhysical("thtd_satori_01_damage_up")
|
||||
end
|
||||
139
scripts/vscripts/abilities/abilityseiga.lua
Executable file
139
scripts/vscripts/abilities/abilityseiga.lua
Executable file
@@ -0,0 +1,139 @@
|
||||
local Seiga01ItemDrop =
|
||||
{
|
||||
[1] =
|
||||
{
|
||||
["item_1011"] = 1,
|
||||
["item_1012"] = 0,
|
||||
["item_1013"] = 0,
|
||||
["item_1014"] = 0,
|
||||
},
|
||||
[2] =
|
||||
{
|
||||
["item_1011"] = 2,
|
||||
["item_1012"] = 0,
|
||||
["item_1013"] = 0,
|
||||
["item_1014"] = 0,
|
||||
},
|
||||
[3] =
|
||||
{
|
||||
["item_1011"] = 2,
|
||||
["item_1012"] = 1,
|
||||
["item_1013"] = 0,
|
||||
["item_1014"] = 0,
|
||||
},
|
||||
[4] =
|
||||
{
|
||||
["item_1011"] = 0,
|
||||
["item_1012"] = 2,
|
||||
["item_1013"] = 1,
|
||||
["item_1014"] = 0,
|
||||
},
|
||||
[5] =
|
||||
{
|
||||
["item_1011"] = 0,
|
||||
["item_1012"] = 0,
|
||||
["item_1013"] = 2,
|
||||
["item_1014"] = 1,
|
||||
},
|
||||
}
|
||||
|
||||
function OnSeiga01Death(keys)
|
||||
if keys.caster==nil or keys.caster:IsNull() or keys.caster:IsAlive()==false then
|
||||
return
|
||||
end
|
||||
|
||||
local caster = keys.caster
|
||||
local target = keys.unit
|
||||
|
||||
if SpawnSystem.IsUnLimited or GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then
|
||||
if caster:HasModifier("modifier_miko_02_buff") and caster.thtd_miko_buff_seiga ~= nil then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_seiga/ability_seiga_03.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),caster:GetAbilityValue("thtd_seiga_03", "range"))
|
||||
local damage = THTD_GetTempleOfGodBuffedTowerStarCount(caster) * caster:THTD_GetPower() * caster.thtd_miko_buff_seiga
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
else
|
||||
if caster.thtd_chance_count == nil then
|
||||
caster.thtd_chance_count = {}
|
||||
end
|
||||
local hero = caster:GetOwner()
|
||||
local count = 0
|
||||
for itemName,chance in pairs(Seiga01ItemDrop[caster:THTD_GetStar()]) do
|
||||
if chance > 0 then
|
||||
if caster.thtd_chance_count[itemName] == nil then
|
||||
caster.thtd_chance_count[itemName] = 0
|
||||
end
|
||||
local randChance = chance
|
||||
if caster.thtd_chance_count[itemName] >= math.floor(100/randChance) then
|
||||
randChance = 100
|
||||
end
|
||||
if RollPercentage(randChance) then
|
||||
caster.thtd_chance_count[itemName] = 0
|
||||
local item = CreateItem(itemName, nil, nil)
|
||||
item.owner_player_id = caster:GetPlayerOwnerID()
|
||||
item:SetPurchaser(hero)
|
||||
item:SetPurchaseTime(1.0)
|
||||
local pos = GetSpawnLineOffsetVector(hero.spawn_index, hero.spawn_position, count * 130, 150)
|
||||
CreateItemOnPositionSync(pos,item)
|
||||
else
|
||||
caster.thtd_chance_count[itemName] = caster.thtd_chance_count[itemName] + 1
|
||||
end
|
||||
end
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnSeiga02SpellStart(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
|
||||
if target:THTD_IsTower() and target:IsInAttackSpeedBlackList() == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_seiga_02_attack_speed_buff", {})
|
||||
caster.thtd_last_cast_unit = target
|
||||
end
|
||||
end
|
||||
|
||||
function OnSeiga03Death(keys)
|
||||
if keys.caster==nil or keys.caster:IsNull() or keys.caster:IsAlive()==false then
|
||||
return
|
||||
end
|
||||
if keys.ability:GetLevel()<1 then return end
|
||||
|
||||
local caster = keys.caster
|
||||
local target = keys.unit
|
||||
|
||||
local count = target:GetPoisonCount()
|
||||
if count > 0 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_seiga/ability_seiga_03.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * count
|
||||
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
|
||||
end
|
||||
end
|
||||
185
scripts/vscripts/abilities/abilityshikieiki.lua
Executable file
185
scripts/vscripts/abilities/abilityshikieiki.lua
Executable file
@@ -0,0 +1,185 @@
|
||||
function OnSpellStartShikieiki01(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),keys.range)
|
||||
|
||||
if GameRules:GetGameTime() - (caster.thtd_shikieiki_01_sound or 0) > 12 then
|
||||
caster.thtd_shikieiki_01_sound = GameRules:GetGameTime()
|
||||
caster:EmitSound("Hero_Chen.PenitenceCast")
|
||||
caster:EmitSound("Hero_Chen.PenitenceImpact")
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/shikieiki/ability_shikieiki_01_guilty.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, v, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, false)
|
||||
|
||||
local modifier = v:FindModifierByName(keys.modifier)
|
||||
if modifier == nil then
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster, v, keys.modifier, nil)
|
||||
modifier:SetStackCount(RandomInt(1, 3))
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/shikieiki/ability_shikieiki_01_guilty_b.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 0, v, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 1, v:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex2, 2, v:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex2, 3, v:GetOrigin())
|
||||
v.thtd_shikieiki_01_count_effect = effectIndex2
|
||||
else
|
||||
local count = modifier:GetStackCount()
|
||||
if count < 10 then
|
||||
modifier:SetStackCount(math.min(10, count + RandomInt(1, 3)))
|
||||
end
|
||||
end
|
||||
if modifier ~= nil then
|
||||
ParticleManager:SetParticleControl(v.thtd_shikieiki_01_count_effect, 1, Vector(0,modifier:GetStackCount(),0))
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
|
||||
function OnDestroyShikieiki01Debuff(keys)
|
||||
local target = keys.target
|
||||
ParticleManager:DestroyParticleSystem(target.thtd_shikieiki_01_count_effect, true)
|
||||
end
|
||||
|
||||
function OnSpellStartShikieiki02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),keys.range)
|
||||
|
||||
local count = 0
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_omniknight/omniknight_purification.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1,1,1))
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, Vector(0,0,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, false)
|
||||
|
||||
local modifier = v:FindModifierByName(keys.modifier)
|
||||
local crit = 1
|
||||
if modifier ~= nil then
|
||||
count = count + modifier:GetStackCount()
|
||||
crit = 1 + modifier:GetStackCount() * keys.damage_up/100
|
||||
modifier:Destroy()
|
||||
end
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * crit,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
if count > 0 then
|
||||
caster.thtd_shikieiki_02_power_bonus = count * keys.power_bonus
|
||||
caster:RemoveModifierByName("modifier_shikieiki_02_buff")
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_shikieiki_02_buff", {})
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedShikieiki02Buff(keys)
|
||||
keys.target:THTD_AddBasePower(keys.target.thtd_shikieiki_02_power_bonus, "thtd_shikieiki_02_buff")
|
||||
end
|
||||
|
||||
function OnDestroyShikieiki02Buff(keys)
|
||||
keys.target:THTD_AddBasePower("thtd_shikieiki_02_buff")
|
||||
end
|
||||
|
||||
function OnCreatedShikieiki03Debuff(keys)
|
||||
local caster = keys.caster
|
||||
local target = keys.target
|
||||
local effectIndex = ParticleManager:CreateParticle(
|
||||
"particles/heroes/shikieiki/ability_shikieiki_04.vpcf",
|
||||
PATTACH_CUSTOMORIGIN,
|
||||
target)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 4, target, 5, "follow_origin", Vector(0,0,0), true)
|
||||
target.thtd_shikieiki_03_effect = effectIndex
|
||||
|
||||
if not keys.ability:GetAutoCastState() then
|
||||
caster:EmitSound("Voice_Thdots_Shikieiki.AbilityShikieiki04")
|
||||
end
|
||||
end
|
||||
|
||||
function OnIntervalThinkShikieiki03(keys)
|
||||
UnitDamageHpRemove(keys.caster, keys.target, keys.hp_damage, false)
|
||||
end
|
||||
|
||||
function OnDestroyShikieiki03Debuff(keys)
|
||||
ParticleManager:DestroyParticleSystem(keys.target.thtd_shikieiki_03_effect, true)
|
||||
end
|
||||
|
||||
function OnSpellStartShikieiki04(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/enigma/enigma_world_chasm/enigma_blackhole_ti5.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
|
||||
caster:EmitSound("Hero_Enigma.Black_Hole")
|
||||
|
||||
local time = keys.duration_time
|
||||
local tick = 0.05
|
||||
local count = 0
|
||||
local damage_tick = math.floor(keys.tick * 100 + 0.5)/100
|
||||
local damage_count = math.floor(damage_tick/tick)
|
||||
caster:SetContextThink(DoUniqueString("thtd_shikieiki_04"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
count = count + 1
|
||||
if time < 0 or THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex, true)
|
||||
caster:StopSound("Hero_Enigma.Black_Hole")
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
local damage = 0
|
||||
if count%damage_count == 0 then
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
end
|
||||
|
||||
for k, v in pairs(targets) do
|
||||
local distance = (v:GetAbsOrigin() - targetPoint):Length2D()
|
||||
local in_pull = 400
|
||||
local new_pos = GetGroundPosition(RotatePosition(targetPoint, QAngle(0,1.5,0), v:GetAbsOrigin()), v)
|
||||
if distance > 20 then
|
||||
local direction = (targetPoint - new_pos):Normalized()
|
||||
direction.z = 0.0
|
||||
new_pos = new_pos + direction * in_pull * tick
|
||||
end
|
||||
v:SetOrigin(new_pos)
|
||||
|
||||
if damage > 0 then
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
time = time - tick
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
|
||||
395
scripts/vscripts/abilities/abilityshinki.lua
Executable file
395
scripts/vscripts/abilities/abilityshinki.lua
Executable file
@@ -0,0 +1,395 @@
|
||||
-- 是否魔界
|
||||
function IsMakaiCard(unit)
|
||||
local unitName = unit:GetUnitName()
|
||||
if unitName == "shinki" or unitName == "alice" or unitName == "koakuma" or unitName == "mima" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function OnShinki01Think(keys)
|
||||
local caster = keys.caster
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(caster,caster:GetOrigin(),1200)
|
||||
for k,v in pairs(targets) do
|
||||
if IsMakaiCard(v) then
|
||||
local modifier = v:FindModifierByName(keys.modifier)
|
||||
if modifier ~= nil then
|
||||
modifier:SetDuration(0.3, false)
|
||||
else
|
||||
if v.thtd_shinki_01_kill_count == nil then
|
||||
v.thtd_shinki_01_kill_count = 0
|
||||
end
|
||||
modifier = keys.ability:ApplyDataDrivenModifier(caster, v, keys.modifier, {duration = 0.3})
|
||||
if modifier ~= nil and v.thtd_shinki_01_kill_count > 0 then
|
||||
modifier:SetStackCount(v.thtd_shinki_01_kill_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedShinki01Buff(keys)
|
||||
keys.target:THTD_AddBasePower(keys.kill_bonus * keys.target.thtd_shinki_01_kill_count, "thtd_shinki_01_kill")
|
||||
end
|
||||
|
||||
function OnDestroyShinki01Buff(keys)
|
||||
keys.target:THTD_AddBasePower("thtd_shinki_01_kill")
|
||||
end
|
||||
|
||||
function OnSpellStartShinki02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local castPoint = caster:GetOrigin()
|
||||
-- local effect = "particles/econ/items/queen_of_pain/qop_arcana/qop_arcana_sonic_wave.vpcf"
|
||||
local effect = "particles/econ/items/queen_of_pain/qop_arcana/qop_arcana_sonic_wave_v2.vpcf"
|
||||
local range = keys.ability:GetCastRange()
|
||||
for i=1,6 do
|
||||
local forward = Vector(math.cos(i*math.pi/3),math.sin(i*math.pi/3),0)
|
||||
local effectIndex = ParticleManager:CreateParticle(effect, PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, castPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward * (range/2))
|
||||
ParticleManager:ReleaseParticleIndex(effectIndex)
|
||||
-- local info =
|
||||
-- {
|
||||
-- Ability = keys.ability,
|
||||
-- EffectName = effect,
|
||||
-- vSpawnOrigin = castPoint,
|
||||
-- fDistance = range,
|
||||
-- fStartRadius = 100,
|
||||
-- fEndRadius = 500,
|
||||
-- Source = caster,
|
||||
-- iSourceAttachment = "mouth",
|
||||
-- bHasFrontalCone = false,
|
||||
-- bReplaceExisting = false,
|
||||
-- iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
-- iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
-- iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
-- fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
-- bDeleteOnHit = false,
|
||||
-- vVelocity = forward * 1400,
|
||||
-- bProvidesVision = false,
|
||||
-- ExtraData = {}
|
||||
-- }
|
||||
-- ProjectileManager:CreateLinearProjectile(info)
|
||||
end
|
||||
|
||||
local tick = math.floor(keys.tick * 100 + 0.5)/100
|
||||
local time = math.floor(keys.duration_time * 100 + 0.5)/100
|
||||
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
time = time - tick
|
||||
if time < 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,castPoint,range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local type = keys.ability:GetAbilityDamageType()
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = type,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
return tick
|
||||
end,
|
||||
tick)
|
||||
end
|
||||
|
||||
function OnSpellStartShinki03(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:HasModifier(keys.modifier) then
|
||||
caster:RemoveModifierByName(keys.modifier)
|
||||
end
|
||||
local modifier = keys.ability:ApplyDataDrivenModifier(caster, caster, keys.modifier, nil)
|
||||
|
||||
local pfx_caster = ParticleManager:CreateParticle("particles/units/heroes/heroes_underlord/abbysal_underlord_darkrift_ambient.vpcf", PATTACH_ABSORIGIN_FOLLOW, caster)
|
||||
ParticleManager:SetParticleControlEnt(pfx_caster, 2, caster, PATTACH_ABSORIGIN_FOLLOW, nil, caster:GetAbsOrigin(), true)
|
||||
ParticleManager:SetParticleControl(pfx_caster, 1, Vector(0, 0, 0))
|
||||
modifier:AddParticle(pfx_caster, false, false, 15, false, false)
|
||||
|
||||
-- caster:EmitSound("Hero_Nevermore.ROS.Arcana.Cast")
|
||||
caster:EmitSound("Hero_Terrorblade.Metamorphosis")
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/terrorblade/terrorblade_back_ti8/terrorblade_sunder_ti8.vpcf", PATTACH_ROOTBONE_FOLLOW, caster)
|
||||
-- ParticleManager:SetParticleControlEnt(effectIndex, 0, caster, PATTACH_ROOTBONE_FOLLOW, "follow_rootbone", caster:GetAbsOrigin(), true)
|
||||
-- ParticleManager:SetParticleControlEnt(effectIndex, 1, caster, PATTACH_ROOTBONE_FOLLOW, "follow_rootbone", caster:GetAbsOrigin(), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex, 0, caster, PATTACH_ROOTBONE_FOLLOW, "follow_origin", caster:GetAbsOrigin(), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex, 1, caster, PATTACH_ROOTBONE_FOLLOW, "follow_origin", caster:GetAbsOrigin(), true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnCreatedShinki03Buff(keys)
|
||||
local target = keys.target
|
||||
target:SetModelScale(target:GetModelScale() * 2)
|
||||
target:THTD_AddBasePower(keys.power_bonus, "thtd_shinki_03_bonus")
|
||||
target:THTD_DestroyLevelEffect()
|
||||
end
|
||||
|
||||
function OnDestroyShinki03Buff(keys)
|
||||
local target = keys.target
|
||||
target:SetModelScale(target:GetModelScale() / 2)
|
||||
target:THTD_AddBasePower("thtd_shinki_03_bonus")
|
||||
target:THTD_CreateLevelEffect()
|
||||
end
|
||||
|
||||
|
||||
local baseModel = 1.0
|
||||
|
||||
function OnShinki04Spawn(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local entities = Entities:FindAllByClassname("npc_dota_creature")
|
||||
for k,v in pairs(entities) do
|
||||
local findNum = string.find(v:GetUnitName(), 'shinki_dragon')
|
||||
if findNum ~= nil and v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
local c = v.thtd_spawn_unit_owner
|
||||
if c:GetOwner() == caster:GetOwner() then
|
||||
CustomGameEventManager:Send_ServerToPlayer(caster:GetPlayerOwner(), "display_custom_error", {msg="shinki_dragon_casted"})
|
||||
keys.ability:EndCooldown()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if caster.ability_shinki04_devour_count == nil then
|
||||
caster.ability_shinki04_devour_count = 0
|
||||
end
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"shinki_dragon"
|
||||
,caster:GetOrigin() + caster:GetForwardVector() * 500
|
||||
,false
|
||||
,caster:GetOwner()
|
||||
,caster:GetOwner()
|
||||
,caster:GetTeam()
|
||||
)
|
||||
if unit == nil then
|
||||
keys.ability:EndCooldown()
|
||||
return
|
||||
end
|
||||
FindClearSpaceForUnit(unit, unit:GetOrigin(), false)
|
||||
|
||||
unit:SetModelScale(baseModel * (1 + caster.ability_shinki04_devour_count * 0.02))
|
||||
|
||||
unit:SetControllableByPlayer(caster:GetPlayerOwnerID(), false)
|
||||
unit:SetHasInventory(false)
|
||||
unit.thtd_spawn_unit_owner = caster
|
||||
|
||||
local powerStack = math.max(0, math.min(3, caster:GetTowerPowerLevel()))
|
||||
local hero = caster:GetOwner()
|
||||
if GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"] > 0 or powerStack > 0 then
|
||||
unit:AddNewModifier(unit, nil, "modifier_bb_buff_3016_effect", nil):SetStackCount(GameRules.player_bb_buff[hero.thtd_player_id]["item_3016"] + powerStack)
|
||||
end
|
||||
|
||||
local ability = unit:GetAbilityByIndex(0)
|
||||
if ability ~= nil then
|
||||
ability:SetActivated(true)
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
ability = unit:GetAbilityByIndex(1)
|
||||
if ability ~= nil then
|
||||
ability:SetActivated(true)
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
ability = unit:GetAbilityByIndex(2)
|
||||
if ability ~= nil then
|
||||
ability:SetActivated(true)
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
|
||||
ability = unit:FindAbilityByName("shinki_dragon_01")
|
||||
if ability ~= nil then
|
||||
if caster.ability_shinki04_devour_count > 0 then
|
||||
ability:ApplyDataDrivenModifier(unit, unit, "modifier_shinki_dragon_01_buff", nil)
|
||||
unit:SetModifierStackCount("modifier_shinki_dragon_01_buff", unit, caster.ability_shinki04_devour_count)
|
||||
end
|
||||
local modifier = caster:FindModifierByName("modifier_shinki_dragon_01_cooldown")
|
||||
if modifier ~= nil then
|
||||
ability:StartCooldown(modifier:GetDuration())
|
||||
end
|
||||
end
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, unit, "modifier_shinki_04_buff", nil)
|
||||
|
||||
local oldSwpanUnit = caster.thtd_summon_unit
|
||||
if oldSwpanUnit ~=nil and oldSwpanUnit:IsNull() == false then
|
||||
oldSwpanUnit:AddNoDraw()
|
||||
oldSwpanUnit:ForceKill(false)
|
||||
end
|
||||
caster.thtd_summon_unit = unit
|
||||
|
||||
local factor = unit:GetAbilityValue("shinki_dragon_01", "damage_up", true)
|
||||
local attackValue = math.floor(caster:THTD_GetStarDamage() * (1 + caster.ability_shinki04_devour_count * factor))
|
||||
unit:SetBaseDamageMax(attackValue)
|
||||
unit:SetBaseDamageMin(attackValue)
|
||||
|
||||
unit:SetContextThink(DoUniqueString("modifier_shinki_04"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster==nil or caster:IsNull() or caster:IsAlive()==false or caster:THTD_IsHidden() then
|
||||
unit:AddNoDraw()
|
||||
unit:ForceKill(false)
|
||||
caster.thtd_summon_unit = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
attackValue = math.floor(caster:THTD_GetStarDamage() * (1 + caster.ability_shinki04_devour_count * factor))
|
||||
unit:SetBaseDamageMax(attackValue)
|
||||
unit:SetBaseDamageMin(attackValue)
|
||||
|
||||
unit:InheritOwnerBuff(caster)
|
||||
|
||||
if GetDistanceBetweenTwoVec2D(caster:GetOrigin(), unit:GetOrigin()) > 1000 then
|
||||
local forward = (unit:GetAbsOrigin() - caster:GetAbsOrigin()):Normalized()
|
||||
unit:MoveToPosition(caster:GetOrigin() + forward*1000)
|
||||
end
|
||||
|
||||
enemy = unit:GetAttackTarget()
|
||||
|
||||
ability = unit:FindAbilityByName("shinki_dragon_01")
|
||||
if unit:IsReadyToCastAbility(ability) and enemy ~= nil and enemy.thtd_damage_lock ~= true then
|
||||
if enemy~=nil and enemy:IsNull()==false and enemy:IsAlive() then
|
||||
unit:CastAbilityOnTarget(enemy, ability, caster:GetPlayerOwnerID())
|
||||
end
|
||||
end
|
||||
|
||||
ability = unit:FindAbilityByName("shinki_dragon_03")
|
||||
if unit:IsReadyToCastAbility(ability) then
|
||||
if enemy~=nil and enemy:IsNull()==false and enemy:IsAlive() then
|
||||
unit:CastAbilityNoTarget(ability, caster:GetPlayerOwnerID())
|
||||
end
|
||||
end
|
||||
|
||||
return math.floor(100/unit:GetAttacksPerSecond()) / 100
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
|
||||
function OnShinkiDragon01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local owner = caster.thtd_spawn_unit_owner
|
||||
if owner==nil or owner:IsNull() or owner:IsAlive()==false or owner:THTD_IsHidden() then return end
|
||||
if target.thtd_damage_lock == true then return end
|
||||
|
||||
local cooldown = math.floor(target:GetHealth() / caster:GetAverageTrueAttackDamage(caster))
|
||||
cooldown = math.min(600, math.max(15, cooldown))
|
||||
keys.ability:ApplyDataDrivenModifier(owner, owner, "modifier_shinki_dragon_01_cooldown", {Duration = cooldown})
|
||||
keys.ability:StartCooldown(cooldown)
|
||||
|
||||
caster:NpcKill(target)
|
||||
|
||||
local max_count = keys.max_count
|
||||
if owner:IsPower999() then max_count = 999 end
|
||||
|
||||
if owner.ability_shinki04_devour_count < max_count then
|
||||
local skipedCount = 0
|
||||
if SpawnSystem.ReachToWave ~= nil then
|
||||
if owner.skiped_wave == nil then
|
||||
owner.skiped_wave = SpawnSystem.ReachToWave + 50 - SpawnSystem.CurWave - 1
|
||||
end
|
||||
elseif owner.skiped_wave ~= nil then
|
||||
skipedCount = owner.skiped_wave * 2
|
||||
owner.skiped_wave = nil
|
||||
end
|
||||
local addCount = math.min(max_count - owner.ability_shinki04_devour_count, 1 + skipedCount)
|
||||
|
||||
owner.ability_shinki04_devour_count = owner.ability_shinki04_devour_count + addCount
|
||||
caster:SetModelScale(baseModel * (1 + math.min(3, owner.ability_shinki04_devour_count * 0.02)))
|
||||
if not caster:HasModifier("modifier_shinki_dragon_01_buff") then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, caster, "modifier_shinki_dragon_01_buff", nil)
|
||||
end
|
||||
caster:SetModifierStackCount("modifier_shinki_dragon_01_buff", caster, owner.ability_shinki04_devour_count)
|
||||
elseif owner.ability_shinki04_devour_count > max_count then
|
||||
owner.ability_shinki04_devour_count = max_count
|
||||
caster:SetModelScale(baseModel * (1 + math.min(3, owner.ability_shinki04_devour_count * 0.02)))
|
||||
caster:SetModifierStackCount("modifier_shinki_dragon_01_buff", caster, owner.ability_shinki04_devour_count)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnShinki02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local owner = caster.thtd_spawn_unit_owner
|
||||
if owner==nil or owner:IsNull() or owner:IsAlive()==false or owner:THTD_IsHidden() then return end
|
||||
local target = keys.target
|
||||
|
||||
if RollPercentage(keys.chance) then
|
||||
local enemies = THTD_FindUnitsInRadius(owner, target:GetOrigin(), keys.range)
|
||||
local damage = caster:GetAverageTrueAttackDamage(caster)
|
||||
local isEnabledStun = false
|
||||
if caster.stun_locked ~= true then
|
||||
isEnabledStun = true
|
||||
caster.stun_locked = true
|
||||
caster:SetContextThink(DoUniqueString("modifier_shinki_04"),
|
||||
function()
|
||||
caster.stun_locked = false
|
||||
return nil
|
||||
end,
|
||||
1.0)
|
||||
end
|
||||
if #enemies > 0 then
|
||||
for k,v in pairs(enemies) do
|
||||
if isEnabledStun then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_bash_stun_datadriven", {Duration = keys.stun_time})
|
||||
end
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
if v == target then
|
||||
DamageTable.damage = DamageTable.damage * keys.damage_crit
|
||||
else
|
||||
DamageTable.damage = DamageTable.damage * keys.aoe_crit
|
||||
end
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
caster:EmitSound("Hero_Slardar.Bash")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnShinkiDragon03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local owner = caster.thtd_spawn_unit_owner
|
||||
if owner==nil or owner:IsNull() or owner:IsAlive()==false or owner:THTD_IsHidden() then return end
|
||||
|
||||
local crit = 1
|
||||
if owner:IsPower666() then
|
||||
crit = 4
|
||||
keys.ability:EndCooldown()
|
||||
keys.ability:StartCooldown(1.0)
|
||||
end
|
||||
|
||||
local enemies = THTD_FindUnitsInRadius(owner, caster:GetOrigin(), keys.RangeRadius)
|
||||
local damage = caster:GetAverageTrueAttackDamage(caster) * keys.DamageTimes * crit
|
||||
local debuff = "modifier_earthshock_debuff_datadriven"
|
||||
if #enemies > 0 then
|
||||
for k,v in pairs(enemies) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, debuff, {})
|
||||
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
|
||||
end
|
||||
end
|
||||
15
scripts/vscripts/abilities/abilitysizuha.lua
Executable file
15
scripts/vscripts/abilities/abilitysizuha.lua
Executable file
@@ -0,0 +1,15 @@
|
||||
function OnSizuha02StarImprove(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target:THTD_IsTower() and target:GetUnitName()~=caster:GetUnitName() and target:THTD_GetStar() < caster:THTD_GetStar() and target:GetUnitName() ~= "minoriko" and target:GetUnitName() ~= "sizuha" then
|
||||
target:THTD_SetStar(target:THTD_GetStar()+1)
|
||||
target:THTD_SetLevel(THTD_MAX_LEVEL)
|
||||
|
||||
caster.thtd_is_changed = true
|
||||
caster.thtd_star = caster:THTD_GetStar() - 1
|
||||
caster:THTD_OpenAbility()
|
||||
caster:THTD_DestroyLevelEffect()
|
||||
caster:THTD_CreateLevelEffect()
|
||||
end
|
||||
end
|
||||
403
scripts/vscripts/abilities/abilitysoga.lua
Executable file
403
scripts/vscripts/abilities/abilitysoga.lua
Executable file
@@ -0,0 +1,403 @@
|
||||
function OnSoga01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster:HasModifier("modifier_miko_02_buff") and caster.thtd_miko_buff_soga01 ~= nil then
|
||||
caster:ReCooldown(keys.ability, caster.thtd_miko_buff_soga01)
|
||||
end
|
||||
|
||||
if caster.thtd_soga_01_effect_list == nil then
|
||||
caster.thtd_soga_01_effect_list = {}
|
||||
end
|
||||
|
||||
if caster.thtd_soga_01_rect_last ~= nil then
|
||||
for index,point in pairs(caster.thtd_soga_01_rect_last) do
|
||||
local forward = (point - caster:GetAbsOrigin()):Normalized()
|
||||
|
||||
for i=1,math.floor(keys.length/100) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin() + 100 * i * forward)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, caster:GetOrigin() + 100 * i * forward)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_01_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + keys.length * forward,
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
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)
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
|
||||
for k,v in pairs(caster.thtd_soga_01_effect_list) do
|
||||
ParticleManager:DestroyParticleSystem(v,true)
|
||||
end
|
||||
caster.thtd_soga_01_effect_list = {}
|
||||
caster.thtd_soga_01_rect_last = {}
|
||||
return nil
|
||||
end,
|
||||
0.2)
|
||||
end
|
||||
else
|
||||
caster.thtd_soga_01_rect_last = {}
|
||||
end
|
||||
|
||||
local forward = (targetPoint - caster:GetAbsOrigin()):Normalized()
|
||||
|
||||
for i=1,math.floor(keys.length/100) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin() + 100 * i * forward)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, caster:GetOrigin() + 100 * i * forward)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_01_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + 800 * forward,
|
||||
nil,
|
||||
200,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
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)
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
|
||||
table.insert(caster.thtd_soga_01_rect_last,targetPoint)
|
||||
|
||||
for i=1,8 do
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_thtd_soga_lightning.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, caster:GetOrigin() + 100 * i * forward)
|
||||
table.insert(caster.thtd_soga_01_effect_list,effectIndex2)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnSoga02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_soga_02_effect_list == nil then
|
||||
caster.thtd_soga_02_effect_list = {}
|
||||
end
|
||||
|
||||
if caster.thtd_soga_02_rect_last ~= nil then
|
||||
for index,point in pairs(caster.thtd_soga_02_rect_last) do
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_02_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, point)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
return nil
|
||||
end,
|
||||
0.5)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_02_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * keys.damage_down/100
|
||||
local targets = THTD_FindUnitsInRadius(caster,point,keys.range)
|
||||
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
|
||||
for k,v in pairs(caster.thtd_soga_02_effect_list) do
|
||||
ParticleManager:DestroyParticleSystem(v,true)
|
||||
end
|
||||
caster.thtd_soga_02_effect_list = {}
|
||||
caster.thtd_soga_02_rect_last = {}
|
||||
return nil
|
||||
end,
|
||||
0.7)
|
||||
end
|
||||
else
|
||||
caster.thtd_soga_02_rect_last = {}
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_02_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
return nil
|
||||
end,
|
||||
0.5)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_02_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
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
|
||||
|
||||
for i=1,12 do
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_thtd_soga_lightning.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, targetPoint+Vector(math.cos(i*math.pi*2/12),math.sin(i*math.pi*2/12),0)*keys.range)
|
||||
table.insert(caster.thtd_soga_02_effect_list,effectIndex2)
|
||||
end
|
||||
|
||||
table.insert(caster.thtd_soga_02_rect_last,targetPoint)
|
||||
return nil
|
||||
end,
|
||||
0.7)
|
||||
|
||||
end
|
||||
|
||||
function OnSoga03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster:HasModifier("modifier_miko_02_buff") and caster.thtd_miko_buff_soga03 ~= nil then
|
||||
caster:ReCooldown(keys.ability, caster.thtd_miko_buff_soga03)
|
||||
end
|
||||
|
||||
if caster.thtd_soga_03_effect_list == nil then
|
||||
caster.thtd_soga_03_effect_list = {}
|
||||
end
|
||||
|
||||
if caster.thtd_soga_03_rect_last ~= nil then
|
||||
for index,point in pairs(caster.thtd_soga_03_rect_last) do
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count < 9 then
|
||||
count = count + 1
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point+Vector(math.cos(math.pi/2+count*math.pi*2/18),math.sin(math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, point+Vector(math.cos(math.pi/2+count*math.pi*2/18),math.sin(math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, point+Vector(math.cos(-math.pi/2+count*math.pi*2/18),math.sin(-math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 1, point+Vector(math.cos(-math.pi/2+count*math.pi*2/18),math.sin(-math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
return 0.1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0.1)
|
||||
return nil
|
||||
end,
|
||||
0)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_effect_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
for i=1,6 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point+Vector(math.cos(-math.pi/2+i*math.pi*2/6),math.sin(-math.pi/2+i*math.pi*2/6),0)*400)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, point+Vector(math.cos(-math.pi/2+i*math.pi*2/6),math.sin(-math.pi/2+i*math.pi*2/6),0)*400)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
for i=1,3 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point+Vector(math.cos(-math.pi/2+i*math.pi*2/3),math.sin(-math.pi/2+i*math.pi*2/3),0)*200)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, point+Vector(math.cos(-math.pi/2+i*math.pi*2/3),math.sin(-math.pi/2+i*math.pi*2/3),0)*200)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
for i=1,1 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point+Vector(math.cos(-math.pi/2+i*math.pi*2/1),math.sin(-math.pi/2+i*math.pi*2/1),0)*100)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, point+Vector(math.cos(-math.pi/2+i*math.pi*2/1),math.sin(-math.pi/2+i*math.pi*2/1),0)*100)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
return nil
|
||||
end,
|
||||
1.1)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * keys.damage_down/100
|
||||
local targets = THTD_FindUnitsInRadius(caster,point,keys.range)
|
||||
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)
|
||||
if keys.damage_up > 0 and v:HasModifier("modifier_soga_03_debuff") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_soga_03_debuff", {Duration = keys.duration_time})
|
||||
end
|
||||
end
|
||||
for k,v in pairs(caster.thtd_soga_03_effect_list) do
|
||||
ParticleManager:DestroyParticleSystem(v,true)
|
||||
end
|
||||
caster.thtd_soga_03_effect_list = {}
|
||||
caster.thtd_soga_03_rect_last = {}
|
||||
return nil
|
||||
end,
|
||||
1.3)
|
||||
end
|
||||
else
|
||||
caster.thtd_soga_03_rect_last = {}
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_think"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count < 9 then
|
||||
count = count + 1
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint+Vector(math.cos(math.pi/2+count*math.pi*2/18),math.sin(math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(math.cos(math.pi/2+count*math.pi*2/18),math.sin(math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, targetPoint+Vector(math.cos(-math.pi/2+count*math.pi*2/18),math.sin(-math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 1, targetPoint+Vector(math.cos(-math.pi/2+count*math.pi*2/18),math.sin(-math.pi/2+count*math.pi*2/18),0)*500)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
return 0.1
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0.1)
|
||||
return nil
|
||||
end,
|
||||
0)
|
||||
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_effect_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
|
||||
for i=1,6 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint+Vector(math.cos(-math.pi/2+i*math.pi*2/6),math.sin(-math.pi/2+i*math.pi*2/6),0)*400)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(math.cos(-math.pi/2+i*math.pi*2/6),math.sin(-math.pi/2+i*math.pi*2/6),0)*400)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
for i=1,3 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint+Vector(math.cos(-math.pi/2+i*math.pi*2/3),math.sin(-math.pi/2+i*math.pi*2/3),0)*200)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(math.cos(-math.pi/2+i*math.pi*2/3),math.sin(-math.pi/2+i*math.pi*2/3),0)*200)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
for i=1,1 do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_soga_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint+Vector(math.cos(-math.pi/2+i*math.pi*2/1),math.sin(-math.pi/2+i*math.pi*2/1),0)*100)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(math.cos(-math.pi/2+i*math.pi*2/1),math.sin(-math.pi/2+i*math.pi*2/1),0)*100)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
return nil
|
||||
end,
|
||||
1.1)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_soga_03_spell_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
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)
|
||||
if keys.damage_up > 0 and v:HasModifier("modifier_soga_03_debuff") == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_soga_03_debuff", {Duration = keys.duration_time})
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,18 do
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_soga/ability_thtd_soga_lightning.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, targetPoint+Vector(math.cos(i*math.pi*2/18),math.sin(i*math.pi*2/18),0)*keys.range)
|
||||
table.insert(caster.thtd_soga_03_effect_list,effectIndex2)
|
||||
end
|
||||
|
||||
table.insert(caster.thtd_soga_03_rect_last,targetPoint)
|
||||
return nil
|
||||
end,
|
||||
1.3)
|
||||
|
||||
end
|
||||
|
||||
function OnCreatedSogaComboBuff(keys)
|
||||
keys.target:AddDamageIncomingMagical(keys.damage_up, "thtd_soga_combo_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroySogaComboBuff(keys)
|
||||
keys.target:AddDamageIncomingMagical("thtd_soga_combo_damage_up")
|
||||
end
|
||||
200
scripts/vscripts/abilities/abilitystar.lua
Executable file
200
scripts/vscripts/abilities/abilitystar.lua
Executable file
@@ -0,0 +1,200 @@
|
||||
function OnStar01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local fairyArea = nil
|
||||
local hero = caster:GetOwner()
|
||||
if hero~=nil and hero:IsNull()==false then
|
||||
local fairyList = GetHeroFairyList(hero)
|
||||
for k,v in pairs(fairyList) do
|
||||
if v.star == caster then
|
||||
fairyArea = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local isTargetInArea = false
|
||||
if fairyArea ~= nil then
|
||||
local pos1 = fairyArea.sunny:GetAbsOrigin()
|
||||
local pos2 = fairyArea.star:GetAbsOrigin()
|
||||
local pos3 = fairyArea.luna:GetAbsOrigin()
|
||||
isTargetInArea = IsInTriangle(pos1,pos2,pos3,targetPoint)
|
||||
local center, radius = GetCircleCenterAndRadius(pos1,pos2,pos3)
|
||||
local targetsTotal = {}
|
||||
local fairyTargets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
for _,v in pairs(fairyTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() and IsUnitInFairy(fairyArea,v) then
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
end
|
||||
for k,v in pairs(targetsTotal) do
|
||||
OnStar01Damage(keys,v:GetOrigin())
|
||||
end
|
||||
end
|
||||
|
||||
if not isTargetInArea then
|
||||
OnStar01Damage(keys,targetPoint)
|
||||
end
|
||||
end
|
||||
|
||||
function OnStar01Damage(keys,targetPoint)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_star/ability_star_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_star_01_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_star_01_slow", {Duration = keys.duration_time})
|
||||
|
||||
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,
|
||||
0.5)
|
||||
end
|
||||
|
||||
function OnStar02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local fairyArea = nil
|
||||
local hero = caster:GetOwner()
|
||||
if hero~=nil and hero:IsNull()==false then
|
||||
local fairyList = GetHeroFairyList(hero)
|
||||
for k,v in pairs(fairyList) do
|
||||
if v.star == caster then
|
||||
fairyArea = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local isTargetInArea = false
|
||||
if fairyArea ~= nil then
|
||||
local pos1 = fairyArea.sunny:GetAbsOrigin()
|
||||
local pos2 = fairyArea.star:GetAbsOrigin()
|
||||
local pos3 = fairyArea.luna:GetAbsOrigin()
|
||||
|
||||
isTargetInArea = IsInTriangle(pos1,pos2,pos3,targetPoint)
|
||||
|
||||
local center, radius = GetCircleCenterAndRadius(pos1,pos2,pos3)
|
||||
|
||||
local pos10 = GetTwoVectorSub(center, pos1, 2/1)
|
||||
local pos20 = GetTwoVectorSub(center, pos2, 2/1)
|
||||
local pos30 = GetTwoVectorSub(center, pos3, 2/1)
|
||||
local star_points = {}
|
||||
table.insert(star_points, center)
|
||||
table.insert(star_points, pos10)
|
||||
table.insert(star_points, pos20)
|
||||
table.insert(star_points, pos30)
|
||||
table.insert(star_points, GetTwoVectorSub(pos10, pos20, 1/1))
|
||||
table.insert(star_points, GetTwoVectorSub(pos20, pos30, 1/1))
|
||||
table.insert(star_points, GetTwoVectorSub(pos30, pos10, 1/1))
|
||||
|
||||
local time = keys.max_count * 0.2
|
||||
local count = 0
|
||||
caster:SetContextThink(DoUniqueString("ability_star_02_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time < 0 then return nil end
|
||||
if fairyArea.sunny==nil or fairyArea.sunny:IsNull() or fairyArea.sunny:THTD_IsHidden() then return nil end
|
||||
if fairyArea.star==nil or fairyArea.star:IsNull() or fairyArea.star:THTD_IsHidden() then return nil end
|
||||
if fairyArea.luna==nil or fairyArea.luna:IsNull() or fairyArea.luna:THTD_IsHidden() then return nil end
|
||||
|
||||
for _, pos in pairs(star_points) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_star/ability_star_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, pos)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
if count > 0 and count % 2 == 0 then
|
||||
local targetsTotal = {}
|
||||
local targets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
for _,v in pairs(targets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() and IsUnitInFairy(fairyArea,v) then
|
||||
table.insert(targetsTotal, v)
|
||||
end
|
||||
end
|
||||
targets = {}
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 2 * (1 + keys.damage_up/100)^count
|
||||
for _, v in pairs(targetsTotal) 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
|
||||
end
|
||||
|
||||
count = count + 1
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
|
||||
end
|
||||
|
||||
if not isTargetInArea then
|
||||
OnStar02Damage(keys,targetPoint)
|
||||
end
|
||||
end
|
||||
|
||||
function OnStar02Damage(keys,targetPoint)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local time = keys.max_count * 0.2
|
||||
local count = 0
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_star_02_delay"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time < 0 then return nil end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_star/ability_star_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
if count > 0 and count % 2 == 0 then
|
||||
caster:SetContextThink(DoUniqueString("ability_star_02_delay"),
|
||||
function()
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 2 * (1 + keys.damage_up/100)^count
|
||||
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,
|
||||
0.5)
|
||||
end
|
||||
|
||||
count = count + 1
|
||||
time = time - 0.2
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
371
scripts/vscripts/abilities/abilitysuika.lua
Executable file
371
scripts/vscripts/abilities/abilitysuika.lua
Executable file
@@ -0,0 +1,371 @@
|
||||
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
|
||||
166
scripts/vscripts/abilities/abilitysunny.lua
Executable file
166
scripts/vscripts/abilities/abilitysunny.lua
Executable file
@@ -0,0 +1,166 @@
|
||||
function OnSunny01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local targetPoint = target:GetOrigin()
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
OnSunny01Damage(keys,caster,caster,target,damage)
|
||||
local count = 1
|
||||
local lastTarget = target
|
||||
local attackedTarget = {}
|
||||
for k,v in pairs(targets) do
|
||||
if count <= keys.max_count and THTD_IsValid(v) and v ~= lastTarget then
|
||||
count = count + 1
|
||||
OnSunny01Damage(keys,caster,lastTarget,v, damage*(1+keys.damage_up/100)^count)
|
||||
lastTarget = v
|
||||
table.insert(attackedTarget, v)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local fairyArea = nil
|
||||
local hero = caster:GetOwner()
|
||||
if hero~=nil and hero:IsNull()==false then
|
||||
local fairyList = GetHeroFairyList(hero)
|
||||
for k,v in pairs(fairyList) do
|
||||
if v.sunny == caster then
|
||||
fairyArea = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if fairyArea ~= nil then
|
||||
local pos1 = fairyArea.sunny:GetAbsOrigin()
|
||||
local pos2 = fairyArea.star:GetAbsOrigin()
|
||||
local pos3 = fairyArea.luna:GetAbsOrigin()
|
||||
local center, radius = GetCircleCenterAndRadius(pos1,pos2,pos3)
|
||||
local targetsTotal = {}
|
||||
local fairyTargets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
for _,v in pairs(fairyTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() and IsUnitInFairy(fairyArea,v) then
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
end
|
||||
local targetAdds = {}
|
||||
for k,v in pairs(targetsTotal) do
|
||||
local isExist = false
|
||||
for k2,v2 in pairs(attackedTarget) do
|
||||
if v2 == v then
|
||||
isExist = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if isExist == false then
|
||||
table.insert(targetAdds,v)
|
||||
end
|
||||
end
|
||||
targetsTotal = {}
|
||||
|
||||
local factor = 0
|
||||
for i=1,keys.max_count+1 do
|
||||
factor = factor + (1+keys.damage_up/100)^(i-1)
|
||||
end
|
||||
local lastTarget = caster
|
||||
for k,v in pairs(targetAdds) do
|
||||
OnSunny01Damage(keys,caster,lastTarget,v,damage*factor)
|
||||
lastTarget = v
|
||||
end
|
||||
targetAdds = {}
|
||||
end
|
||||
end
|
||||
|
||||
function OnSunny01Damage(keys,caster,target1,target2,damage)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/sunny/ability_sunny_01_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, target2, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, target1, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 9, target2, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target2,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnSunny02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/sunny/ability_sunny_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex , 0, targetPoint+Vector(0,0,32))
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time)
|
||||
|
||||
local fairyArea = nil
|
||||
local hero = caster:GetOwner()
|
||||
if hero~=nil and hero:IsNull()==false then
|
||||
local fairyList = GetHeroFairyList(hero)
|
||||
for k,v in pairs(fairyList) do
|
||||
if v.sunny == caster then
|
||||
fairyArea = v
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local center = nil
|
||||
local radius = nil
|
||||
if fairyArea ~= nil then
|
||||
local pos1 = fairyArea.sunny:GetAbsOrigin()
|
||||
local pos2 = fairyArea.star:GetAbsOrigin()
|
||||
local pos3 = fairyArea.luna:GetAbsOrigin()
|
||||
center, radius = GetCircleCenterAndRadius(pos1,pos2,pos3)
|
||||
end
|
||||
|
||||
local time = keys.duration_time
|
||||
caster:SetContextThink(DoUniqueString("ability_sunny_02_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then return nil end
|
||||
if THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
local targetsTotal = {}
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
if center ~= nil and radius ~= nil then
|
||||
local fairyTargets = THTD_FindUnitsInRadius(caster,center,radius)
|
||||
for _,v in pairs(fairyTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() and IsUnitInFairy(fairyArea,v) then
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
for k,v in pairs(targets) do
|
||||
targetsTotal[v:GetEntityIndex()] = v
|
||||
end
|
||||
targets = {}
|
||||
for k,v in pairs(targetsTotal) do
|
||||
local m = v:FindModifierByName("modifier_sunny_02_debuff")
|
||||
if m ~= nil then
|
||||
m:SetDuration(0.4, false)
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_sunny_02_debuff", {Duration = 0.4})
|
||||
end
|
||||
end
|
||||
|
||||
time = time - 0.25
|
||||
return 0.25
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnCreatedSunny02Buff(keys)
|
||||
keys.target:AddDamageIncomingPure(keys.damage_up, "thtd_sunny_02_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroySunny02Buff(keys)
|
||||
keys.target:AddDamageIncomingPure("thtd_sunny_02_damage_up")
|
||||
end
|
||||
207
scripts/vscripts/abilities/abilitysuwako.lua
Executable file
207
scripts/vscripts/abilities/abilitysuwako.lua
Executable file
@@ -0,0 +1,207 @@
|
||||
function OnSuwako01SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
function OnSuwako01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_suwako/ability_suwako_01_ring.vpcf",
|
||||
vSpawnOrigin = caster:GetOrigin() + Vector(0,0,128),
|
||||
fDistance = caster:Script_GetAttackRange(),
|
||||
fStartRadius = 200,
|
||||
fEndRadius = 200,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = caster:GetForwardVector() * 1500,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
|
||||
function OnSuwako02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_suwako_02_rect == nil then
|
||||
caster.thtd_suwako_02_rect = {}
|
||||
end
|
||||
|
||||
caster.thtd_suwako_02_rect["point"] = targetPoint
|
||||
if caster.thtd_suwako_02_rect["effectIndex"] == nil then
|
||||
caster.thtd_suwako_02_rect["effectIndex"] = ParticleManager:CreateParticle("particles/heroes/thtd_suwako/ability_suwako_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(caster.thtd_suwako_02_rect["effectIndex"], 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(caster.thtd_suwako_02_rect["effectIndex"], 1, Vector(keys.range,1,1))
|
||||
else
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_suwako_02_rect["effectIndex"],true)
|
||||
caster.thtd_suwako_02_rect["effectIndex"] = ParticleManager:CreateParticle("particles/heroes/thtd_suwako/ability_suwako_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(caster.thtd_suwako_02_rect["effectIndex"], 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(caster.thtd_suwako_02_rect["effectIndex"], 1, Vector(keys.range,1,1))
|
||||
end
|
||||
end
|
||||
|
||||
function OnSuwako02Think(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster.thtd_suwako_02_rect == nil then
|
||||
caster.thtd_suwako_02_rect = {}
|
||||
end
|
||||
if keys.ability:GetLevel() < 1 or caster:THTD_IsHidden() then
|
||||
if caster.thtd_suwako_02_rect["effectIndex"]~=nil then
|
||||
ParticleManager:DestroyParticleSystem(caster.thtd_suwako_02_rect["effectIndex"],true)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if caster.thtd_suwako_02_rect["effectIndex"] ~= nil then
|
||||
local point = caster.thtd_suwako_02_rect["point"]
|
||||
local targets = THTD_FindUnitsInRadius(caster,point,keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.2 * (1 + caster:THTD_GetFaith()*keys.up_percent/100)
|
||||
for k,v in pairs(targets) do
|
||||
if v.thtd_suwako_02_count == nil then
|
||||
v.thtd_suwako_02_count = 0
|
||||
end
|
||||
if v.thtd_suwako_02_lock == nil then
|
||||
v.thtd_suwako_02_lock = false
|
||||
end
|
||||
v.thtd_suwako_02_count = v.thtd_suwako_02_count + 1
|
||||
if v.thtd_suwako_02_count > keys.stay_time/0.2 and v.thtd_suwako_02_lock == false then
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_suwako_rooted",{Duration = keys.root_time})
|
||||
v.thtd_suwako_02_lock = true
|
||||
|
||||
v:SetContextThink(DoUniqueString("thtd_suwako_02_leave_rect"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if GetDistanceBetweenTwoVec2D(point,v:GetOrigin()) > keys.range then
|
||||
v.thtd_suwako_02_count = 0
|
||||
v.thtd_suwako_02_lock = false
|
||||
return nil
|
||||
else
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
return 0.2
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnSuwako03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local inners = THTD_FindUnitsInner(caster)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * (1 + caster:THTD_GetFaith()*keys.up_percent/100)
|
||||
for k,v in pairs(inners) do
|
||||
if v:HasModifier("modifier_suwako_03_rooted") == false then
|
||||
local g = -10
|
||||
local vh = 120
|
||||
local t = math.abs(2*vh/g)
|
||||
local targetPoint = v:GetOrigin() -- + RandomVector(200)
|
||||
local rad = GetRadBetweenTwoVec2D(v:GetOrigin(),targetPoint)
|
||||
local dis = GetDistanceBetweenTwoVec2D(v:GetOrigin(),targetPoint)
|
||||
local speed = dis/t
|
||||
local curOrigin = v:GetOrigin()
|
||||
local originz = curOrigin.z
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster,v,"modifier_suwako_03_rooted",{})
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/kunkka/kunkka_torrent_base/kunkka_spell_torrent_splash_econ.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
v:SetContextThink(DoUniqueString("thtd_suwako_03_unit_up"),
|
||||
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)
|
||||
v:SetAbsOrigin(curOrigin)
|
||||
|
||||
if curOrigin.z >= originz then
|
||||
return 0.03
|
||||
else
|
||||
-- FindClearSpaceForUnit(v, v:GetOrigin(), false)
|
||||
v:SetAbsOrigin(targetPoint)
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
v:RemoveModifierByName("modifier_suwako_03_rooted")
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnSuwakoKill(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
caster:THTD_AddFaith()
|
||||
end
|
||||
|
||||
function OnSuwako04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_suwako_04")
|
||||
caster.thtd_last_cast_unit = target
|
||||
|
||||
local modifier = target:FindModifierByName("modifier_suwako_04_buff")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_suwako_04_buff", {duration = keys.duration_time})
|
||||
else
|
||||
modifier:SetDuration(keys.duration_time, false)
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedSuwako04Buff(keys)
|
||||
local unitName = keys.target:GetUnitName()
|
||||
if unitName == "suwako" or unitName == "kanako" or unitName == "sanae" then
|
||||
keys.target:THTD_AddCritDamage(keys.self_crit, "thtd_suwako_04_bonus")
|
||||
else
|
||||
keys.target:THTD_AddCritDamage(keys.crit, "thtd_suwako_04_bonus")
|
||||
end
|
||||
end
|
||||
|
||||
function OnDestroySuwako04Buff(keys)
|
||||
keys.target:THTD_AddCritDamage("thtd_suwako_04_bonus")
|
||||
end
|
||||
|
||||
242
scripts/vscripts/abilities/abilitytenshi.lua
Executable file
242
scripts/vscripts/abilities/abilitytenshi.lua
Executable file
@@ -0,0 +1,242 @@
|
||||
function OnTenshi01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_tenshi_01")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
|
||||
local powerBonus = #targets * keys.bonus_attack_power
|
||||
if powerBonus > 0 then
|
||||
caster:THTD_AddBasePower(powerBonus)
|
||||
caster:THTD_AddBaseAttack(powerBonus)
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:THTD_AddBasePower(-powerBonus)
|
||||
caster:THTD_AddBaseAttack(-powerBonus)
|
||||
return nil
|
||||
end,
|
||||
keys.duration_time)
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable_aoe = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable_aoe)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/earthshaker/egteam_set/hero_earthshaker_egset/earthshaker_echoslam_start_fallback_low_egset.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnTenshi02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAttack()
|
||||
for k,v in pairs(targets) do
|
||||
local DamageTable_aoe = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable_aoe)
|
||||
end
|
||||
|
||||
if caster.thtd_attack_time == nil then
|
||||
caster.thtd_attack_time = GameRules:GetGameTime() - 10
|
||||
end
|
||||
if caster.thtd_attack_time < GameRules:GetGameTime() - 1 then
|
||||
caster.thtd_attack_time = GameRules:GetGameTime()
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/earthshaker/egteam_set/hero_earthshaker_egset/earthshaker_echoslam_start_fallback_low_egset.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
end
|
||||
|
||||
-- 被动modifier会在所有自定变量前生效,造成不起作用,不要用Passive
|
||||
function OnThinkTenshi02Buff(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
local powerChance = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_tenshi_02")
|
||||
if pv ~= nil then
|
||||
powerChance = pv[1]
|
||||
end
|
||||
local bonus = keys.chance + powerChance
|
||||
local add = bonus - (caster.thtd_tenshi_02_crit_chance or 0)
|
||||
if add ~= 0 then
|
||||
caster:THTD_AddCritChance(add)
|
||||
caster.thtd_tenshi_02_crit_chance = bonus
|
||||
end
|
||||
|
||||
local bonus = keys.crit
|
||||
if caster:IsPower999() then
|
||||
bonus = bonus * 2
|
||||
end
|
||||
local add = bonus - (caster.thtd_tenshi_02_crit_damage or 0)
|
||||
if add ~= 0 then
|
||||
caster:THTD_AddCritDamage(add)
|
||||
caster.thtd_tenshi_02_crit_damage = bonus
|
||||
end
|
||||
end
|
||||
|
||||
function OnDestroyTenshi02Buff(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
if caster.thtd_tenshi_02_crit_chance ~= nil then
|
||||
caster:THTD_AddCritChance(-caster.thtd_tenshi_02_crit_chance)
|
||||
caster.thtd_tenshi_02_crit_chance = nil
|
||||
end
|
||||
if caster.thtd_tenshi_02_crit_damage ~= nil then
|
||||
caster:THTD_AddCritDamage(-caster.thtd_tenshi_02_crit_damage)
|
||||
caster.thtd_tenshi_02_crit_damage = nil
|
||||
end
|
||||
end
|
||||
|
||||
function OnTenshi03AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
if caster.thtd_tenshi_03_attack_count == nil then
|
||||
caster.thtd_tenshi_03_attack_count = 0
|
||||
end
|
||||
|
||||
caster.thtd_tenshi_03_attack_count = caster.thtd_tenshi_03_attack_count + 1
|
||||
|
||||
if caster.thtd_tenshi_03_attack_count >= keys.max_count then
|
||||
caster.thtd_tenshi_03_attack_count = 0
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_tenshi_03")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
caster.thtd_tenshi_03_damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
|
||||
caster:EmitSound("Hero_Magnataur.ShockWave.Particle")
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/tenshi/ability_tenshi_03.vpcf",
|
||||
vSpawnOrigin = caster:GetAbsOrigin(),
|
||||
fDistance = 1500,
|
||||
fStartRadius = 380,
|
||||
fEndRadius = 380,
|
||||
Source = caster,
|
||||
bHasFrontalCone = false,
|
||||
bReplaceExisting = false,
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_NONE,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
fExpireTime = GameRules:GetGameTime() + 10.0,
|
||||
bDeleteOnHit = false,
|
||||
vVelocity = caster:GetForwardVector() * 1800,
|
||||
bProvidesVision = true,
|
||||
iVisionRadius = 1000,
|
||||
iVisionTeamNumber = caster:GetTeamNumber()
|
||||
}
|
||||
local projectile = ProjectileManager:CreateLinearProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
if caster:IsPower666() then
|
||||
if caster.thtd_tenshi_power666_cast ~= true then
|
||||
caster.thtd_tenshi_power666_cast = true
|
||||
local time = 1.5
|
||||
local forward = caster:GetForwardVector()
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_elder_titan/elder_titan_earth_splitter.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, forward * 900) --方向
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, Vector(0, time, 0)) --时间
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_suwako_03_unit_up"),
|
||||
function()
|
||||
caster:EmitSound("Hero_ElderTitan.EarthSplitter.Cast")
|
||||
local targets = FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + forward * 1000,
|
||||
nil,
|
||||
300,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
local damage = 666 * caster:THTD_GetStarDamage()
|
||||
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
|
||||
|
||||
caster.thtd_tenshi_power666_cast = false
|
||||
return nil
|
||||
end,
|
||||
time)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnTenshiProjectileHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster.thtd_tenshi_03_damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
|
||||
function OnThinkTenshi03Buff(keys)
|
||||
local target = keys.target
|
||||
|
||||
local targets = THTD_FindFriendlyUnitsInRadius(target,target:GetAbsOrigin(),keys.radius)
|
||||
for k,v in pairs(targets) do
|
||||
local modifier = v:FindModifierByName("modifier_tenshi_03_attack_speed_buff")
|
||||
-- 持续时间比think大一点
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(target, v, "modifier_tenshi_03_attack_speed_buff", {Duration = 0.3})
|
||||
else
|
||||
modifier:SetDuration(0.3, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnCreatedTenshi03Buff(keys)
|
||||
keys.target:THTD_AddAttackSpeed(keys.attack_speed, "thtd_tenshi_03_bonus")
|
||||
end
|
||||
|
||||
function OnDestroyTenshi03Buff(keys)
|
||||
keys.target:THTD_AddAttackSpeed("thtd_tenshi_03_bonus")
|
||||
end
|
||||
105
scripts/vscripts/abilities/abilitytoramaru.lua
Executable file
105
scripts/vscripts/abilities/abilitytoramaru.lua
Executable file
@@ -0,0 +1,105 @@
|
||||
function OnToramaru01SpellStart(keys)
|
||||
if SpawnSystem.IsUnLimited then return end
|
||||
if GameRules:GetCustomGameDifficulty() >= FUNNY_MODE then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local gold = keys.BonusGold
|
||||
THTD_ModifyGoldEx(caster:GetPlayerOwnerID(), gold , true, DOTA_ModifyGold_CreepKill)
|
||||
SendOverheadEventMessage(caster:GetPlayerOwner(), OVERHEAD_ALERT_GOLD, target, gold, caster:GetPlayerOwner() )
|
||||
caster:EmitSound("Sound_THTD.thtd_nazrin_01")
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/items/item_donation_box.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetAbsOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
function OnToramaru02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") then
|
||||
THTD_ModifyGoldEx(caster:GetPlayerOwnerID(), 500 * caster.thtd_byakuren_buff_toramaru/100 , true, DOTA_ModifyGold_CreepKill)
|
||||
caster.toramaru_cost_gold = (caster.toramaru_cost_gold or 0) + 500
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/items/item_donation_box.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, target:GetAbsOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
function OnToramaru03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster:HasModifier("modifier_byakuren_03_buff") then
|
||||
THTD_ModifyGoldEx(caster:GetPlayerOwnerID(), 5000 * caster.thtd_byakuren_buff_toramaru/100, true, DOTA_ModifyGold_CreepKill)
|
||||
caster.toramaru_cost_gold = (caster.toramaru_cost_gold or 0) + 5000
|
||||
end
|
||||
|
||||
local inners = THTD_FindUnitsInner(caster)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(inners) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/items/item_donation_box.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetAbsOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, v:GetAbsOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = 0
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
|
||||
function OnSpellStartToramaru04(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local damage = caster:THTD_GetStarDamage() * 2
|
||||
damage = damage + (caster.toramaru_cost_gold or 0)*caster:THTD_GetStar()*0.02
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),keys.ability:GetCastRange())
|
||||
for k,v in pairs(targets) do
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/sunny/ability_sunny_01_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 0, v, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 1, caster, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex , 9, v, 5, "attach_hitloc", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
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
|
||||
end
|
||||
141
scripts/vscripts/abilities/abilityutsuho.lua
Executable file
141
scripts/vscripts/abilities/abilityutsuho.lua
Executable file
@@ -0,0 +1,141 @@
|
||||
function OnUtsuho01Attack(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
end
|
||||
|
||||
function OnCreatedUtsuhoRinBuff(keys)
|
||||
keys.target:AddDamageOutgoingPhysical(keys.damage_up, "thtd_utsuho_rin_damage_up")
|
||||
end
|
||||
|
||||
function OnDestroyUtsuhoRinBuff(keys)
|
||||
keys.target:AddDamageOutgoingPhysical("thtd_utsuho_rin_damage_up")
|
||||
end
|
||||
|
||||
function OnUtsuho02Attack(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if caster.thtd_utsuho_02_attack_count == nil then
|
||||
caster.thtd_utsuho_02_attack_count = 0
|
||||
end
|
||||
|
||||
caster.thtd_utsuho_02_attack_count = caster.thtd_utsuho_02_attack_count + 1
|
||||
|
||||
if caster.thtd_utsuho_02_attack_count >= keys.max_count then
|
||||
caster.thtd_utsuho_02_attack_count = 0
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/utsuho/ability_utsuho03_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
target:EmitSound("Hero_Invoker.ChaosMeteor.Impact")
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function OnUtsuho03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
keys.ability.ability_utsuho04_point_x = targetPoint.x
|
||||
keys.ability.ability_utsuho04_point_y = targetPoint.y
|
||||
keys.ability.ability_utsuho04_point_z = targetPoint.z
|
||||
local dummy = CreateUnitByName("npc_dummy_unit",
|
||||
targetPoint,
|
||||
false,
|
||||
caster,
|
||||
caster,
|
||||
caster:GetTeamNumber()
|
||||
)
|
||||
caster.ability_utsuho_04_dummy = dummy
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/utsuho/ability_utsuho04_effect.vpcf", PATTACH_CUSTOMORIGIN, dummy)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetPoint)
|
||||
keys.ability.ability_utsuho04_effect_index = effectIndex
|
||||
end
|
||||
|
||||
function OnUtsuho03SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local tx = keys.ability.ability_utsuho04_point_x
|
||||
local ty = keys.ability.ability_utsuho04_point_y
|
||||
local tz = keys.ability.ability_utsuho04_point_z
|
||||
local targetPoint = Vector(tx,ty,tz)
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.radius)
|
||||
|
||||
for _,v in pairs(targets) do
|
||||
local dis = GetDistanceBetweenTwoVec2D(targetPoint,v:GetOrigin())
|
||||
local rad = GetRadBetweenTwoVec2D(targetPoint,v:GetOrigin())
|
||||
if(dis>=(keys.Gravity/10))then
|
||||
v:SetAbsOrigin(v:GetOrigin() - keys.Gravity/10 * Vector(math.cos(rad),math.sin(rad),0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnUtsuho03SpellRemove(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = keys.target_entities
|
||||
local effectIndex = keys.ability.ability_utsuho04_effect_index
|
||||
local tx = keys.ability.ability_utsuho04_point_x
|
||||
local ty = keys.ability.ability_utsuho04_point_y
|
||||
local tz = keys.ability.ability_utsuho04_point_z
|
||||
local targetPoint = Vector(tx,ty,tz)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
if(caster.ability_utsuho_04_dummy~=nil)then
|
||||
effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/utsuho/ability_utsuho04_end.vpcf", PATTACH_CUSTOMORIGIN, caster.ability_utsuho_04_dummy)
|
||||
else
|
||||
effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/utsuho/ability_utsuho04_end.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
end
|
||||
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
caster.ability_utsuho_04_dummy:SetContextThink(DoUniqueString("ability_utsuho04_effect_remove"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
caster.ability_utsuho_04_dummy:RemoveSelf()
|
||||
end,
|
||||
1.0)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for _,v in pairs(targets) do
|
||||
FindClearSpaceForUnit(v, v:GetOrigin(), false)
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
67
scripts/vscripts/abilities/abilitywriggle.lua
Executable file
67
scripts/vscripts/abilities/abilitywriggle.lua
Executable file
@@ -0,0 +1,67 @@
|
||||
function OnSpellStartWriggle02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local vecForward = caster:GetForwardVector()
|
||||
local targetPoint = keys.target_points[1] + Vector(0, 0, 200)
|
||||
local range = keys.range
|
||||
local max_count = keys.max_count
|
||||
|
||||
local effectIndex1 = ParticleManager:CreateParticle("particles/units/heroes/hero_keeper_of_the_light/keeper_dazzling.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex1, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex1, 1, Vector(range, 1, 1))
|
||||
local effectIndex2 = nil
|
||||
local count = 1
|
||||
local startTime = GameRules:GetGameTime()
|
||||
caster:SetContextThink(DoUniqueString("thtd_wriggle_02"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count/3 > max_count or THTD_IsValid(caster) == false then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex1,true)
|
||||
if effectIndex2 ~= nil then ParticleManager:DestroyParticleSystem(effectIndex2,true) end
|
||||
-- print("---- duration time : ", GameRules:GetGameTime() - startTime)
|
||||
return nil
|
||||
end
|
||||
if count%3 == 1 then
|
||||
effectIndex2 = ParticleManager:CreateParticle("particles/units/heroes/hero_keeper_of_the_light/keeper_dazzling_on.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, targetPoint)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 1, Vector(range, 0, 0))
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,range)
|
||||
for k,v in pairs(targets) do
|
||||
if v.thtd_is_fearing ~= true then
|
||||
v.thtd_is_fearing = true
|
||||
|
||||
local current_next_move_point = v.next_move_point
|
||||
v.next_move_point = targetPoint
|
||||
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_wriggle02_speed", {})
|
||||
|
||||
local fearCount = 0.5 * 2 * 10
|
||||
-- local startTime = GameRules:GetGameTime()
|
||||
v:SetContextThink(DoUniqueString("modifier_thtd_wriggle_02"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if not IsValidAlive(target) then
|
||||
return nil
|
||||
end
|
||||
fearCount = fearCount - 1
|
||||
if fearCount <= 0 or THTD_IsValid(caster) == false then
|
||||
target.next_move_point = current_next_move_point
|
||||
target.thtd_is_fearing = false
|
||||
return nil
|
||||
end
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
elseif count%3 == 0 then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,true)
|
||||
effectIndex2 = nil
|
||||
end
|
||||
count = count + 1
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
|
||||
end
|
||||
75
scripts/vscripts/abilities/abilityyoshika.lua
Executable file
75
scripts/vscripts/abilities/abilityyoshika.lua
Executable file
@@ -0,0 +1,75 @@
|
||||
function OnYoshika01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yoshika/ability_yoshika_01.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local debuff_count = 1
|
||||
if caster:HasModifier("modifier_miko_02_buff") and caster.thtd_miko_buff_yoshika ~= nil then
|
||||
debuff_count = 1 + caster.thtd_miko_buff_yoshika
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
for k,v in pairs(targets) do
|
||||
local time = keys.duration_time
|
||||
v:AddPoison(debuff_count, caster)
|
||||
v:SetContextThink(DoUniqueString("thtd_yoshika01_debuff"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if THTD_IsValid(v) == false then return nil end
|
||||
if time <= 0 then
|
||||
v:AddPoison(-debuff_count)
|
||||
return nil
|
||||
end
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * 0.5,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
|
||||
time = time - 0.5
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
|
||||
local modifier = v:FindModifierByName("modifier_yoshika_01_slow")
|
||||
if modifier == nil then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_yoshika_01_slow", nil)
|
||||
else
|
||||
modifier:SetDuration(keys.duration_time,false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnYoshika02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local inners = THTD_FindUnitsInner(caster)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
for k,v in pairs(inners) do
|
||||
if THTD_IsValid(v) then
|
||||
local count = v:GetPoisonCount()
|
||||
if count > 0 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yoshika/ability_yoshika_02.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = damage * count,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
179
scripts/vscripts/abilities/abilityyoumu.lua
Executable file
179
scripts/vscripts/abilities/abilityyoumu.lua
Executable file
@@ -0,0 +1,179 @@
|
||||
function OnYoumu01AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
if caster.thtd_youmu_01_attack_count == nil then
|
||||
caster.thtd_youmu_01_attack_count = 0
|
||||
end
|
||||
|
||||
local powerChance = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_youmu_02")
|
||||
if pv ~= nil then
|
||||
powerChance = pv[1]
|
||||
end
|
||||
|
||||
caster:GiveMana(1)
|
||||
|
||||
caster.thtd_youmu_01_attack_count = caster.thtd_youmu_01_attack_count + 1
|
||||
|
||||
if caster.thtd_youmu_01_attack_count >= keys.max_count then
|
||||
caster.thtd_youmu_01_attack_count = 0
|
||||
caster:EmitSound("Hero_Magnataur.ShockWave.Particle")
|
||||
|
||||
local targetPoint = caster:GetOrigin() + caster:GetForwardVector() * keys.length
|
||||
Youmu01Damage(keys,targetPoint,caster:GetOrigin())
|
||||
|
||||
if RollPercentage(caster:GetAbilityValue("thtd_youmu_02", "chance") + powerChance) then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/youmu/youmu_01_blink_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0 , target:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
targetPoint = target:GetOrigin() - target:GetForwardVector() * keys.length
|
||||
Youmu01Damage(keys,targetPoint,target:GetOrigin())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Youmu01Damage(keys,targetPoint,vecCaster)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
if caster:IsPower666() then damage = damage * 3 end
|
||||
|
||||
local targets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
targetPoint,
|
||||
nil,
|
||||
360,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
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)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/youmu/youmu_01_blink_effect_a.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_youmu/ability_youmu_01_laser.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster+Vector(0,0,32))
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, targetPoint+Vector(0,0,32))
|
||||
ParticleManager:SetParticleControl(effectIndex, 9, vecCaster+Vector(0,0,32))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnYoumu03Damage(keys,targetPoint,vecCaster)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/youmu/youmu_04_circle.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local rad = 210*math.pi/180
|
||||
|
||||
local count = 0
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_youmu_01")
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_youmu_03")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) + powerDamage * caster:THTD_GetStarDamage()
|
||||
if caster:IsPower666() then damage = damage * 3 end
|
||||
if caster:IsPower999() then damage = damage * 4 end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("thtd_youmu_03_spell_start"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
rad = rad + 210*math.pi/180
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/youmu/youmu_04_sword_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
local effect2VecForward = Vector(targetPoint.x+math.cos(rad)*500,targetPoint.y+math.sin(rad)*500,vecCaster.z)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, effect2VecForward)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
vecCaster = effect2VecForward
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,550)
|
||||
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)
|
||||
|
||||
if count%5 == 0 then
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/youmu/youmu_02_effect_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
end
|
||||
end
|
||||
|
||||
if count > 20 then return nil end
|
||||
count = count + 1
|
||||
return 0.12
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnYoumu03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_youmu_03_power_bonus == nil then
|
||||
local attack = caster:THTD_GetBaseAttack()
|
||||
local bonus = attack
|
||||
caster:THTD_AddBasePower(bonus)
|
||||
caster.thtd_youmu_03_power_bonus = bonus
|
||||
caster:THTD_AddBaseAttack(-attack)
|
||||
caster.thtd_kagerou_02_attack_bonus = attack
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:THTD_AddBasePower(-caster.thtd_youmu_03_power_bonus)
|
||||
caster.thtd_youmu_03_power_bonus = nil
|
||||
caster:THTD_AddBaseAttack(caster.thtd_kagerou_02_attack_bonus)
|
||||
caster.thtd_kagerou_02_attack_bonus = nil
|
||||
return nil
|
||||
end,
|
||||
2.5)
|
||||
end
|
||||
|
||||
OnYoumu03Damage(keys,targetPoint,vecCaster)
|
||||
|
||||
local powerChance = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_youmu_02")
|
||||
if pv ~= nil then
|
||||
powerChance = pv[1]
|
||||
end
|
||||
|
||||
if RollPercentage(caster:GetAbilityValue("thtd_youmu_02", "chance") + powerChance) then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/youmu/youmu_01_blink_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin() + RandomVector(300))
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 0 , caster:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
targetPoint = targetPoint + RandomVector(150)
|
||||
OnYoumu03Damage(keys,targetPoint,vecCaster)
|
||||
end
|
||||
end
|
||||
744
scripts/vscripts/abilities/abilityyukari.lua
Executable file
744
scripts/vscripts/abilities/abilityyukari.lua
Executable file
@@ -0,0 +1,744 @@
|
||||
-- 代替触发器
|
||||
local UnitMoveRect = {
|
||||
[0] = {
|
||||
[1] = {
|
||||
["center"] = {-2200, 1550},
|
||||
["radius"] = 200,
|
||||
["tag"] = {2}
|
||||
},
|
||||
[2] = {
|
||||
["center"] = {-4100, 1600},
|
||||
["radius"] = 100,
|
||||
["tag"] = {3}
|
||||
},
|
||||
[3] = {
|
||||
["center"] = {-4100, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {4}
|
||||
},
|
||||
[4] = {
|
||||
["center"] = {6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {5}
|
||||
},
|
||||
[5] = {
|
||||
["center"] = {6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {6}
|
||||
},
|
||||
[6] = {
|
||||
["center"] = {-6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {7}
|
||||
},
|
||||
[7] = {
|
||||
["center"] = {-6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {4}
|
||||
},
|
||||
},
|
||||
[1] = {
|
||||
[1] = {
|
||||
["center"] = {2200, 1550},
|
||||
["radius"] = 200,
|
||||
["tag"] = {2}
|
||||
},
|
||||
[2] = {
|
||||
["center"] = {4100, 1600},
|
||||
["radius"] = 100,
|
||||
["tag"] = {3}
|
||||
},
|
||||
[3] = {
|
||||
["center"] = {4100, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {4}
|
||||
},
|
||||
[4] = {
|
||||
["center"] = {6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {5}
|
||||
},
|
||||
[5] = {
|
||||
["center"] = {6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {6}
|
||||
},
|
||||
[6] = {
|
||||
["center"] = {-6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {7}
|
||||
},
|
||||
[7] = {
|
||||
["center"] = {-6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {4}
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
[1] = {
|
||||
["center"] = {2200, -1550},
|
||||
["radius"] = 200,
|
||||
["tag"] = {2}
|
||||
},
|
||||
[2] = {
|
||||
["center"] = {4100, -1600},
|
||||
["radius"] = 100,
|
||||
["tag"] = {3}
|
||||
},
|
||||
[3] = {
|
||||
["center"] = {4100, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {6}
|
||||
},
|
||||
[4] = {
|
||||
["center"] = {6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {5}
|
||||
},
|
||||
[5] = {
|
||||
["center"] = {6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {6}
|
||||
},
|
||||
[6] = {
|
||||
["center"] = {-6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {7}
|
||||
},
|
||||
[7] = {
|
||||
["center"] = {-6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {4}
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
[1] = {
|
||||
["center"] = {-2200, -1550},
|
||||
["radius"] = 200,
|
||||
["tag"] = {2}
|
||||
},
|
||||
[2] = {
|
||||
["center"] = {-4100, -1600},
|
||||
["radius"] = 100,
|
||||
["tag"] = {3}
|
||||
},
|
||||
[3] = {
|
||||
["center"] = {-4100, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {6}
|
||||
},
|
||||
[4] = {
|
||||
["center"] = {6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {5}
|
||||
},
|
||||
[5] = {
|
||||
["center"] = {6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {6}
|
||||
},
|
||||
[6] = {
|
||||
["center"] = {-6750, -4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {7}
|
||||
},
|
||||
[7] = {
|
||||
["center"] = {-6750, 4120},
|
||||
["radius"] = 100,
|
||||
["tag"] = {4}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function OnYukari01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if target.thtd_player_index ~= caster:GetPlayerOwnerID() then return end
|
||||
|
||||
local powerBonus = target:GetBaseDamageMax()
|
||||
if powerBonus > 0 then
|
||||
caster:THTD_AddBasePower(powerBonus)
|
||||
target:SetBaseDamageMax(0)
|
||||
target:SetBaseDamageMin(0)
|
||||
caster:SetContextThink(DoUniqueString("dota_timer"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
caster:THTD_AddBasePower(-powerBonus)
|
||||
if THTD_IsValid(target) then
|
||||
target:SetBaseDamageMax(powerBonus)
|
||||
target:SetBaseDamageMin(powerBonus)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
keys.duration_time)
|
||||
end
|
||||
|
||||
if caster.thtd_yukari_01_hidden_table == nil then
|
||||
caster.thtd_yukari_01_hidden_table = {}
|
||||
end
|
||||
|
||||
if target.thtd_yukari_01_hidden_count == nil then
|
||||
target.thtd_yukari_01_hidden_count = 0
|
||||
end
|
||||
|
||||
if #caster.thtd_yukari_01_hidden_table < keys.max_count and target.thtd_yukari_01_hidden_count < keys.limit_count then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, target, "modifier_yukari_01_hidden", nil)
|
||||
target:AddNoDraw()
|
||||
target.thtd_is_yukari_01_hidden = true
|
||||
target.thtd_yukari_01_hidden_count = target.thtd_yukari_01_hidden_count + 1
|
||||
table.insert(caster.thtd_yukari_01_hidden_table,target)
|
||||
|
||||
target:SetContextThink(DoUniqueString("thtd_yukari_01_death"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster==nil or caster:IsNull() or caster:IsAlive() == false then
|
||||
target:RemoveNoDraw()
|
||||
target:RemoveModifierByName("modifier_yukari_01_hidden")
|
||||
target.thtd_is_yukari_01_hidden = false
|
||||
return nil
|
||||
end
|
||||
return 1.0
|
||||
end,
|
||||
1.0)
|
||||
end
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"npc_thdots_unit_yukari01_unit"
|
||||
,target:GetOrigin()
|
||||
,false
|
||||
,caster
|
||||
,caster
|
||||
,caster:GetTeam()
|
||||
)
|
||||
local ability_dummy_unit = unit:FindAbilityByName("ability_dummy_unit")
|
||||
ability_dummy_unit:SetLevel(1)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_02_vortex_2.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, unit:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
unit:EmitSound("Hero_ObsidianDestroyer.AstralImprisonment")
|
||||
|
||||
unit:SetContextThink(DoUniqueString("thtd_yukari_01_release"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if unit:IsAlive() then
|
||||
unit:ForceKill(false)
|
||||
return 0.5
|
||||
else
|
||||
unit:AddNoDraw()
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
1.0)
|
||||
end
|
||||
|
||||
function OnYukari02SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_yukari_01_hidden_table == nil then
|
||||
caster.thtd_yukari_01_hidden_table = {}
|
||||
end
|
||||
|
||||
if #caster.thtd_yukari_01_hidden_table > 0 then
|
||||
for k,v in pairs(caster.thtd_yukari_01_hidden_table) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
OnYukari02SpellDropUnit(keys,v)
|
||||
table.remove(caster.thtd_yukari_01_hidden_table,k)
|
||||
break
|
||||
else
|
||||
table.remove(caster.thtd_yukari_01_hidden_table,k)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnYukari02SpellDropUnit(keys,unit)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local g = -5
|
||||
local high = 500
|
||||
local v = 0
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local currentOrigin = targetPoint + Vector(0,0,high)
|
||||
local minHigh = caster:GetOrigin().z
|
||||
local isRemove = false
|
||||
|
||||
unit:SetAbsOrigin(currentOrigin)
|
||||
unit.thtd_is_yukari_01_hidden = false
|
||||
if GetDistanceBetweenTwoVec2D(unit.next_move_point, targetPoint) > 2500 then
|
||||
unit.next_move_point = unit.first_move_point
|
||||
unit.next_move_forward = unit.first_move_forward
|
||||
unit.thtd_next_corner = unit.thtd_first_corner
|
||||
unit.thtd_is_outer = nil
|
||||
table.insert(THTD_EntitiesRectInner[unit.thtd_player_index],unit)
|
||||
for k,target in pairs(THTD_EntitiesRectOuter) do
|
||||
if target == unit then
|
||||
table.remove(THTD_EntitiesRectOuter,k)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_02_body.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
EmitSoundOnLocationWithCaster(currentOrigin,"Hero_ObsidianDestroyer.AstralImprisonment.End",caster)
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_yuuka_02"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
v = v + g
|
||||
currentOrigin = currentOrigin + Vector(0,0,v)
|
||||
if unit~=nil and unit:IsNull()==false and unit:IsAlive() then
|
||||
if GetDistanceBetweenTwoVec2D(unit:GetOrigin(),currentOrigin) < 100 and isRemove == false then
|
||||
unit:RemoveNoDraw()
|
||||
isRemove = true
|
||||
end
|
||||
unit:SetAbsOrigin(currentOrigin)
|
||||
end
|
||||
|
||||
if currentOrigin.z >= minHigh then
|
||||
return 0.02
|
||||
else
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_02_down.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, currentOrigin)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
EmitSoundOnLocationWithCaster(currentOrigin,"Ability.TossImpact",caster)
|
||||
|
||||
if unit~=nil and unit:IsNull()==false and unit:IsAlive() then
|
||||
unit:RemoveModifierByName("modifier_yukari_01_hidden")
|
||||
FindClearSpaceForUnit(unit, currentOrigin, false)
|
||||
end
|
||||
if caster~=nil then
|
||||
local targets = THTD_FindUnitsInRadius(caster,currentOrigin,keys.range)
|
||||
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)
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
|
||||
-- 无比丑陋
|
||||
function OnYukari03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
local e1 = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_04_magical.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(e1, 0, caster:GetOrigin())
|
||||
|
||||
local e2 = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_04_magical.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(e2, 0, targetPoint)
|
||||
|
||||
caster:EmitSound("Hero_Enigma.BlackHole.Cast.Chasm")
|
||||
caster:EmitSound("Hero_Enigma.Black_Hole")
|
||||
|
||||
local isFirst = false
|
||||
|
||||
caster:SetContextThink(DoUniqueString("OnYukari03"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
ParticleManager:DestroyParticleSystem(e1,true)
|
||||
ParticleManager:DestroyParticleSystem(e2,true)
|
||||
|
||||
-- 取消所有传送
|
||||
-- local targets =
|
||||
-- FindUnitsInRadius(
|
||||
-- caster:GetTeamNumber(),
|
||||
-- caster:GetOrigin(),
|
||||
-- nil,
|
||||
-- 2000,
|
||||
-- keys.ability:GetAbilityTargetTeam(),
|
||||
-- keys.ability:GetAbilityTargetType(),
|
||||
-- keys.ability:GetAbilityTargetFlags(),
|
||||
-- FIND_ANY_ORDER,
|
||||
-- false
|
||||
-- )
|
||||
local v = caster
|
||||
-- for k,v in pairs(targets) do
|
||||
if v:THTD_IsTower() and (v:GetUnitName()=="yukari" or v:GetUnitName()=="ran" or v:GetUnitName()=="chen") then
|
||||
if v:THTD_IsHidden() == false then
|
||||
local vecOrigin = v:GetOrigin()
|
||||
v:SetAbsOrigin(targetPoint)
|
||||
v:AddNoDraw()
|
||||
local unit = CreateUnitByName(
|
||||
"npc_thdots_unit_yukari01_unit"
|
||||
,vecOrigin
|
||||
,false
|
||||
,caster
|
||||
,caster
|
||||
,caster:GetTeam()
|
||||
)
|
||||
local ability_dummy_unit = unit:FindAbilityByName("ability_dummy_unit")
|
||||
ability_dummy_unit:SetLevel(1)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_02_vortex_2.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, unit:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
unit:SetContextThink(DoUniqueString("thtd_yukari_01_release"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if unit:IsAlive() then
|
||||
unit:ForceKill(false)
|
||||
return 0.5
|
||||
else
|
||||
unit:AddNoDraw()
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
1.0)
|
||||
|
||||
v:SetContextThink(DoUniqueString("FindClearSpaceForUnit"),
|
||||
function()
|
||||
if GetDistanceBetweenTwoVec2D(v:GetOrigin(),targetPoint) < 100 then
|
||||
v:RemoveNoDraw()
|
||||
FindClearSpaceForUnit(v, targetPoint, false)
|
||||
v:THTD_DestroyLevelEffect()
|
||||
v:THTD_CreateLevelEffect()
|
||||
return nil
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03)
|
||||
|
||||
v:SetContextThink(DoUniqueString("thtd_yukari_03_back"),
|
||||
function()
|
||||
if isFirst == false then
|
||||
isFirst = true
|
||||
local e1 = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_04_magical.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(e1, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystemTime(e1,1.0)
|
||||
|
||||
local e2 = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_04_magical.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(e2, 0, vecCaster)
|
||||
ParticleManager:DestroyParticleSystemTime(e2,1.0)
|
||||
|
||||
caster:EmitSound("Hero_Enigma.BlackHole.Cast.Chasm")
|
||||
caster:EmitSound("Hero_Enigma.Black_Hole")
|
||||
end
|
||||
v:SetContextThink(DoUniqueString("OnYuuka03SpellEnd"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if v:THTD_IsHidden() == false then
|
||||
local unit = CreateUnitByName(
|
||||
"npc_thdots_unit_yukari01_unit"
|
||||
,v:GetOrigin()
|
||||
,false
|
||||
,caster
|
||||
,caster
|
||||
,caster:GetTeam()
|
||||
)
|
||||
local ability_dummy_unit = unit:FindAbilityByName("ability_dummy_unit")
|
||||
ability_dummy_unit:SetLevel(1)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_02_vortex_2.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
v:SetAbsOrigin(vecOrigin)
|
||||
v:AddNoDraw()
|
||||
v:EmitSound("Hero_Enigma.Black_Hole.Stop")
|
||||
caster:StopSound("Hero_Enigma.BlackHole.Cast.Chasm")
|
||||
caster:StopSound("Hero_Enigma.Black_Hole")
|
||||
|
||||
unit:SetContextThink(DoUniqueString("thtd_yukari_01_release"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if unit:IsAlive() then
|
||||
unit:ForceKill(false)
|
||||
return 0.5
|
||||
else
|
||||
unit:AddNoDraw()
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
1.0)
|
||||
|
||||
v:SetContextThink(DoUniqueString("FindClearSpaceForUnit"),
|
||||
function()
|
||||
if GetDistanceBetweenTwoVec2D(v:GetOrigin(),vecOrigin) < 100 then
|
||||
v:RemoveNoDraw()
|
||||
FindClearSpaceForUnit(v, vecOrigin, false)
|
||||
v:THTD_DestroyLevelEffect()
|
||||
v:THTD_CreateLevelEffect()
|
||||
return nil
|
||||
end
|
||||
return 0.03
|
||||
end,
|
||||
0.03)
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
1.0)
|
||||
return nil
|
||||
end,
|
||||
3.0)
|
||||
end
|
||||
end
|
||||
-- end
|
||||
|
||||
caster:StopSound("Hero_Enigma.BlackHole.Cast.Chasm")
|
||||
caster:StopSound("Hero_Enigma.Black_Hole")
|
||||
caster:EmitSound("Hero_Enigma.Black_Hole.Stop")
|
||||
return nil
|
||||
end,
|
||||
1.0)
|
||||
end
|
||||
|
||||
function OnThinkYukari03(keys)
|
||||
local caster = keys.caster
|
||||
|
||||
if keys.ability:GetLevel() < 1 then return end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetAbsOrigin(),1500)
|
||||
if #targets > 0 then
|
||||
local point = targets[RandomInt(1, #targets)]:GetAbsOrigin()
|
||||
targets = {}
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/econ/items/clockwerk/clockwerk_paraflare/clockwerk_para_rocket_flare_parachute.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, point)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(2,0,0))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
-- EmitSoundOnLocationWithCaster(point,"Hero_Rattletrap.Rocket_Flare.Fire",caster)
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
targets = THTD_FindUnitsInRadius(caster,point,keys.range)
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
local thtd_yukari_04_train_spwan =
|
||||
{
|
||||
[1] =
|
||||
{
|
||||
["spawn"] = Vector(-1408,1056,136) * 1.5 + Vector(500,0,0),
|
||||
["firstPoint"] = Vector(-1408,1056,136) * 1.5,
|
||||
["firstForward"] = "left",
|
||||
["forward"] = Vector(-1,0,0),
|
||||
},
|
||||
[2] =
|
||||
{
|
||||
["spawn"] = Vector(1408,1056,136) * 1.5 + Vector(-500,0,0),
|
||||
["firstPoint"] = Vector(1408,1056,136) * 1.5,
|
||||
["firstForward"] = "right",
|
||||
["forward"] = Vector(1,0,0),
|
||||
},
|
||||
[3] =
|
||||
{
|
||||
["spawn"] = Vector(1408,-1056,136) * 1.5 + Vector(-500,0,0),
|
||||
["firstPoint"] = Vector(1408,-1056,136) * 1.5,
|
||||
["firstForward"] = "right",
|
||||
["forward"] = Vector(-1,0,0),
|
||||
},
|
||||
[4] =
|
||||
{
|
||||
["spawn"] = Vector(-1408,-1056,136) * 1.5 + Vector(500,0,0),
|
||||
["firstPoint"] = Vector(-1408,-1056,136) * 1.5,
|
||||
["firstForward"] = "left",
|
||||
["forward"] = Vector(1,0,0),
|
||||
},
|
||||
}
|
||||
|
||||
function OnYukari04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local max_count = keys.max_count
|
||||
local crit = 1 + (max_count - 1) * keys.damage_up / 100
|
||||
local duration_time = math.floor(keys.duration_time * 100 + 0.5) / 100
|
||||
local tick = math.floor(keys.tick * 100 + 0.5) / 100
|
||||
|
||||
local originSpawn = thtd_yukari_04_train_spwan[caster:GetOwner():GetPlayerOwnerID()+1]["spawn"]
|
||||
local originPoint = thtd_yukari_04_train_spwan[caster:GetOwner():GetPlayerOwnerID()+1]["firstPoint"]
|
||||
local originForward = thtd_yukari_04_train_spwan[caster:GetOwner():GetPlayerOwnerID()+1]["firstForward"]
|
||||
local forward = thtd_yukari_04_train_spwan[caster:GetOwner():GetPlayerOwnerID()+1]["forward"]
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_yukari_04")
|
||||
|
||||
local train = CreateUnitByName(
|
||||
"yukari_train",
|
||||
originSpawn,
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yukari/ability_yukari_04_door.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, originSpawn-forward*400)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, originSpawn-forward*400)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 3, forward)
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, originSpawn-forward*400)
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 4, forward)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
train:AddNewModifier(train, nil, "modifier_move_max_speed", nil)
|
||||
train:SetAbsOrigin(originSpawn)
|
||||
train:SetForwardVector(forward)
|
||||
train.next_move_point = originPoint
|
||||
train.firstForward = originForward
|
||||
train.next_corner_table = {}
|
||||
train.FirstTrain = nil
|
||||
|
||||
local timecount = math.floor(duration_time / tick)
|
||||
train:SetContextThink(DoUniqueString("AttackingBase"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if timecount > 0 then
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * crit
|
||||
local targets = THTD_FindUnitsInRadius(caster,train:GetOrigin(),200)
|
||||
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)
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_04_boom.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 3, train:GetOrigin()-train:GetForwardVector()*100)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
timecount = timecount - 1
|
||||
train:MoveToPosition(train.next_move_point)
|
||||
if timecount%10 == 0 then
|
||||
train:EmitSound("Sound_THTD.thtd_yukari_04.loop")
|
||||
end
|
||||
|
||||
-- 替代触发器
|
||||
-- local id = caster:GetPlayerOwnerID()
|
||||
-- for k,v in pairs(UnitMoveRect[id]) do
|
||||
-- if GetDistanceBetweenTwoVec2D(train:GetOrigin(), Vector(v["center"][1],v["center"][2]),0) <= v["radius"] then
|
||||
-- if train.current_rect_id ~= k then
|
||||
-- train.current_rect_id = k
|
||||
-- local tagIndex = v["tag"][RandomInt(1, #v["tag"])]
|
||||
-- train.next_move_point = Vector(UnitMoveRect[id][tagIndex]["center"][1],UnitMoveRect[id][tagIndex]["center"][2],0)
|
||||
-- train:MoveToPosition(train.next_move_point)
|
||||
-- end
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return tick
|
||||
else
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yukari/ability_yukari_04_door.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, train:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, train:GetOrigin())
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 3, train:GetForwardVector())
|
||||
ParticleManager:SetParticleControl(effectIndex, 4, train:GetOrigin())
|
||||
ParticleManager:SetParticleControlForward(effectIndex, 4, train:GetForwardVector())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
train:ForceKill(true)
|
||||
train:AddNoDraw()
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
|
||||
local count = max_count - 1
|
||||
caster:SetContextThink(DoUniqueString("OnYukari04SpellStart"),
|
||||
function()
|
||||
local nexttrain = CreateUnitByName(
|
||||
"yukari_train",
|
||||
originSpawn,
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
|
||||
nexttrain:AddNewModifier(nexttrain, nil, "modifier_move_max_speed", nil)
|
||||
nexttrain:SetAbsOrigin(originSpawn)
|
||||
nexttrain.next_move_point = originPoint
|
||||
nexttrain.firstForward = originForward
|
||||
nexttrain.FirstTrain = train
|
||||
nexttrain:SetForwardVector(forward)
|
||||
|
||||
local nexttimecount = math.floor(duration_time / tick)
|
||||
nexttrain:SetContextThink(DoUniqueString("AttackingBase"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if nexttimecount > 0 and nexttrain~=nil and nexttrain:IsNull()==false and nexttrain:IsAlive() then
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * crit
|
||||
local targets = THTD_FindUnitsInRadius(caster,nexttrain:GetOrigin(),200)
|
||||
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)
|
||||
UnitStunTarget(caster,v,keys.stun_time)
|
||||
end
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/yukari/ability_yukari_04_boom.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 3, nexttrain:GetOrigin()-nexttrain:GetForwardVector()*100)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex2,false)
|
||||
nexttimecount = nexttimecount - 1
|
||||
if nexttrain.next_move_point ~= nil then
|
||||
nexttrain:MoveToPosition(nexttrain.next_move_point)
|
||||
end
|
||||
|
||||
-- 替代触发器
|
||||
-- local id = caster:GetPlayerOwnerID()
|
||||
-- for k,v in pairs(UnitMoveRect[id]) do
|
||||
-- if GetDistanceBetweenTwoVec2D(nexttrain:GetOrigin(), Vector(v["center"][1],v["center"][2]),0) <= v["radius"] then
|
||||
-- if nexttrain.current_rect_id ~= k then
|
||||
-- nexttrain.current_rect_id = k
|
||||
-- local tagIndex = v["tag"][RandomInt(1, #v["tag"])]
|
||||
-- nexttrain.next_move_point = Vector(UnitMoveRect[id][tagIndex]["center"][1],UnitMoveRect[id][tagIndex]["center"][2],0)
|
||||
-- nexttrain:MoveToPosition(nexttrain.next_move_point)
|
||||
-- end
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return tick
|
||||
else
|
||||
nexttrain:ForceKill(true)
|
||||
nexttrain:AddNoDraw()
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
|
||||
if count > 0 then
|
||||
count = count - 1
|
||||
return tick
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
0)
|
||||
end
|
||||
105
scripts/vscripts/abilities/abilityyuugi.lua
Executable file
105
scripts/vscripts/abilities/abilityyuugi.lua
Executable file
@@ -0,0 +1,105 @@
|
||||
function OnYuugi01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),caster:Script_GetAttackRange())
|
||||
for k,v in pairs(targets) do
|
||||
local damage_table = {
|
||||
victim = v,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetStarDamage()*RandomInt(math.min(keys.power_damage2,math.max(keys.power_damage1,#targets)),keys.power_damage2),
|
||||
ability = keys.ability,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE,
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuugi/ability_yuugi_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, caster:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, Vector(1000,1000,1000))
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
function OnYuugi02AttackLanded(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
if RollPercentage(keys.chance) then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuugi/ability_yuugi_02.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, target:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,target:GetOrigin(),keys.range)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
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)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_yuugi_02_pause_unit", {Duration = 0.48})
|
||||
OnYuugi02KnockBack(v,(v:GetAbsOrigin()-target:GetAbsOrigin()):Normalized())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnYuugi02KnockBack(target,forward)
|
||||
local time = 0.48
|
||||
target:SetContextThink(DoUniqueString("ability_yuugi_02_knockback"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then
|
||||
FindClearSpaceForUnit(target, target:GetOrigin(), false)
|
||||
return nil
|
||||
end
|
||||
target:SetAbsOrigin(target:GetOrigin()+forward*10)
|
||||
time = time - 0.03
|
||||
return 0.03
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnYuugi03SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.range)
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/yugi/yugi_slam.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
for k,v in pairs(targets) do
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_yuugi_03_pause_unit", {Duration = keys.duration_time})
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuggi/ability_yuugi_03.vpcf", PATTACH_CUSTOMORIGIN, v)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,keys.duration_time)
|
||||
|
||||
local time = keys.duration_time
|
||||
local vOrigin = v:GetOrigin()
|
||||
|
||||
v:SetContextThink(DoUniqueString("ability_yuugi_03_stop_move"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if time <= 0 then
|
||||
return nil
|
||||
end
|
||||
if not THTD_IsValid(caster) then
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end
|
||||
|
||||
if GetDistanceBetweenTwoVec2D(v:GetOrigin(), vOrigin) > 100 then
|
||||
caster:AbilityKill(v, keys.ability)
|
||||
return nil
|
||||
end
|
||||
|
||||
time = time - 0.1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
504
scripts/vscripts/abilities/abilityyuuka.lua
Executable file
504
scripts/vscripts/abilities/abilityyuuka.lua
Executable file
@@ -0,0 +1,504 @@
|
||||
function OnYuuka01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
|
||||
if caster.thtd_yuuka_seeds == nil then
|
||||
caster.thtd_yuuka_seeds = {}
|
||||
end
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_yuuka_01")
|
||||
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability)
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(), keys.range)
|
||||
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
|
||||
|
||||
for k,v in pairs(caster.thtd_yuuka_seeds) do
|
||||
if v~=nil and GetDistanceBetweenTwoVec2D(v, caster:GetOrigin()) <= keys.range then
|
||||
Yuuka02CreatePlant(keys,v,k)
|
||||
caster.thtd_yuuka_seeds[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/ability_yuuka_01.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vecCaster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 1, vecCaster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 2, vecCaster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 3, vecCaster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 7, vecCaster)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex,5.0)
|
||||
end
|
||||
|
||||
function Yuuka02CreatePlant(keys,vec,seed)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
local flower = CreateUnitByName(
|
||||
"yuuka_flower",
|
||||
vec,
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
|
||||
ParticleManager:DestroyParticleSystem(seed,true)
|
||||
|
||||
flower.thtd_spawn_unit_owner = caster
|
||||
flower:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, flower, "modifier_yuuka_02_flower", nil)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/ability_yuuka_01_spawn.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, vec)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/ability_yuuka_01_flower.vpcf", PATTACH_CUSTOMORIGIN, flower)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 0, flower, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 1, flower, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 2, flower, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:SetParticleControlEnt(effectIndex2 , 3, flower, 5, "follow_origin", Vector(0,0,0), true)
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex2,5.0)
|
||||
|
||||
local count = 0
|
||||
flower:SetContextThink(DoUniqueString("thtd_yuuka_02_plant"),
|
||||
function()
|
||||
local attack = caster:THTD_GetBaseAttack()
|
||||
flower:SetBaseDamageMax(attack)
|
||||
flower:SetBaseDamageMin(attack)
|
||||
flower:InheritOwnerBuff(caster)
|
||||
if count == 10 then
|
||||
local particle = ParticleManager:CreateParticle("particles/units/heroes/hero_techies/techies_land_mine_explode.vpcf",PATTACH_CUSTOMORIGIN,caster)
|
||||
ParticleManager:SetParticleControl(particle,0,flower:GetOrigin()+Vector(0,0,64))
|
||||
ParticleManager:DestroyParticleSystem(particle,false)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,flower:GetAbsOrigin(),keys.radius)
|
||||
local damage = caster:THTD_GetAbilityPowerDamage(keys.ability) * keys.crit
|
||||
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
|
||||
elseif count > 10 then
|
||||
flower:AddNoDraw()
|
||||
flower:ForceKill(true)
|
||||
return nil
|
||||
else
|
||||
if flower:IsAttacking() == false then
|
||||
flower:MoveToPositionAggressive(flower:GetOrigin() + flower:GetForwardVector() * 100)
|
||||
end
|
||||
end
|
||||
count = count + 1
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnIntervalThinkYuuka02(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
if caster:THTD_IsHidden() then return end
|
||||
|
||||
local forward = nil
|
||||
if IsValidAlive(caster.thtd_yuuka_03_illusion) then
|
||||
forward = (caster.thtd_yuuka_03_illusion:GetAbsOrigin() - caster:GetAbsOrigin()):Normalized()
|
||||
else
|
||||
forward = caster:GetForwardVector()
|
||||
end
|
||||
|
||||
if caster.thtd_yuuka_seeds == nil then
|
||||
caster.thtd_yuuka_seeds = {}
|
||||
end
|
||||
|
||||
local num = RandomInt(0,300)
|
||||
|
||||
local randomVector = caster:GetOrigin() + forward * 300 + RandomVector(num) + Vector(0,0,32)
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/ability_yuuka_02_seed.vpcf", PATTACH_CUSTOMORIGIN, nil)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, randomVector)
|
||||
|
||||
caster.thtd_yuuka_seeds[effectIndex] = randomVector
|
||||
-- caster:EmitSound("Sound_THTD.thtd_yuuka_02")
|
||||
|
||||
caster:GetOwner():SetContextThink(DoUniqueString("thtd_yuuka_02_seed_release"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if caster~=nil and caster:IsNull()==false and caster:IsAlive() then
|
||||
caster.thtd_yuuka_seeds[effectIndex] = nil
|
||||
end
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,true)
|
||||
return nil
|
||||
end,
|
||||
10.0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- 在本体和分身之间创建花田,若花田内有单位死亡,则增加花和花妈的属性
|
||||
|
||||
function OnSpellStartYuuka03(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
|
||||
if caster.thtd_yuuka_03_illusion == nil or caster.thtd_yuuka_03_illusion:IsNull() or caster.thtd_yuuka_03_illusion:IsAlive()==false then
|
||||
local illusion = CreateUnitByName(
|
||||
"yuuka_illusion",
|
||||
targetPoint,
|
||||
false,
|
||||
caster:GetOwner(),
|
||||
caster:GetOwner(),
|
||||
caster:GetTeam()
|
||||
)
|
||||
caster.thtd_yuuka_03_illusion = illusion
|
||||
illusion.thtd_yuuka_03_owner = caster
|
||||
ParticleManager:DestroyParticleSystem(seed,true)
|
||||
|
||||
illusion:SetControllableByPlayer(caster:GetPlayerOwnerID(), true)
|
||||
keys.ability:ApplyDataDrivenModifier(caster, illusion, "modifier_yuuka_03_illusion", nil)
|
||||
|
||||
local midOrigin = (caster:GetAbsOrigin() + targetPoint)/2
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/ability_yuuka_03.vpcf", PATTACH_CUSTOMORIGIN, illusion)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, midOrigin)
|
||||
ParticleManager:SetParticleControl(effectIndex, 7, midOrigin)
|
||||
illusion.effect = effectIndex
|
||||
|
||||
illusion:SetContextThink(DoUniqueString("thtd_yuuka_03_illusion"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
illusion:SetBaseDamageMax(caster:THTD_GetAttack())
|
||||
illusion:SetBaseDamageMin(caster:THTD_GetAttack())
|
||||
illusion:InheritOwnerBuff(caster)
|
||||
if caster==nil or caster:IsNull() or caster:THTD_IsHidden() or caster:IsAlive()==false then
|
||||
illusion:AddNoDraw()
|
||||
illusion:ForceKill(true)
|
||||
return nil
|
||||
elseif illusion:IsAttacking() == false and caster:IsChanneling() == false and caster:THTD_IsAggressiveLock()==false then
|
||||
illusion:MoveToPositionAggressive(illusion:GetOrigin() + illusion:GetForwardVector() * 100)
|
||||
illusion:THTD_SetAggressiveLock()
|
||||
end
|
||||
return 0.5
|
||||
end,
|
||||
0)
|
||||
else
|
||||
local midOrigin = (caster:GetAbsOrigin() + targetPoint)/2
|
||||
ParticleManager:SetParticleControl(caster.thtd_yuuka_03_illusion.effect, 0, midOrigin)
|
||||
ParticleManager:SetParticleControl(caster.thtd_yuuka_03_illusion.effect, 7, midOrigin)
|
||||
caster.thtd_yuuka_03_illusion:SetAbsOrigin(targetPoint)
|
||||
FindClearSpaceForUnit(caster.thtd_yuuka_03_illusion, targetPoint, false)
|
||||
end
|
||||
end
|
||||
|
||||
function OnThinkYuuka03(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
|
||||
if caster.thtd_yuuka_03_illusion ~= nil and caster.thtd_yuuka_03_illusion:IsNull()==false and caster.thtd_yuuka_03_illusion:IsAlive() then
|
||||
local midOrigin = (caster:GetAbsOrigin() + caster.thtd_yuuka_03_illusion:GetAbsOrigin())/2
|
||||
local dis = GetDistanceBetweenTwoEntity(caster,caster.thtd_yuuka_03_illusion)
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,midOrigin,dis/2)
|
||||
local damage = math.floor(caster:THTD_GetAbilityPowerDamage(keys.ability) * keys.tick)
|
||||
for k,v in pairs(targets) do
|
||||
if IsValidAlive(v) then
|
||||
local modifier = v:FindModifierByName("modifier_thtd_yuuka_03_death")
|
||||
if modifier ~= nil then
|
||||
modifier:SetDuration(keys.tick + 0.1, false)
|
||||
else
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_thtd_yuuka_03_death", {duration = keys.tick + 0.1})
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnYuuka03Death(keys)
|
||||
-- local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
-- local target = keys.unit
|
||||
|
||||
-- if caster == nil or caster:IsNull() or caster:IsAlive() == false then
|
||||
-- return
|
||||
-- end
|
||||
|
||||
-- if caster.thtd_yuuka_03_kill_count == nil then
|
||||
-- caster.thtd_yuuka_03_kill_count = 0
|
||||
-- end
|
||||
|
||||
-- if caster.thtd_yuuka_03_kill_count < keys.max_count then
|
||||
-- caster.thtd_yuuka_03_kill_count = caster.thtd_yuuka_03_kill_count + 1
|
||||
-- caster:AddDamageOutgoingAll(keys.damage_up, "thtd_yuuka_03_kill_bonus")
|
||||
-- caster:THTD_AddBaseAttack(keys.damage_up, "thtd_yuuka_03_kill_bonus")
|
||||
-- caster:THTD_AddBasePower(keys.damage_up, "thtd_yuuka_03_kill_bonus")
|
||||
-- end
|
||||
end
|
||||
|
||||
function OnYuuka04SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = keys.target_points[1]
|
||||
caster.cool_down_bonus_count = 0
|
||||
if caster.ability_dummy_unit~=nil then
|
||||
caster.ability_dummy_unit:RemoveSelf()
|
||||
keys.ability.effectcircle = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectcircle,true)
|
||||
keys.ability.effectIndex = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex,true)
|
||||
keys.ability.effectIndex_b = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex_b,true)
|
||||
end
|
||||
|
||||
local owner
|
||||
if caster.thtd_yuuka_03_owner == nil then
|
||||
owner = caster
|
||||
else
|
||||
owner = caster.thtd_yuuka_03_owner
|
||||
end
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"npc_dota2x_unit_yuuka04_spark"
|
||||
,caster:GetOrigin()
|
||||
,false
|
||||
,caster
|
||||
,caster
|
||||
,caster:GetTeam()
|
||||
)
|
||||
local ability_dummy_unit = unit:FindAbilityByName("ability_dummy_unit")
|
||||
ability_dummy_unit:SetLevel(1)
|
||||
|
||||
keys.ability.effectcircle = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/yuuka_04_spark_circle.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
keys.ability.effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/yuuka_04_spark.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
keys.ability.effectIndex_b = ParticleManager:CreateParticle("particles/heroes/thtd_yuuka/ability_yuuka_04_spark_wind.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
keys.ability:SetContextNum("ability_yuuka_04_spark_unit",unit:GetEntityIndex(),0)
|
||||
|
||||
YuukaSparkParticleControl(caster,keys.ability,targetPoint)
|
||||
keys.ability:SetContextNum("ability_yuuka_04_spark_lock",0,0)
|
||||
|
||||
caster.thtd_Yuuka_04_count = 1
|
||||
caster.thtd_Yuuka_04_last_distance = 10
|
||||
caster.thtd_Yuuka_04_currentForward = caster:GetForwardVector()
|
||||
caster.ability_dummy_unit = unit
|
||||
|
||||
if caster.thtd_yuuka_03_illusion ~= nil and caster.thtd_yuuka_03_illusion:IsNull()==false and caster.thtd_yuuka_03_illusion:IsAlive() then
|
||||
local ability = caster.thtd_yuuka_03_illusion:FindAbilityByName("thtd_yuuka_04")
|
||||
if ability == nil then
|
||||
ability = caster.thtd_yuuka_03_illusion:AddAbility("thtd_yuuka_04")
|
||||
end
|
||||
if ability:GetLevel() ~= 1 then
|
||||
ability:SetLevel(1)
|
||||
end
|
||||
ability:EndCooldown()
|
||||
local count = 1
|
||||
caster.thtd_yuuka_03_illusion:SetContextThink(DoUniqueString("thtd_yuuka_02_plant"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.03 end
|
||||
if count > 50 then return nil end
|
||||
if not ability:IsCooldownReady() then return nil end
|
||||
caster.thtd_yuuka_03_illusion:CastAbilityOnPosition(targetPoint,ability,caster:GetPlayerOwnerID())
|
||||
count = count + 1
|
||||
return 0.1
|
||||
end,
|
||||
0)
|
||||
end
|
||||
end
|
||||
|
||||
function YuukaSparkParticleControl(caster,ability,targetPoint)
|
||||
local unitIndex = ability:GetContext("ability_yuuka_04_spark_unit")
|
||||
local unit = EntIndexToHScript(unitIndex)
|
||||
|
||||
if(ability.targetPoint == targetPoint)then
|
||||
return
|
||||
else
|
||||
ability.targetPoint = targetPoint
|
||||
end
|
||||
|
||||
if(unit == nil or ability.effectIndex == -1 or ability.effectcircle == -1)then
|
||||
return
|
||||
end
|
||||
|
||||
forwardRad = GetRadBetweenTwoVec2D(targetPoint,caster:GetOrigin())
|
||||
vecForward = Vector(math.cos(math.pi/2 + forwardRad),math.sin(math.pi/2 + forwardRad),0)
|
||||
unit:SetForwardVector(vecForward)
|
||||
vecUnit = caster:GetOrigin() + Vector(caster:GetForwardVector().x * 100,caster:GetForwardVector().y * 100,160)
|
||||
vecColor = Vector(255,255,255)
|
||||
unit:SetAbsOrigin(vecUnit)
|
||||
|
||||
ParticleManager:SetParticleControl(ability.effectcircle, 0, caster:GetOrigin())
|
||||
|
||||
local effect2ForwardRad = GetRadBetweenTwoVec2D(caster:GetOrigin(),targetPoint)
|
||||
local effect2VecForward = Vector(math.cos(effect2ForwardRad)*1400,math.sin(effect2ForwardRad)*1400,0) + caster:GetOrigin() + Vector(caster:GetForwardVector().x * 100,caster:GetForwardVector().y * 100,108)
|
||||
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 0, caster:GetOrigin() + Vector(caster:GetForwardVector().x * 92,caster:GetForwardVector().y * 92,150))
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 1, effect2VecForward)
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 2, vecColor)
|
||||
local forwardRadwind = forwardRad + math.pi
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 8, Vector(math.cos(forwardRadwind),math.sin(forwardRadwind),0))
|
||||
ParticleManager:SetParticleControl(ability.effectIndex, 9, caster:GetOrigin() + Vector(caster:GetForwardVector().x * 100,caster:GetForwardVector().y * 100,108))
|
||||
|
||||
ParticleManager:SetParticleControl(ability.effectIndex_b, 0, caster:GetOrigin() + Vector(caster:GetForwardVector().x * 92,caster:GetForwardVector().y * 92,150))
|
||||
ParticleManager:SetParticleControlForward(ability.effectIndex_b, 3, Vector(math.cos(forwardRadwind),math.sin(forwardRadwind),0))
|
||||
end
|
||||
|
||||
function OnYuuka04SpellRemove(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local unitIndex = keys.ability:GetContext("ability_yuuka_04_spark_unit")
|
||||
|
||||
local unit = EntIndexToHScript(unitIndex)
|
||||
if unit~=nil then
|
||||
unit:RemoveSelf()
|
||||
keys.ability.effectcircle = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectcircle,true)
|
||||
keys.ability.effectIndex = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex,true)
|
||||
keys.ability.effectIndex_b = -1
|
||||
ParticleManager:DestroyParticleSystem(keys.ability.effectIndex_b,true)
|
||||
end
|
||||
keys.ability:SetContextNum("ability_yuuka_04_spark_lock",1,0)
|
||||
caster:StopSound("Sound_THTD.thtd_yuuka_04")
|
||||
caster.ability_dummy_unit = nil
|
||||
end
|
||||
|
||||
function OnYuuka04SpellThink(keys)
|
||||
if GameRules:IsGamePaused() then return end
|
||||
if (keys.ability:GetContext("ability_yuuka_04_spark_lock")==1) then
|
||||
return
|
||||
end
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local targetPoint = vecCaster + caster:GetForwardVector()
|
||||
|
||||
local nextForward,maxCount = FindYuuka04MaxCountEnemeiesForward(keys)
|
||||
if nextForward ~= nil then
|
||||
local forward = GetYuuka04ForwardMove(caster.thtd_Yuuka_04_currentForward,nextForward,caster.thtd_Yuuka_04_count * math.pi/180)
|
||||
local distance = GetDistanceBetweenTwoVec2D(forward, nextForward)
|
||||
|
||||
if caster.thtd_Yuuka_04_last_distance <= distance then
|
||||
caster.thtd_Yuuka_04_count = caster.thtd_Yuuka_04_count * - 1
|
||||
end
|
||||
caster.thtd_Yuuka_04_last_distance = distance
|
||||
|
||||
local NowDamageTargets =
|
||||
FindUnitsInLine(
|
||||
caster:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + keys.DamageLenth * caster.thtd_Yuuka_04_currentForward,
|
||||
nil,
|
||||
keys.DamageWidth,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
local NowCount = 0
|
||||
|
||||
for k,v in pairs(NowDamageTargets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
NowCount = NowCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
if distance > math.sin(math.pi/18) and distance < 1.86 and NowCount~=maxCount then
|
||||
caster:SetForwardVector(forward)
|
||||
caster.thtd_Yuuka_04_currentForward = forward
|
||||
end
|
||||
else
|
||||
caster:SetForwardVector(caster.thtd_Yuuka_04_currentForward)
|
||||
end
|
||||
|
||||
local targetPoint = vecCaster + caster.thtd_Yuuka_04_currentForward
|
||||
|
||||
if caster.thtd_effect_count == nil then
|
||||
caster.thtd_effect_count = 0
|
||||
end
|
||||
|
||||
if caster.thtd_effect_count >= 10 then
|
||||
local attacker = caster
|
||||
if caster.thtd_yuuka_03_owner~=nil then
|
||||
attacker = caster.thtd_yuuka_03_owner
|
||||
end
|
||||
|
||||
local DamageTargets =
|
||||
FindUnitsInLine(
|
||||
attacker:GetTeamNumber(),
|
||||
caster:GetOrigin(),
|
||||
caster:GetOrigin() + keys.DamageLenth * caster.thtd_Yuuka_04_currentForward,
|
||||
nil,
|
||||
keys.DamageWidth,
|
||||
keys.ability:GetAbilityTargetTeam(),
|
||||
keys.ability:GetAbilityTargetType(),
|
||||
keys.ability:GetAbilityTargetFlags()
|
||||
)
|
||||
|
||||
if #DamageTargets > 0 then
|
||||
local damage = attacker:THTD_GetAbilityPowerDamage(keys.ability) / keys.times
|
||||
for _,v in pairs(DamageTargets) do
|
||||
local damage_table = {
|
||||
ability = keys.ability,
|
||||
victim = v,
|
||||
attacker = attacker,
|
||||
damage = damage,
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(damage_table)
|
||||
end
|
||||
end
|
||||
caster.thtd_effect_count = 0
|
||||
else
|
||||
caster.thtd_effect_count = caster.thtd_effect_count + 1
|
||||
end
|
||||
YuukaSparkParticleControl(caster,keys.ability,targetPoint)
|
||||
end
|
||||
|
||||
function FindYuuka04MaxCountEnemeiesForward(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local forwardVector = caster.thtd_Yuuka_04_currentForward
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,caster:GetOrigin(),keys.DamageLenth)
|
||||
|
||||
if #targets <= 0 then
|
||||
return nil,0
|
||||
end
|
||||
|
||||
local maxCount = 0
|
||||
for i=1,120 do
|
||||
local sparkRad = math.pi * i/60
|
||||
local count = 0
|
||||
for k,v in pairs(targets) do
|
||||
if v~=nil and v:IsNull()==false and v:IsAlive() then
|
||||
if IsRadInRect(v:GetOrigin(),caster:GetOrigin(),keys.DamageWidth,keys.DamageLenth,sparkRad) then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
if count > maxCount then
|
||||
forwardVector = Vector(math.cos(sparkRad),math.sin(sparkRad),forwardVector.z)
|
||||
maxCount = count
|
||||
end
|
||||
end
|
||||
|
||||
return forwardVector,maxCount
|
||||
end
|
||||
|
||||
function GetYuuka04ForwardMove(forward,nextForward,rad)
|
||||
local forwardVector = Vector(math.cos(rad)*forward.x - math.sin(rad)*forward.y,
|
||||
forward.y*math.cos(rad) + forward.x*math.sin(rad),
|
||||
0)
|
||||
return forwardVector
|
||||
end
|
||||
211
scripts/vscripts/abilities/abilityyuyuko.lua
Executable file
211
scripts/vscripts/abilities/abilityyuyuko.lua
Executable file
@@ -0,0 +1,211 @@
|
||||
function OnYuyuko01SpellStart(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local casterPoint = caster:GetAbsOrigin()
|
||||
local range = caster:Script_GetAttackRange()
|
||||
|
||||
local powerChance = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_yuyuko_02")
|
||||
if pv ~= nil then
|
||||
powerChance = pv[1]
|
||||
end
|
||||
|
||||
caster.thtd_yuyuko_kill_chance = caster:GetAbilityValue("thtd_yuyuko_02", "chance") + powerChance
|
||||
|
||||
caster:EmitSound("Sound_THTD.thtd_yuyuka_01")
|
||||
|
||||
local count = keys.max_count
|
||||
local tick = keys.tick_time
|
||||
|
||||
if caster:IsPower666() then
|
||||
count = count + 3
|
||||
end
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_yuyuko_01_casted"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if not THTD_IsValid(caster) then
|
||||
return nil
|
||||
end
|
||||
if count <= 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,casterPoint,range)
|
||||
for k,v in pairs(targets) do
|
||||
local info =
|
||||
{
|
||||
Target = v,
|
||||
Source = caster,
|
||||
Ability = keys.ability,
|
||||
EffectName = "particles/heroes/thtd_yuyuko/ability_yuyuko_01.vpcf",
|
||||
iMoveSpeed = 750,
|
||||
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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
count = count - 1
|
||||
return tick
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnYuyuko01SpellHit(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local target = keys.target
|
||||
|
||||
caster:EmitSound("Hero_Necrolyte.ProjectileImpact")
|
||||
|
||||
if RollPercentage(caster.thtd_yuyuko_kill_chance) then
|
||||
caster:AbilityKill(target, keys.ability)
|
||||
else
|
||||
local DamageTable = {
|
||||
ability = keys.ability,
|
||||
victim = target,
|
||||
attacker = caster,
|
||||
damage = caster:THTD_GetAbilityPowerDamage(keys.ability),
|
||||
damage_type = keys.ability:GetAbilityDamageType(),
|
||||
damage_flags = DOTA_DAMAGE_FLAG_NONE
|
||||
}
|
||||
UnitDamageTarget(DamageTable)
|
||||
end
|
||||
end
|
||||
|
||||
function OnSpellStartYuyuko03(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local vecCaster = caster:GetOrigin()
|
||||
local vecForward = caster:GetForwardVector()
|
||||
local targetPoint = keys.target_points[1]
|
||||
caster.thtd_yuyuko_03_target_point = targetPoint
|
||||
caster.thtd_yuyuko_03_think_count = 0
|
||||
|
||||
caster:EmitSound("Voice_Thdots_Yuyuko.AbilityYuyuko04")
|
||||
|
||||
local unit = CreateUnitByName(
|
||||
"npc_dota2x_unit_yuyuko_04"
|
||||
,caster:GetOrigin() - vecForward * 100
|
||||
,false
|
||||
,caster
|
||||
,caster
|
||||
,caster:GetTeam()
|
||||
)
|
||||
local ability_dummy_unit = unit:FindAbilityByName("ability_dummy_unit")
|
||||
ability_dummy_unit:SetLevel(1)
|
||||
|
||||
unit:StartGesture(ACT_DOTA_IDLE)
|
||||
local forwardRad = GetRadBetweenTwoVec2D(caster:GetOrigin(),unit:GetOrigin())
|
||||
unit:SetForwardVector(Vector(math.cos(forwardRad+math.pi/2),math.sin(forwardRad+math.pi/2),0))
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_yuyuko/ability_yuyuko_04.vpcf", PATTACH_CUSTOMORIGIN, unit)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, targetPoint)
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/yuyuko/ability_yuyuko_04_effect_d.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, caster:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex2,2.0)
|
||||
|
||||
unit:SetContextThink(DoUniqueString("thtd_yuyuko_03_unit_remove"),
|
||||
function ()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
unit:RemoveSelf()
|
||||
return nil
|
||||
end,
|
||||
5.0)
|
||||
|
||||
|
||||
local powerChance = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_yuyuko_02")
|
||||
if pv ~= nil then
|
||||
powerChance = pv[1]
|
||||
end
|
||||
|
||||
caster.thtd_yuyuko_kill_chance = caster:GetAbilityValue("thtd_yuyuko_02", "chance") + powerChance
|
||||
local ability = caster:FindAbilityByName("thtd_yuyuko_01")
|
||||
|
||||
caster:SetContextThink(DoUniqueString("ability_yuyuko_01_casted"),
|
||||
function()
|
||||
if GameRules:IsGamePaused() then return 0.1 end
|
||||
if not THTD_IsValid(caster) then
|
||||
return nil
|
||||
end
|
||||
if not caster:HasModifier("modifier_yuyuko_03_think") then
|
||||
return nil
|
||||
end
|
||||
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.damage_radius)
|
||||
for k,v in pairs(targets) do
|
||||
local info =
|
||||
{
|
||||
Target = v,
|
||||
Source = caster,
|
||||
Ability = ability,
|
||||
EffectName = "particles/heroes/thtd_yuyuko/ability_yuyuko_01.vpcf",
|
||||
iMoveSpeed = 750,
|
||||
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
|
||||
}
|
||||
local projectile = ProjectileManager:CreateTrackingProjectile(info)
|
||||
ParticleManager:DestroyLinearProjectileSystem(projectile,false)
|
||||
end
|
||||
|
||||
return 0.25
|
||||
end,
|
||||
0)
|
||||
end
|
||||
|
||||
function OnThinkYuyuko03(keys)
|
||||
local caster = EntIndexToHScript(keys.caster_entindex)
|
||||
local targetPoint = caster.thtd_yuyuko_03_target_point
|
||||
|
||||
|
||||
local powerDamage = 0
|
||||
local pv = caster:GetAbilityPowerValue("thtd_yuyuko_03")
|
||||
if pv ~= nil then
|
||||
powerDamage = pv[1]
|
||||
end
|
||||
|
||||
caster.thtd_yuyuko_03_health_kill = keys.health_kill + powerDamage
|
||||
local targets = THTD_FindUnitsInRadius(caster,targetPoint,keys.damage_radius)
|
||||
for _,v in pairs(targets) do
|
||||
if caster.thtd_yuyuko_03_think_count%4 == 0 then
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/yuyuko/ability_yuyuko_04_effect.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
end
|
||||
|
||||
if v.thtd_damage_lock ~= true and v:HasModifier("modifier_yuyuko04_killed") ~= true and v:GetHealthPercent() <= caster.thtd_yuyuko_03_health_kill then
|
||||
keys.ability:ApplyDataDrivenModifier(caster, v, "modifier_yuyuko04_killed", {})
|
||||
|
||||
local effectIndex = ParticleManager:CreateParticle("particles/thd2/heroes/yuyuko/ability_yuyuko_04_effect_a.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex, 0, v:GetOrigin())
|
||||
ParticleManager:SetParticleControl(effectIndex, 5, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystem(effectIndex,false)
|
||||
|
||||
local effectIndex2 = ParticleManager:CreateParticle("particles/heroes/yuyuko/ability_yuyuko_04_effect_d.vpcf", PATTACH_CUSTOMORIGIN, caster)
|
||||
ParticleManager:SetParticleControl(effectIndex2, 0, v:GetOrigin())
|
||||
ParticleManager:DestroyParticleSystemTime(effectIndex2,2.0)
|
||||
|
||||
caster:AbilityKill(v, keys.ability)
|
||||
end
|
||||
end
|
||||
|
||||
caster.thtd_yuyuko_03_think_count = caster.thtd_yuyuko_03_think_count + 1
|
||||
end
|
||||
Reference in New Issue
Block a user