- 18 Дек 2021
- 337
- 54
- Проект
- Воздух
Pangolier | Старые способности - Heartpiercer
Особенности:Pangolier | Старые способности - Heartpiercer
Шанс срабатывания 15% (меняется в файле npc_abilities_custom - chance_pct)
Замедление скорости передвижения -35%/-40%/-45%/-50% (меняется в файле npc_abilities_custom - slow_pct)
Время задержки до срабатывания 2 (меняется в файле npc_abilities_custom - debuff_delay)
Длительность отрицательного дебаффа 2/3/4/5 (меняется в файле npc_abilities_custom - duration)
Способность полностью отрицает броню.
Вопреки тому, что отражается в интерфейсе, Heartpiercer отрицает всю броню, включая дополнительную, а не только базовую и даваемую атрибутом ловкость.
Lua:
LinkLuaModifier("modifier_heartpiercer_custom", "abilities/cust_heartpiercer", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier("modifier_heartpiercer_custom_delay", "abilities/cust_heartpiercer", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier("modifier_heartpiercer_custom_debuff", "abilities/cust_heartpiercer", LUA_MODIFIER_MOTION_NONE)
heartpiercer_custom = class({})
function heartpiercer_custom:GetIntrinsicModifierName()
return "modifier_heartpiercer_custom"
end
--------------------------------------------------------------------------------
local debuffModName = "modifier_heartpiercer_custom_debuff"
local delayModName = "modifier_heartpiercer_custom_delay"
modifier_heartpiercer_custom = class({})
function modifier_heartpiercer_custom:IsHidden()
return true
end
function modifier_heartpiercer_custom:IsPurgable()
return false
end
function modifier_heartpiercer_custom:RemoveOnDeath()
return false
end
function modifier_heartpiercer_custom:DeclareFunctions()
return {
MODIFIER_EVENT_ON_ATTACK_LANDED
}
end
if IsServer() then
function modifier_heartpiercer_custom:OnAttackLanded(event)
local parent = self:GetParent()
local attacker = event.attacker
local target = event.target
-- Check if attacker exists
if not attacker or attacker:IsNull() then
return
end
-- Check if attacker has this modifier
if attacker ~= parent then
return
end
-- Check if broken
if parent:PassivesDisabled() then
return
end
-- Check if attacked entity exists
if not target or target:IsNull() then
return
end
-- Check if attacked entity is an item, rune or something weird
if target.GetUnitName == nil then
return
end
-- Can't proc on allies, towers, or wards
if UnitFilter(target, DOTA_UNIT_TARGET_TEAM_ENEMY, bit.bor(DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_BASIC), DOTA_UNIT_TARGET_FLAG_NONE, parent:GetTeamNumber()) ~= UF_SUCCESS then
return
end
local ability = self:GetAbility()
local procChance = ability:GetSpecialValueFor("chance_pct") / 100
local prdMult = self:GetStackCount() + 1
-- Roll proc chance
if RandomFloat(0.0, 1.0) <= (ProcRandom:GetProcRandomP(procChance) * prdMult) then
self:SetStackCount(0) -- Reset PRD counter on successful proc
-- If the target already has the debuff, then refresh it
if target:HasModifier(debuffModName) then
target:AddNewModifier(parent, ability, debuffModName, {duration = ability:GetSpecialValueFor("duration")})
-- Only apply the delay handler if the target doesn't already have it
elseif not target:HasModifier(delayModName) then
target:AddNewModifier(parent, ability, delayModName, {duration = ability:GetSpecialValueFor("debuff_delay")})
end
-- Play proc sound
if target:IsHero() then
target:EmitSound("Hero_Pangolier.HeartPiercer")
else
target:EmitSound("Hero_Pangolier.HeartPiercer.Creep")
end
else
-- Didn't proc; increment PRD counter
self:IncrementStackCount()
end
end
end
--------------------------------------------------------------------------------
modifier_heartpiercer_custom_delay = class({})
function modifier_heartpiercer_custom_delay:IsDebuff()
return true
end
function modifier_heartpiercer_custom_delay:IsPurgable()
return true
end
if IsServer() then
function modifier_heartpiercer_custom_delay:OnDestroy()
-- Only apply on expiration and not when purged or removed early
if self:GetRemainingTime() <= 0 then
local ability = self:GetAbility()
local debuffDuration = ability:GetSpecialValueFor("duration")
-- Apply the Heartpiercer debuff
self:GetParent():AddNewModifier(self:GetCaster(), ability, debuffModName, {duration = debuffDuration})
end
end
end
function modifier_heartpiercer_custom_delay:GetEffectAttachType()
return PATTACH_OVERHEAD_FOLLOW
end
function modifier_heartpiercer_custom_delay:GetEffectName()
return "particles/units/heroes/hero_pangolier/pangolier_heartpiercer_delay.vpcf"
end
--------------------------------------------------------------------------------
modifier_heartpiercer_custom_debuff = class({})
function modifier_heartpiercer_custom_debuff:IsDebuff()
return true
end
function modifier_heartpiercer_custom_debuff:IsPurgable()
return true
end
function modifier_heartpiercer_custom_debuff:GetEffectAttachType()
return PATTACH_OVERHEAD_FOLLOW
end
function modifier_heartpiercer_custom_debuff:GetEffectName()
return "particles/units/heroes/hero_pangolier/pangolier_heartpiercer_debuff.vpcf"
end
function modifier_heartpiercer_custom_debuff:OnCreated(keys)
local parent = self:GetParent()
local slow_pct = self:GetAbility():GetSpecialValueFor("slow_pct")
if IsServer() then
if parent:IsHero() then
parent:EmitSound("Hero_Pangolier.HeartPiercer.Proc")
else
parent:EmitSound("Hero_Pangolier.HeartPiercer.Proc.Creep")
end
end
self.slow = slow_pct --parent:GetValueChangedBySlowResistance(slow_pct)
end
function modifier_heartpiercer_custom_debuff:OnRefresh()
self:OnCreated()
end
function modifier_heartpiercer_custom_debuff:DeclareFunctions()
return {
MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE,
MODIFIER_PROPERTY_PHYSICAL_ARMOR_BONUS,
}
end
function modifier_heartpiercer_custom_debuff:GetModifierMoveSpeedBonus_Percentage()
return self.slow
end
function modifier_heartpiercer_custom_debuff:GetModifierPhysicalArmorBonus()
return -self:GetParent():GetPhysicalArmorBaseValue()
end
ProcRandom = ProcRandom or {}
ProcRandom.cache = ProcRandom.cache or {}
function ProcRandom.GetProcRandom(c)
local pProcByN = 0
local expectedN = 0
local maxN = math.ceil(1 / c)
for n = 1, maxN do
local pProcOnN = math.min(1, n * c) * (1 - pProcByN)
pProcByN = pProcByN + pProcOnN
expectedN = expectedN + pProcOnN * n
end
return 1 / expectedN
end
function ProcRandom:GetProcRandomP(p)
if self.cache[p] then
return self.cache[p]
end
local cUpper = p
local cLower = 0
local prevP = p
while true do
local cMid = (cUpper + cLower) / 2
local currentP = self.GetProcRandom(cMid)
if currentP == prevP then
self.cache[p] = cMid
return cMid
end
if currentP > p then
cUpper = cMid
else
cLower = cMid
end
prevP = currentP
end
end
Код:
"heartpiercer_custom"
{
"BaseClass" "ability_lua"
"ScriptFile" "abilities/cust_heartpiercer"
"AbilityTextureName" "pangolier_heartpiercer"
"AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
"SpellImmunityType" "SPELL_IMMUNITY_ENEMIES_NO"
"SpellDispellableType" "SPELL_DISPELLABLE_YES"
"MaxLevel" "4"
"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"chance_pct" "15"
}
"02"
{
"var_type" "FIELD_INTEGER"
"slow_pct" "-35 -40 -45 -50"
}
"03"
{
"var_type" "FIELD_FLOAT"
"debuff_delay" "2.0"
}
"04"
{
"var_type" "FIELD_FLOAT"
"duration" "2.0 3.0 4.0 5.0"
}
}
}
Код:
"DOTA_Tooltip_Ability_heartpiercer_custom" "Heartpiercer"
"DOTA_Tooltip_Ability_heartpiercer_custom_Description" "Герой видит врагов насквозь, искусно пронзая их броню. Каждая атака может сбросить броню цели, а также наложить замедление передвижения. Эффект активируется с небольшой задержкой после срабатывания."
"DOTA_Tooltip_Ability_heartpiercer_custom_Lore" "Эти глупцы не ведают, что такое настоящая броня..."
"DOTA_Tooltip_Ability_heartpiercer_custom_chance_pct" "%Шанс срабатывания: "
"DOTA_Tooltip_Ability_heartpiercer_custom_slow_pct" "%Замедление передвижения: "
"DOTA_Tooltip_Ability_heartpiercer_custom_debuff_delay" "Задержка активации: "
"DOTA_Tooltip_Ability_heartpiercer_custom_duration" "Длительность: "
"DOTA_Tooltip_modifier_heartpiercer_custom_delay" "Heartpiercer"
"DOTA_Tooltip_modifier_heartpiercer_custom_delay_Description" "Броня сломлена"
"DOTA_Tooltip_modifier_heartpiercer_custom_debuff" "Heartpiercer"
"DOTA_Tooltip_modifier_heartpiercer_custom_debuff_Description" "Броня разбита"
У вас уже должна быть база (какой то начальный проект)
Установка в 3х пунктах:
Установка в 3х пунктах:
Берем из спойлера - LUA
2.1] Идем по пути: :\steam\steamapps\common\dota 2 beta\game\dota_addons\\scripts\vscripts\ ( - диск, ** - ваша карта) p.s. По желанию можно разделить папками ваши абилки
Пример из сборника пассивок: :\steam\steamapps\common\dota 2 beta\game\dota_addons\***\scripts\vscripts\hero\Passive (Добавилась 1 папка и подпапка)
2.2] Создаем файл с расширением *.lua и вставляем в него код
2.3] Если у вас другие папки/подпапки или вовсе вы создали *.lua в корне vscripts то редактируем путь в коде:
Находим строчку: LinkLuaModifier("modifier_legion_Armor", "heroes/Passive/legion_Armor", LUA_MODIFIER_MOTION_NONE)
Меняем в кавычках путь: "heroes/Passive/legion_Armor" => "Ваш путь к LUA, без расширения *.lua"
P.S. Если вы оставили скрипт в корне VSCRIPTS => Путь будет: "Ваше название скрипта, без расширения *.lua"
P.s. содержание строки зависит от пассивки/модификатора, главное это путь к скрипту!
2.1] Идем по пути: :\steam\steamapps\common\dota 2 beta\game\dota_addons\\scripts\vscripts\ ( - диск, ** - ваша карта) p.s. По желанию можно разделить папками ваши абилки
Пример из сборника пассивок: :\steam\steamapps\common\dota 2 beta\game\dota_addons\***\scripts\vscripts\hero\Passive (Добавилась 1 папка и подпапка)
2.2] Создаем файл с расширением *.lua и вставляем в него код
2.3] Если у вас другие папки/подпапки или вовсе вы создали *.lua в корне vscripts то редактируем путь в коде:
Находим строчку: LinkLuaModifier("modifier_legion_Armor", "heroes/Passive/legion_Armor", LUA_MODIFIER_MOTION_NONE)
Меняем в кавычках путь: "heroes/Passive/legion_Armor" => "Ваш путь к LUA, без расширения *.lua"
P.S. Если вы оставили скрипт в корне VSCRIPTS => Путь будет: "Ваше название скрипта, без расширения *.lua"
P.s. содержание строки зависит от пассивки/модификатора, главное это путь к скрипту!
Берем из спойлера - Абилку
1.1] Идем по пути: :\steam\steamapps\common\dota 2 beta\game\dota_addons\***\npc\ в файлик: npc_abilities_custom.txt
1.2] Вставляем абилку между фигурных скобок
"DOTAAbilities"
{
}
1.3] Строки:
"ScriptFile" "heroes/passive/legion_Armor" - ПУТЬ К LUA файлу (P.S. Если вы оставили скрипт в корне VSCRIPTS => Путь будет: "Ваше название скрипта, без расширения *.lua")
"AbilityTextureName" "specal/armor" - ПУТЬ К Иконке 128х128 .png (Полный путь: :\steam\steamapps\common\dota 2 beta\game\dota_addons\**\resource\flash3\images\spellicons\specal\)
1.1] Идем по пути: :\steam\steamapps\common\dota 2 beta\game\dota_addons\***\npc\ в файлик: npc_abilities_custom.txt
1.2] Вставляем абилку между фигурных скобок
"DOTAAbilities"
{
}
1.3] Строки:
"ScriptFile" "heroes/passive/legion_Armor" - ПУТЬ К LUA файлу (P.S. Если вы оставили скрипт в корне VSCRIPTS => Путь будет: "Ваше название скрипта, без расширения *.lua")
"AbilityTextureName" "specal/armor" - ПУТЬ К Иконке 128х128 .png (Полный путь: :\steam\steamapps\common\dota 2 beta\game\dota_addons\**\resource\flash3\images\spellicons\specal\)
Берем из спойлера - Ру локаль, от абилки
3.1]Идем по пути: :\steam\steamapps\common\dota 2 beta\game\dota_addons\\resource\ ( - диск, ** - ваша карта)
3.2] Открываем / создаем файлик: addon_russian.txt
3.3] Вставляем строки между:
"lang"
{
"Language" "russian"
"Tokens"
{
"addon_game_name" "Название вашей карты на ру"
Вот сюда уже строки
}
}
3.1]Идем по пути: :\steam\steamapps\common\dota 2 beta\game\dota_addons\\resource\ ( - диск, ** - ваша карта)
3.2] Открываем / создаем файлик: addon_russian.txt
3.3] Вставляем строки между:
"lang"
{
"Language" "russian"
"Tokens"
{
"addon_game_name" "Название вашей карты на ру"
Вот сюда уже строки
}
}
Взят с открытого GitHub oаa