Создаём Blade Mail + Aghanim

CrySidingWorld

Друзья CG
31 Май 2019
306
33
Всем привет, хотелось видите ли вы создать гайд об аганиме и как его использовать.

Но как это делать, может показаться очень сложным.
На самом деле, нет это не так сложно, если понять.

Сперва мы должны открыть npc_abilities_custom.txt (в вашем в аддоне/scripts/npc/npc_abilities_custom.txt) он автоматически создаётся при создании аддона (как будто для новичка рассказываю).

Ну и первое создаём имя способности.
И главное отличие DataDriven от луа.
Нужно сменить BaseClass "ability_datadriven" на BaseClass "ability_lua"
Луа не сможет находиться в txt файле и это ясно почему.
Так что надо добавить одну строчку.
ScriptFile "название_луа" автоматически тянет к vscripts даже если не написал.
Дальше вписать все остальное, могу предложить простой шаблон изменяйте как, хотите.

Код:
"example_lua_ability"
{
    "BaseClass"                     "ability_lua"
    "ScriptFile"                    "example_lua_file.lua"
    "AbilityTextureName"            "example_icon"
    "AbilityBehavior"                "DOTA_ABILITY_BEHAVIOR_PASSIVE"
    "SpellImmunityType"                "SPELL_IMMUNITY_ENEMIES_NO" // NO or YES

    //-------------------------------------------------
    // Cast Range
    //-------------------------------------------------
    "AbilityCastRange"                "700"

    //-------------------------------------------------
    //  Cooldown
    //-------------------------------------------------
    "AbilityCooldown"                "32.0 24.0 16.0 8.0"
    "AbilityManaCost"                "30 40 50 60"

    "MaxLevel"                         "4"
  
"AbilitySpecial"
    {
        "01"
        {
            "var_type"            "FIELD_INTEGER"
            "value_chacne"            "10 20 30 40"
        }
    }


}
Думаю уже создали луа файл, который был вписан в ScriptFile.
Теперь что писать в нём?
Сразу пишем на первой строке название способности.
И теперь пишем равно class({}).
Вот так example_lua_ability = class({}).
Теперь дальше пишем:
Код:
LinkLuaModifier("modifier_reflect_damage", "example_lua_file.lua") -- Можно прописать путь к модификатору сюда, тогда не придётся создавать новый луа файл

function example_lua_ability:GetIntrinsicModifierName() -- Используется для применяемых так и для пассивных, применяется модификатор после вкачки способности
    return "modifier_reflect_damage" -- Давайте создадим наподобие Blade Mail.
end

Переходим к модификатору и после функции снизу пишем уже название модификатора, если он расположен здесь.
modifier_reflect_damage = class({})

Теперь давайте сделаем модификатором пассивным и скрытым.

Код:
function modifier_reflect_damage:IsHidden() return true end
function modfier_reflect_damage:IsPassive() return true end
А теперь давайте создадим при создании чтобы все переменные ключи находились в OnCreated() и мы смогли использовать их когда надо.
Код:
function modifier_reflect_damage:OnCreated()
    local ability = self:GetAbility() -- Локал облегчает написанию кода
    self.chance_reflect = ability:GetSpecialValueFor("value_chance") -- self это очень полезная штука она лучше от своего local и её можна использовать в любой функции
end

А теперь создаём событие. Событие будет находиться в DeclareFunctions()
Код:
function modifier_reflect_damage:DeclareFunctions() -- Здесь будут находится ивенты и property(бонусы для героя)
    local prop = {
        MODIFIER_EVENT_ON_TAKEDAMAGE  
    }
    return prop
end
А теперь когда есть событие мы сможем что-то сделать, например отразить урон.
И пишем теперь
Код:
function modifier_reflect_damage:OnTakeDamage( kv ) -- и теперь нам нужно табло которые будем использовать
    local attacker = kv.attacker -- атакующий
    local target = kv.unit -- мы
    local damage = kv.damage -- урон которій нам нанесли
    local damage_type = kv.damage_type -- получаем тип урона который нам нанесли
    local damage_flags = kv.damage_flags -- флаги урона
   
    if attacker ~= self:GetParent() and not attacker:IsBuilding() and damage_flags ~= DOTA_DAMAGE_FLAG_HPLOSS + DOTA_DAMAGE_FLAG_REFLACTION then -- делаем проверку что атакующий не мы и чтобы не отразить урон постройки добавляем и проверка на флаги оно не сработает если будет флаг хп луз или отражение.
        if RollPercentage( self.chance_reflect ) then -- ну вы понял)
            if not target:IsOther() then -- чтобы была не другая цель
                local damage_table = {
                    victim = attacker,
                    attacker = self:GetParent(),
                    ability = self:GetAbility(), -- optional
                    damage = damage,
                    damage_type = damage_type,
                    damage_flags = DOTA_DAMAGE_FLAG_REFLECTION + DOTA_DAMAGE_FLAG_NO_SPELL_LIFESTEAL + DOTA_DAMAGE_FLAG_NO_SPELL_AMPLIFICATION
                }
                ApplyDamage( damage_table )
            end
        end
    end
end
И вот все теперь можем давать герою эту абилку и радоваться.
Ну вот нам этого не хватает и мы хотим аганим.
Тогда если вы хотите аганим например чтобы больше урона наносило вот:
Код:
function modifier_reflect_damage:OnTakeDamage( kv ) -- и теперь нам нужно табло которые будем использовать

    local attacker = kv.attacker -- атакующий

    local target = kv.unit -- мы

    local damage = kv.damage -- урон которій нам нанесли

    local damage_type = kv.damage_type -- получаем тип урона который нам нанесли

    local damage_flags = kv.damage_flags -- флаги урона

   

    if attacker ~= self:GetParent() and not attacker:IsBuilding() and damage_flags ~= DOTA_DAMAGE_FLAG_HPLOSS + DOTA_DAMAGE_FLAG_REFLACTION then -- делаем проверку что атакующий не мы и чтобы не отразить урон постройки добавляем и проверка на флаги оно не сработает если будет флаг хп луз или отражение.

        if RollPercentage( self.chance_reflect ) then -- ну вы понял)

            if not target:IsOther() then -- чтобы была не другая цель
                local damage_table = {

                    victim = attacker,

                    attacker = self:GetParent(),

                    ability = self:GetAbility(), -- optional

                    damage_type = damage_type,

                    damage_flags = DOTA_DAMAGE_FLAG_REFLECTION + DOTA_DAMAGE_FLAG_NO_SPELL_LIFESTEAL + DOTA_DAMAGE_FLAG_NO_SPELL_AMPLIFICATION

                }
                if self:GetParent():HasScepter() then
                    damage = damage * 1.25 -- Damage increased on 25%
                else
                    damage = damage  
                end

                ApplyDamage( damage_table )

            end

        end

    end

end
не забудьте прописать в абилку то что есть аганим).

А теперь давайте возьмемся за продвинутые аганимы.
Создаём на этот раз активную.
Заходим обратно в луа и тут мы делаем.
Код:
function example_lua_ability:GetCooldown( level ) -- С этим табло узнаём уровень.
    -- Делаем проверку
    if self:GetCaster():HasScepter() then
        return 20 -- лучше делайте через ключи
    end
    return self.BaseClass.GetCooldown( self, level ) -- Получаем из дд информацию про перезарядку.
end
Код:
И вот теперь кулдаун будет уменьшаться.
(Тут вот такое увидел, если будет несколько в ключей для кулдауна.)
То будет одно, поверьте оно будет таким же самим, но первый второй не будет видно.

Ну что уже не так сложно?)

А давайте мы изменим манакост или даже поведение, ну как?

Код:
function example_lua_ability:GetManaCost( level )
    if self:GetCaster():HasScepter() then
        return 30
    end
    return self.BaseClass.GetManaCost( self, level )
end

-- Behavior

function example_lua_ability:GetBehavior()
    if self:GetCaster():HasScepter() then
        return DOTA_ABILITY_BEHAVIOR_AOE + DOTA_ABILITIY_BEHAVIOR_UNIT_TARGET
    end
    return self.BaseClass.GetBehavior( self )
end
-- Надо знать что оно не показывает это, но поведение меняется, это же аганим.
А теперь надо добавить AOE.
Код:
function example_lua_ability:GetAOERadius()
    if self:GetCaster():HasScepter() then
        return 300 -- к примеру
    end
    return 0
end
Ооо, а может сделаем чтобы через бкб проходило?!

Код:
function example_lua_ability:CastFilterTarget( target )
    if IsServer() then
        local caster = self:GetCaster()
        
        if not caster:HasScepter() then
            return UF_FAIL_MAGIC_IMMUNE_ENEMIES
        end
        local newResult =  local nResult = UnitFilter( target, self:GetAbilityTargetTeam(), self:GetAbilityTargetType(), DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, self:GetCaster():GetTeamNumber() )
        return newResult
    end
end
И всё теперь вы восхитительные, радуйтесь, а мне у спячку идти
 
Последнее редактирование:
  • Вооу
Реакции: vulkantsk
Реклама: