Files
2HUCardTDGame/scripts/vscripts/abilities/abilityshinki.lua
2021-10-24 15:36:18 -04:00

395 lines
14 KiB
Lua
Executable File

-- 是否魔界
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