Правильный ли подход реализации скила у нейтрального юнита?

FlashDok

Новичок
27 Июн 2023
6
1
Сейчас юнит при атаке можно сказать сразу вызывает lua код, а не использует способность, вопрос это правильный подход к реализации?
Суть абилки такая (пока условие триггера атака) что при атаке юнит кастует способность (сейчас просто выполняется lua, ставится кд и отнимается мана) - вот до этого дошел, но как по мне это костыль какой-то.

Я пытался сделать отдельный lua подключить его в addon_game_mod и там "слушать атаки", если атакует нужный юнит и способности isCastable, то кастуем, но чего-то вообще было 0 реакции - по мне так правильно реализовать скил, потому-что если тригер не атаки юнита, а его кол-во хп например.

Есть юнит с абилкой
"Ability1" "summon_zombie"

Сама абилка

Код:
"summon_zombie"
    {
        // General
        //-------------------------------------------------------------------------------------------------------------
        "BaseClass"                        "ability_lua"
        "AbilityBehavior"                "DOTA_ABILITY_BEHAVIOR_NO_TARGET"
        "ScriptFile"                    "ability/neutral/boss_undying.lua"
        "AbilityCastAnimation"          "ACT_DOTA_ATTACK"

        "MaxLevel"                         "1"

        "AbilityCastPoint"                "3.0"
        "AbilityCooldown"                "20.0"
        "AbilityManaCost"                "20"

    }

Код:
LinkLuaModifier("modifier_summon_zombie", "ability/neutral/boss_undying.lua", LUA_MODIFIER_MOTION_NONE)

require("timers")

-- Класс скилла
summon_zombie = class({})

function summon_zombie:GetIntrinsicModifierName()
    return "modifier_summon_zombie"
end

-- Модификатор для скилла
modifier_summon_zombie = class({
    IsHidden = function(self) return true end,
    DeclareFunctions = function(self) return {
        MODIFIER_EVENT_ON_ATTACK_START
    } end,
})

-- При создании модификатора
function modifier_summon_zombie:OnCreated(kv)
    self.zombieName = "npc_dota_unit_undying_zombie" -- Имя юнита-зомби
    self.team = self:GetParent():GetTeam()
    self.respawnDuration = 2 -- Длительность возрождения зомби
end

function summon(event)
    print("summon")
    local caster = event.caster
    local spawnLoc = caster:GetAbsOrigin()
    local zombieName = "npc_dota_unit_undying_zombie"

    local zombie = CreateUnitByName(zombieName, spawnLoc, true, nil, nil, caster:GetTeam())
    zombie:SetForwardVector(caster:GetForwardVector())
    zombie:SetOwner(caster:GetPlayerOwner())
end


-- При атаке юнита
function modifier_summon_zombie:OnAttackStart(data)
    local attacker = data.attacker
    local ability = self:GetAbility()

    -- Проверяем, что атакующий юнит является владельцем модификатора
    if attacker == self:GetParent() then
        -- Проверяем, что способность не находится в перезарядке и хватает маны
        if ability:IsCooldownReady() and ability:GetManaCost(-1) <= attacker:GetMana() then
            -- Проверяем, что целью атаки является другой юнит (не сам атакующий)
            if data.target and data.target ~= attacker then
                local spawnLoc = attacker:GetAbsOrigin()
                local casterFw = attacker:GetForwardVector()

                -- Создаем юнита-зомби после истечения времени возрождения
                Timers:CreateTimer(self.respawnDuration, function()
                    local zombie = CreateUnitByName(self.zombieName, spawnLoc, true, nil, nil, self.team)
                    zombie:SetForwardVector(casterFw)
                end)

                -- Вычитаем ману у юнита
                attacker:SpendMana(ability:GetManaCost(-1), ability)

                -- Активируем способность
                attacker:CastAbilityNoTarget(ability, -1)

                -- Устанавливаем перезарядку
                ability:StartCooldown(ability:GetCooldown(-1))
            end
        end
    end
end
 

vulkantsk

Супермодератор
Команда форума
21 Июн 2017
1,150
196
www.dotabuff.com
Проект
Roshan defense
У тебя ошибки сыпит, или че ?
Или вообще не запускается скрипт ?

Пока что увидел, то что у твой абилки нету никакого скрипта, поэтому и вызывать нечего
OnSpellStart => ?
Если даже работает то вызываться нечему
 

FlashDok

Новичок
27 Июн 2023
6
1
У тебя ошибки сыпит, или че ?
Или вообще не запускается скрипт ?

Пока что увидел, то что у твой абилки нету никакого скрипта, поэтому и вызывать нечего
OnSpellStart => ?
Если даже работает то вызываться нечему
Сейчас код работает, я так понимаю lua фаил абилки выполняется сразу при спавне юнита (ScriptFile" "ability/neutral/boss_undying.lua"), и на юните весит модификатор, далее когда он атакует абилка срабатывает.

Это я до чего так сказать сам допёр, то и сделал), работает, но я понимаю что это костыль какой-то.

Мне по сути нужно заставить нейтрального юнита закастить абилку (активную).
 

FlashDok

Новичок
27 Июн 2023
6
1
Делаю сейчас по другому, но проблема что .lua подключенный в addon_game_mode будто не работает.


addon_game_mode.lua:
require("bosses/boss_undying") - относительный путь scripts\vscripts\bosses\boss_undying.lua

Ни один print не срабатывает.
Код:
LinkLuaModifier("modifier_boss_undying", "bosses/undying.lua", LUA_MODIFIER_MOTION_NONE)

boss_undying = class({})

BOSS_NAME = "npc_dota_unit_undying_zombie"

function boss_undying:GetIntrinsicModifierName()
    print("321")
    return "modifier_boss_undying"
end

function boss_undying:OnSpellStart()
    local caster = self:GetCaster()
    local target = self:GetCursorTarget()

    if target and not target:IsMagicImmune() then
        caster:CastAbilityOnTarget(target, self, caster:GetPlayerOwnerID())
    end
end

modifier_boss_undying = class({
    IsHidden = function(self) return true end,
    DeclareFunctions = function(self) return {
        MODIFIER_EVENT_ON_DEATH
    } end,
})

function modifier_boss_undying:OnCreated(kv)
    print("222")
    if not IsServer() then return end

    self.boss = self:GetParent()

    self.summonAbility = self.boss:FindAbilityByName("summon_zombie")

    self:StartIntervalThink(1.0)
end

function modifier_boss_undying:OnIntervalThink()
    if not self.boss:IsAlive() then
        return
    end
    print("123")
    local enemiesNearby = FindUnitsInRadius(self.boss:GetTeamNumber(), self.boss:GetAbsOrigin(), nil,
        self.boss:GetAttackRange(), DOTA_UNIT_TARGET_TEAM_ENEMY,
        bit.bor(DOTA_UNIT_TARGET_CREEP, DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_HERO),
        DOTA_UNIT_TARGET_FLAG_NONE, FIND_CLOSEST, false)

    for _, enemy in ipairs(enemiesNearby) do
        if enemy:IsAlive() and not enemy:IsMagicImmune() then
            if self.summonAbility and self.summonAbility:IsCooldownReady() and
                not self.boss:IsSilenced() and not self.boss:IsStunned() and not self.boss:IsHexed()
            then
                self.boss:CastAbilityOnTarget(enemy, self.summonAbility, self.boss:GetPlayerOwnerID())
            end
            break -- Прерываем цикл после первой успешной попытки призвать зомби
        end
    end

    if self.boss:GetHealthPercent() <= 30 then
        -- Дополнительные действия при низком здоровье босса
    end
end

function modifier_boss_undying:OnDeath(event)
    if event.unit == self.boss then
        -- Дополнительные действия при смерти босса
    end
end
 

vulkantsk

Супермодератор
Команда форума
21 Июн 2017
1,150
196
www.dotabuff.com
Проект
Roshan defense
Так ты же можешь внутри абилки прописать поведение, зачем подключать в основнмо файле
 

FlashDok

Новичок
27 Июн 2023
6
1
Так ты же можешь внутри абилки прописать поведение, зачем подключать в основнмо файле
Ну вот так вижу так сказать, а в целом уже реализовал.
Отдельный .lua под юнита в котором "слушается" модификатор скила и уже можно плясать тригерить скилы от разных параметров.
 
  • Влюблен
Реакции: vulkantsk

BazaltGames

Новичок
5 Июл 2023
2
0
@FlashDok в итоге для базового класса ability_lua и поведения DOTA_ABILITY_BEHAVIOR_NO_TARGET у тебя вызывался скрипт? Пытаюсь навесить пустой скрипт на скилл с принтом, но он не вызывается, такое ощущение что нужно задать еще какие-то параметры.
 
Реклама: