initial commit
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user