Что такое kv?

BombasterDS

Пользователь
27 Мар 2023
24
0
Никак не могу понять, что такое kv
К примеру, я делаю пассивку, у которой эффект схож со старой пассивкой Underlord'а, которая давала перманентный бафф урона - https://github.com/Elfansoer/dota-2...nderlord_atrophy_aura_lua_permanent_stack.lua. Функции OnCreated(kv) и OnRefresh(kv), как раз и требуют этого kv.
Как я посмотрел, ни в одном файле этой пассивки нет какой-нибудь инициализации этой kv, в то время как у меня в коде значение kv выдает nil (проверил через print)
К тому же, я заметил что это kv используется еще во многих других способностях. а я прям вообще не могу понять что это такое.
 
Мне ChatGPT подобное писал, но я не могу понять на практике, где находятся эти файлы или как их задавать. Вот на этом же примере, где находится этот KV файл, который идет в функции OnCreated (kv) или OnRefreshed(kv)? Я так и не смог этого найти
 
Мне ChatGPT подобное писал, но я не могу понять на практике, где находятся эти файлы или как их задавать. Вот на этом же примере, где находится этот KV файл, который идет в функции OnCreated (kv) или OnRefreshed(kv)? Я так и не смог этого найти
Вот пример:
Код:
function TalentTree:Initialize()
    if not IsServer() or TalentTree.initialized then
        return
    end

    -- объявление переменных и кв
    self.abilitiesData = LoadKeyValues("scripts/npc/npc_hero_talents.txt")
    local data = LoadKeyValues("scripts/kv/hero_talents.txt")
    self.talentsData = {}
    self.tabs = {}
    self.rows = {}
    if not data then
        print("[TalentTree] Error loading scripts/kv/hero_talents.txt.")
        return
    end
    if not next(data["HeroesTalents"], nil) then
        print("[TalentTree] Can't find talents data.")
        return
    end

    local loclenght = 1
    local locarr = {}
    -- инициализация талантов
    for hero, talents in pairs(data['HeroesTalents']) do
        self.tabs[hero] = self.tabs[hero] or {}
        self.talentsData[hero] = self.talentsData[hero] or {}
        self.rows[hero] = self.rows[hero] or {}
        for tabName, tabData in pairs(talents) do
            table.insert(self.tabs[hero], tabName)
            -- проход по вкладкам
            for nlvl, talents in pairs(tabData) do
                -- проход по строчкам
                table.insert(self.rows[hero], tonumber(nlvl))
                -- проход по талантам
                for _, talent in pairs(talents) do
                    local talentData = {
                        Ability = talent,
                        Tab = #self.tabs[hero],
                        NeedLevel = tonumber(nlvl)
                    }
                    if self.abilitiesData[talent] then
                        talentData.MaxLevel = self.abilitiesData[talent]["MaxLevel"] or 4
                    else
                        talentData.MaxLevel = 4
                    end
                    table.insert(self.talentsData[hero], talentData)
                end
            end
        end
        table.sort(self.rows[hero])
        loclenght = 1
        locarr = {}
        for i = 1, #self.rows[hero] do
            if locarr[self.rows[hero][i]] == nil then
                locarr[self.rows[hero][i]] = loclenght
                loclenght = loclenght + 1
            end
        end
        self.rows[hero] = locarr
    end

    TalentTree:InitPanoramaEvents()

    self.talentData = data
    ListenToGameEvent('dota_player_gained_level', Dynamic_Wrap(self, 'OnPlayerLevelUp'), self)

    TalentTree.initialized = true
    print("[TalentTree] TalentTree initialized.")
end
...\pizdataya_map\scripts\kv - путь к папке kv


То, что ты нашел - исходный код на гите, скорее всего использует внутреннее дотовское kv


  • OnCreated( kv ) -- Called when the modifier is created, with a table of values in "kv". Client/Server. No return type.
  • OnRefresh( kv ) -- Called when the modifier is refreshed (created when already existing ). Client/Server, No return type.
Из вики
 
У доты есть внутреннее kv?
У меня на работе нет скачаной доты что бы открыть файл:
ЦИТИРУЮ
"файл всех способностей находится steam\steamapps\common\dota 2 beta\game\dota\pak01_dir
Его необходимо открыть через прогу gcfscape после чего идем в папку scpits/npc
В этой папке находятся все базовые конфиги из доты, сохрани их себе.
activelist - список героев
items - конфиг всех предметов
neutral_items - настройка доступных нейтральных предметов
npc_abilities - конфиг всех способностей ( именно в нем ты можешь узнать параметры нужной тебе способности)
npc_heroes - конфиг всех героев
npc_units - конфиг всех юнитов
Всё остальное по желанию..."
Там же скорее всего ты найдешь KV
 
У меня на работе нет скачаной доты что бы открыть файл:
ЦИТИРУЮ
"файл всех способностей находится steam\steamapps\common\dota 2 beta\game\dota\pak01_dir
Его необходимо открыть через прогу gcfscape после чего идем в папку scpits/npc
В этой папке находятся все базовые конфиги из доты, сохрани их себе.
activelist - список героев
items - конфиг всех предметов
neutral_items - настройка доступных нейтральных предметов
npc_abilities - конфиг всех способностей ( именно в нем ты можешь узнать параметры нужной тебе способности)
npc_heroes - конфиг всех героев
npc_units - конфиг всех юнитов
Всё остальное по желанию..."
Там же скорее всего ты найдешь KV
Хорошо, спасибо за помощь
 
В целом если правильно понимаю, вики
То приписка (kv) - это мол серверная/клиентская часть

А твоя способность - из гитхаба - разбита на несколько кусков lua + txt прям там же

Код:
-- Initializations
function modifier_underlord_atrophy_aura_lua:OnCreated( kv )
    -- references
    self.radius = self:GetAbility():GetSpecialValueFor( "radius" )
    self.hero_bonus = self:GetAbility():GetSpecialValueFor( "bonus_damage_from_hero" )
    self.creep_bonus = self:GetAbility():GetSpecialValueFor( "bonus_damage_from_creep" )
    self.bonus = self:GetAbility():GetSpecialValueFor( "permanent_bonus" )
    self.duration = self:GetAbility():GetSpecialValueFor( "bonus_damage_duration" )
    self.duration_scepter = self:GetAbility():GetSpecialValueFor( "bonus_damage_duration_scepter" )

    if not IsServer() then return end

    -- create scepter modifier
    self.scepter_aura = self:GetParent():AddNewModifier(
        self:GetParent(), -- player source
        self:GetAbility(), -- ability source
        "modifier_underlord_atrophy_aura_lua_scepter", -- modifier name
        {} -- kv
    )
end
Код:
"DOTAAbilities"
{
    //=================================================================================================================
    // Underlord: Atrophy Aura (Lua version)
    //=================================================================================================================
    "underlord_atrophy_aura_lua"
    {
        // Ability Technical Aspect
        // base script folder    : scripts/vscripts
        // base texture folder    : resource/flash3/images/spellicons
        //-------------------------------------------------------------------------------------------------------------
        "BaseClass"                        "ability_lua"
        "ScriptFile"                    "lua_abilities/underlord_atrophy_aura_lua/underlord_atrophy_aura_lua"
        "AbilityTextureName"            "underlord_atrophy_aura_lua"
        "FightRecapLevel"                "1"
        "MaxLevel"                        "4"
        "HasScepterUpgrade"                "1"

        "precache"
        {
            "soundfile"    "soundevents/game_sounds_heroes/game_sounds_abyssal_underlord.vsndevts"
//            "particle"    "particles/units/heroes/hero_<hero>/<hero>_<ability>.vpcf"
        }
       
        // Ability General
        //-------------------------------------------------------------------------------------------------------------
        "AbilityType"                    "DOTA_ABILITY_TYPE_BASIC"
        "AbilityBehavior"                "DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AURA"
        "AbilityUnitTargetTeam"            "DOTA_UNIT_TARGET_TEAM_ENEMY"
        "SpellDispellableType"            "SPELL_DISPELLABLE_NO"  
       
        // Ability Casting
        //-------------------------------------------------------------------------------------------------------------
        "AbilityCastRange"                "1200"

        // Ability Resource
        //-------------------------------------------------------------------------------------------------------------

        // Damage
        //-------------------------------------------------------------------------------------------------------------

        // Special
        //-------------------------------------------------------------------------------------------------------------
        "AbilitySpecial"
        {
            "01"
            {
                "var_type"                        "FIELD_INTEGER"
                "radius"                        "1200"
            }
            "02"
            {
                "var_type"                        "FIELD_INTEGER"
                "damage_reduction_pct"            "5 15 25 35"
            }
            "03"
            {
                "var_type"                        "FIELD_INTEGER"
                "bonus_damage_from_creep"        "5"
            }
            "04"
            {
                "var_type"                        "FIELD_INTEGER"
                "bonus_damage_from_hero"        "30 35 40 45"
            }
            "05"
            {
                "var_type"                        "FIELD_FLOAT"
                "bonus_damage_duration"            "30 40 50 60"
            }
            "06"
            {
                "var_type"                        "FIELD_FLOAT"
                "bonus_damage_duration_scepter"        "70 80 90 100"
                "RequiresScepter"    "1"
            }
            "07"
            {
                "var_type"                        "FIELD_INTEGER"
                "permanent_bonus"        "2 3 4 5"
            }
        }
    }
}
Код:
-- Initializations
function modifier_underlord_atrophy_aura_lua_permanent_stack:OnCreated( kv )
    if not IsServer() then return end
    self:SetStackCount( kv.bonus )
end

function modifier_underlord_atrophy_aura_lua_permanent_stack:OnRefresh( kv )
    if not IsServer() then return end
    self:SetStackCount( self:GetStackCount() + kv.bonus )
end

Получается - что он откидывает в сервер описания - и обновляет их на клиенте + kv.bonus - чем является "permanent_bonus" "2 3 4 5"
 
Изначально твой вопрос, стоит немного не так - ибо файлы в папке KV - это "(Key Values) - это формат файлов, используемый для хранения конфигурации игровых объектов, таких как герои, предметы и способности. Файлы KV содержат список пар "ключ-значение", который определяет свойства объекта."

А именно
Функции OnCreated(kv) и OnRefresh(kv)
OnCreated( kv ) -- Called when the modifier is created, with a table of values in "kv". Client/Server. No return type.
OnRefresh( kv ) -- Called when the modifier is refreshed (created when already existing ). Client/Server, No return type.
 
В целом если правильно понимаю, вики
То приписка (kv) - это мол серверная/клиентская часть

А твоя способность - из гитхаба - разбита на несколько кусков lua + txt прям там же

Код:
-- Initializations
function modifier_underlord_atrophy_aura_lua:OnCreated( kv )
    -- references
    self.radius = self:GetAbility():GetSpecialValueFor( "radius" )
    self.hero_bonus = self:GetAbility():GetSpecialValueFor( "bonus_damage_from_hero" )
    self.creep_bonus = self:GetAbility():GetSpecialValueFor( "bonus_damage_from_creep" )
    self.bonus = self:GetAbility():GetSpecialValueFor( "permanent_bonus" )
    self.duration = self:GetAbility():GetSpecialValueFor( "bonus_damage_duration" )
    self.duration_scepter = self:GetAbility():GetSpecialValueFor( "bonus_damage_duration_scepter" )

    if not IsServer() then return end

    -- create scepter modifier
    self.scepter_aura = self:GetParent():AddNewModifier(
        self:GetParent(), -- player source
        self:GetAbility(), -- ability source
        "modifier_underlord_atrophy_aura_lua_scepter", -- modifier name
        {} -- kv
    )
end
Код:
"DOTAAbilities"
{
    //=================================================================================================================
    // Underlord: Atrophy Aura (Lua version)
    //=================================================================================================================
    "underlord_atrophy_aura_lua"
    {
        // Ability Technical Aspect
        // base script folder    : scripts/vscripts
        // base texture folder    : resource/flash3/images/spellicons
        //-------------------------------------------------------------------------------------------------------------
        "BaseClass"                        "ability_lua"
        "ScriptFile"                    "lua_abilities/underlord_atrophy_aura_lua/underlord_atrophy_aura_lua"
        "AbilityTextureName"            "underlord_atrophy_aura_lua"
        "FightRecapLevel"                "1"
        "MaxLevel"                        "4"
        "HasScepterUpgrade"                "1"

        "precache"
        {
            "soundfile"    "soundevents/game_sounds_heroes/game_sounds_abyssal_underlord.vsndevts"
//            "particle"    "particles/units/heroes/hero_<hero>/<hero>_<ability>.vpcf"
        }
      
        // Ability General
        //-------------------------------------------------------------------------------------------------------------
        "AbilityType"                    "DOTA_ABILITY_TYPE_BASIC"
        "AbilityBehavior"                "DOTA_ABILITY_BEHAVIOR_PASSIVE | DOTA_ABILITY_BEHAVIOR_AURA"
        "AbilityUnitTargetTeam"            "DOTA_UNIT_TARGET_TEAM_ENEMY"
        "SpellDispellableType"            "SPELL_DISPELLABLE_NO" 
      
        // Ability Casting
        //-------------------------------------------------------------------------------------------------------------
        "AbilityCastRange"                "1200"

        // Ability Resource
        //-------------------------------------------------------------------------------------------------------------

        // Damage
        //-------------------------------------------------------------------------------------------------------------

        // Special
        //-------------------------------------------------------------------------------------------------------------
        "AbilitySpecial"
        {
            "01"
            {
                "var_type"                        "FIELD_INTEGER"
                "radius"                        "1200"
            }
            "02"
            {
                "var_type"                        "FIELD_INTEGER"
                "damage_reduction_pct"            "5 15 25 35"
            }
            "03"
            {
                "var_type"                        "FIELD_INTEGER"
                "bonus_damage_from_creep"        "5"
            }
            "04"
            {
                "var_type"                        "FIELD_INTEGER"
                "bonus_damage_from_hero"        "30 35 40 45"
            }
            "05"
            {
                "var_type"                        "FIELD_FLOAT"
                "bonus_damage_duration"            "30 40 50 60"
            }
            "06"
            {
                "var_type"                        "FIELD_FLOAT"
                "bonus_damage_duration_scepter"        "70 80 90 100"
                "RequiresScepter"    "1"
            }
            "07"
            {
                "var_type"                        "FIELD_INTEGER"
                "permanent_bonus"        "2 3 4 5"
            }
        }
    }
}
Код:
-- Initializations
function modifier_underlord_atrophy_aura_lua_permanent_stack:OnCreated( kv )
    if not IsServer() then return end
    self:SetStackCount( kv.bonus )
end

function modifier_underlord_atrophy_aura_lua_permanent_stack:OnRefresh( kv )
    if not IsServer() then return end
    self:SetStackCount( self:GetStackCount() + kv.bonus )
end

Получается - что он откидывает в сервер описания - и обновляет их на клиенте + kv.bonus - чем является "permanent_bonus" "2 3 4 5"
То что он разбит на несколько файлов я понял, находил точно такой же код в одном файле. По поводу kv не знаю, т.к он возвращал мне значение nil
 
Изначально твой вопрос, стоит немного не так - ибо файлы в папке KV - это "(Key Values) - это формат файлов, используемый для хранения конфигурации игровых объектов, таких как герои, предметы и способности. Файлы KV содержат список пар "ключ-значение", который определяет свойства объекта."

А именно
Функции OnCreated(kv) и OnRefresh(kv)
OnCreated( kv ) -- Called when the modifier is created, with a table of values in "kv". Client/Server. No return type.
OnRefresh( kv ) -- Called when the modifier is refreshed (created when already existing ). Client/Server, No return type.
Ну тут говорится, что OnCreated (kv) вызывается когда модификатор создан с таблицей значений в kv (если правильно перевел). Я через print проверял значения kv, у меня выводилось nil
 
В связи с тем, что там дохуя и больше self он не может тебе дать конкретики - тебе надо условно говоря вывести в принт

Код:
function modifier_underlord_atrophy_aura_lua_permanent_stack:GetModifierPreAttack_BonusDamage()
    return self:GetStackCount()
end
Значения этой функции - только вместо self полный путь дать))
 
Но лучше сразу выводи значения в тултип - меньше ебли и сразу видно будет
 
Дота до этого момента не доходит, выдается ошибка по поводу неправильного ввода данных в функцию OnCreated
 
Реклама: