Как определять юнитов с лоухп?

AlexInCube

Пользователь
31 Окт 2018
17
0
1
20
Реакции
0 0 0
#1
Хочу сделать способность, чтобы работала так: Когда у союзного героя здоровье меньше 40%, то наш герой получает бафф к скорости передвижения. Это работает нормально, только если у нас есть 1 союзник, но если их больше 2-х и у одного меньше 40%, а у другого больше 40%, то бафф начинает то появляться, то пропадать.
Код такой:
в Datadriven
Код:
"soraka_salvation"
    {
    "BaseClass" "ability_datadriven"
    "AbilityBehavior" "DOTA_ABILITY_BEHAVIOR_PASSIVE"
    "SpellImmunityType" "SPELL_IMMUNITY_ENEMIES_YES"
    "AbilityTextureName"            "Soraka_Passive"

    "precache"
    {
        "particle"            "particles/units/heroes/hero_bloodseeker/bloodseeker_thirst_owner.vpcf"
        "particle"            "particles/status_fx/status_effect_thirst_vision.vpcf"
        "particle"            "particles/units/heroes/hero_bloodseeker/bloodseeker_vision.vpcf"
    }
    
    // Special
    //-------------------------------------------------------------------------------------------------------------

    "AbilitySpecial"

    {
        "01"
        {
            "var_type" "FIELD_INTEGER"
            "buff_threshold_pct" "40"
        }
        "02"
        {
            "var_type" "FIELD_INTEGER"
            "bonus_movement_speed" "5 10 15 20"
        } 
        "03"
        {
            "var_type" "FIELD_INTEGER"
            "global_radius" "100000"
        }
    } 
    
    

    "Modifiers"
    {
        "modifier_soraka"
        {
            "IsHidden"    "1"
            "Passive"    "1"
                
            "Aura"                    "modifier_soraka_check_health"
            "Aura_Radius"            "%global_radius"
            "Aura_Teams"            "DOTA_UNIT_TARGET_TEAM_FRIENDLY"
            "Aura_Types"            "DOTA_UNIT_TARGET_HERO"
            "Aura_Flags"            "DOTA_UNIT_TARGET_FLAG_NOT_CREEP_HERO"
            "Aura_ApplyToCaster"     "0"
            
            
        }
            
        "modifier_soraka_check_health"
        {
            "IsBuff" "1"
            "IsPurgable" "0"
            "IsHidden"      "0"

            "OnTakeDamage" 
            {
                "RunScript"
                {                             
                    "ScriptFile" "heroes/soraka/salvation.lua"
                    "Function" "CheckHealth"
                }
            }
            "OnHealReceived" 
            {
                "RunScript"
                {                             
                    "ScriptFile" "heroes/soraka/salvation.lua"
                    "Function" "CheckHealth"
                }
            }
            
        } 
            
        "modifier_soraka_buff"
        {
            "IsHidden"    "0"
            "Passive"    "1"
            
            "Properties"
            {
                "MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE" "%bonus_movement_speed"
            }
        }
            
        
    }
    }
в LUA
Код:
function CheckHealth(keys)
 
    local caster = keys.caster -- Hero
    local ability = keys.ability
    local buff_modifier =  "modifier_soraka_buff"

    local buff_threshold = ability:GetLevelSpecialValueFor( "buff_threshold_pct", ability:GetLevel() - 1 )/100
    local target = keys.unit
       local healthPercentage = target:GetHealth() / target:GetMaxHealth()
    local previous_stacks = caster:GetModifierStackCount(buff_modifier, ability)
 
 
    if target:IsAlive() and healthPercentage < buff_threshold then
     
        caster:SetModifierStackCount(buff_modifier, ability, 2)
        else
        caster:SetModifierStackCount(buff_modifier, ability, 0)
    end
end
 

Dangalor

Пользователь
11 Авг 2016
21
0
1
18
Реакции
0 0 0
#2
Зделай проверку в Люа, которая будет выдавать тебе модифаер, и заберать если не осталось целей с лоу хп
Примерно так:
Код:
local hTarget = FindUnitsInRadius(caster:GetTeamNumber(), p(позиция Сараки), nil, 200(твой ренж), DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_HERO, 0, 0, false )
local Pasive_prock = 0
if hTarget ~= nil then
            for k, unit in pairs(hTarget) do
            local healthPercentage = target:GetHealth() / target:GetMaxHealth()
            if target:IsAlive() and healthPercentage < buff_threshold then
            Pasive_prock = Pasive_prock + 1
            end
end

if Pasive_prock => 1 then
caster:SetModifierStackCount(buff_modifier, ability, 2)
else
caster:SetModifierStackCount(buff_modifier, ability, 0)
end

Ну это сама, идея, что бы ты понял логику
 
Последнее редактирование:
20 Дек 2016
618
126
28
11
Проект
DI:LS
Реакции
126 0 0
#3
Это работает нормально, только если у нас есть 1 союзник, но если их больше 2-х и у одного меньше 40%, а у другого больше 40%, то бафф начинает то появляться, то пропадать.
Код такой:

Код:
function CheckHealth(keys)

    local caster = keys.caster -- Hero
    local ability = keys.ability
    local buff_modifier =  "modifier_soraka_buff"

    local buff_threshold = ability:GetLevelSpecialValueFor( "buff_threshold_pct", ability:GetLevel() - 1 )/100
    local target = keys.unit
       local healthPercentage = target:GetHealth() / target:GetMaxHealth()
    local previous_stacks = caster:GetModifierStackCount(buff_modifier, ability)


    if target:IsAlive() and healthPercentage < buff_threshold then

        caster:SetModifierStackCount(buff_modifier, ability, 2)
        else
        caster:SetModifierStackCount(buff_modifier, ability, 0)
    end
end
Это логично, ведь твой код проверяет здоровье то для союзника у которого больше, то у союзника которого меньше, и исходя из результата либо скрывается либо появляется.
Тебе необходимо создать дополнительную таблицу в keys.ability и записывать в нее инфу о юнитах и их здоровье, а потом обрабатывать всю таблицу. Если что, ключи таблицы могут иметь любой тип данных
Код:
-- Создание таблицы с инфой о здоровье союзников, если она еще не создана.
if ability.hp_info == nil then
    ability.hp_info = {}
end
if target:IsAlive() then
    -- Занесение в таблицу инфы о живом союзнике
    ability.hp_info[ target ] = healthPercentage
else
    -- Удаление инфы о союзнике, если он мертв, так как способность не должна учитывать мертвых
    ability.hp_info[ target ] = nil
end
-- Обработка таблицы
local IsActive = false
for unit, unit_hp in pairs(ability.hp_info) do
    if unit_hp < buff_threshold then
        IsActive = true
    end
end
--Дальше сам напиши
if IsActive then
    -- Наложить бафф
else
    -- Снять бафф
end
 
Последнее редактирование:

AlexInCube

Пользователь
31 Окт 2018
17
0
1
20
Реакции
0 0 0
#4
Это логично, ведь твой код проверяет здоровье то для союзника у которого больше, то у союзника которого меньше, и исходя из результата либо скрывается либо появляется.
Тебе необходимо создать дополнительную таблицу в keys.ability и записывать в нее инфу о юнитах и их здоровье, а потом обрабатывать всю таблицу. Если что, ключи таблицы могут иметь любой тип данных
Код:
-- Создание таблицы с инфой о здоровье союзников, если она еще не создана.
if ability.hp_info == nil then
    ability.hp_info = {}
end
if target:IsAlive() then
    -- Занесение в таблицу инфы о живом союзнике
    ability.hp_info[ target ] = healthPercentage
else
    -- Удаление инфы о союзнике, если он мертв, так как способность не должна учитывать мертвых
    ability.hp_info[ target ] = nil
end
-- Обработка таблицы
local IsActive = false
for unit, unit_hp in pairs(ability.hp_info) do
    if unit_hp < buff_threshold then
        IsActive = true
    end
end
--Дальше сам напиши
if IsActive then
    -- Наложить бафф
else
    -- Снять бафф
end
Спасибо за помощь. Я знал что надо как-то с таблицами работать. Я в других своих скиллах их применял и в этом тоже пытался использовать, только я раньше не знал как удалять цель из таблицы, мучался с table.remove но не помогало.
 
Реклама: