[SourcePawn] Урок 8 - Структуры Key Values

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Допустим у меня такая структура

C-подобный:
"sound_1"
{
    "sound"
    {   
        "1"
        {
            "wav"    "1.wav"
        }
        
        "2"
        {
            "wav"    "2.wav"
        }
        
        "3"
        {
            "wav"    "3.wav"
        }
    }
}
1. Можно ли сделать так, что бы была пробежка по всем ключам и при заходе они все скачивались, а не только самый последний ключ(или первый). Или лучше делать это с помощью файла загрузки?

2. Можно ли сделать их работу рандомной, а не опять же только первый/последний.

Путь ключа вызывается в эвенте, на пример музыка при старте раунда или картинка при убийстве. Да бы они были рандомны и качались при заходе.


C-подобный:
void KvWriteToFile(const char[] sPath)
{
    hKeyValues = new KeyValues("icon");
    
    if(hKeyValues.ImportFromFile(sPath))
    {
        hKeyValues.Rewind();    //Прыгаем в начало
        hKeyValues.GotoFirstSubKey();
        {
            //hKeyValues.GotoNextKey();
            do
            {
                if(hKeyValues.GotoFirstSubKey(true))    // попали в саб-ключ "sVMT" (саб-ключ, это значит что есть ключ и значение к нему справа)
                {
                    Format(sBuffer, sizeof(sBuffer), "%s.vmt", sVmt);
                    hKeyValues.GetString("vmt", sBuffer, sizeof(sBuffer), "Путь не считался с конфига");    // тут берем информацию ключа, то есть путь к материалам
                }
            }
            while(hKeyValues.GotoNextKey());    // будем прыгать по всем ключам внутри ключа "icon_c4"
        }
    }
}
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #22
@Nekro, "последний/первый ключ" ты имеешь ввиду внутри секции "sound" ?
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #24
@Nekro, почему hKeyValues.GotoFirstSubKey(); а не hKeyValues.JumpToKey("sound"); ?

а if(hKeyValues.GotoFirstSubKey(true)) вынеси за цикл, проблема в том что в каждой итерации цикла он пытается прыгнуть глубже.
 

Tomiks

Участник
Сообщения
419
Реакции
288
@Nekro ещё вот здесь, если не ошибаюсь, надо NULL_STRING, а не имя ключа, т.к. ты по факту прыгаешь на него как на отдельную секции и оно не может найти там ключ с таким названием
1604752286333.png
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #27
@Nekro ещё вот здесь, если не ошибаюсь, надо NULL_STRING, а не имя ключа, т.к. ты по факту прыгаешь на него как на отдельную секции и оно не может найти там ключ с таким названием
вряд ли. ему именно вмт нужен
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
@R1KO,
C-подобный:
void KvWriteToFile(const char[] sPath)
{
    hKeyValues = new KeyValues("icon");
    
    if(hKeyValues.ImportFromFile(sPath))
    {
        hKeyValues.Rewind();    //Прыгаем в начало
        hKeyValues.JumpToKey("icon_c4");        //hKeyValues.GotoFirstSubKey();
        {
            if(hKeyValues.GotoFirstSubKey(true))    // попали в саб-ключ "sVMT" (саб-ключ, это значит что есть ключ и значение к нему справа)
            do
            {
                {
                    Format(sBuffer, sizeof(sBuffer), "%s.vmt", sVmt);
                    hKeyValues.GetString("vmt", sBuffer, sizeof(sBuffer), "Путь не считался с конфига");    // тут берем информацию ключа, то есть путь к материалам
                }
            }
            while(hKeyValues.GotoNextKey());    // будем прыгать по всем ключам внутри ключа "icon_c4"
        }
    }
}
Стартует всегда только последний ключ

C-подобный:
"icon"
{
    "icon_c4"
    {   
        "1"
        {
            "vmt"    "materials/killmessages/ggwp/3v/killsilver_victory_t.vmt"
        }
        
        "2"
        {
            "vmt"    "materials/killmessages/ggwp/3v/killsilver_grenade.vmt"
        }
        
        "3"
        {
            "vmt"    "materials/killmessages/ggwp/3v/killsilver_knife.vmt"
        }
    }
}
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #30
@Nekro, ты скинул огрызок не работающего кода.

C++:
void KvLoadFile(const char[] sPath)
{
    hKeyValues = new KeyValues("icon");
   
    if(hKeyValues.ImportFromFile(sPath))
    {
        hKeyValues.Rewind();    //Прыгаем в начало
        if (hKeyValues.JumpToKey("icon_c4"))
        {
            if(hKeyValues.GotoFirstSubKey())
            {
                char sBuffer[256];
                do
                {
                    hKeyValues.GetString("vmt", sBuffer, sizeof(sBuffer));
                    if (sBuffer[0]) // значение есть
                    {
                       
                    }
                }
                while(hKeyValues.GotoNextKey());    // будем прыгать по всем ключам внутри ключа "icon_c4"
            }
        }
    }
}
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #31
всё решили. проблема не в кв
 

Dragokas

Добрая душа
Сообщения
229
Реакции
213
@R1KO можно пожелание? - добавить в ваше описание работы функции GetSectionName мааааленькую пометку о том, что нельзя полагаться на регистр букв получаемого результата.

Чтобы такие нубасы как я не попадались на эту уловку :D
 

Der Helfer

[WCS] Пытается оживить Страйкера
Сообщения
60
Реакции
20
skill_random.ini:
"Skills"
{
    "speed"
    {
        "speed ="       "1"
        "speed ="       "2"
    }
    "gravity"
    {
        "gravity ="     "1"
        "gravity ="     "0.5"
    }
}

Как рандомно выбрать один из ключей и также рандомно параметр?
 

DENFER

Пишу плагины за два биг тести и картошку фри..
Сообщения
260
Реакции
289
skill_random.ini:
"Skills"
{
    "speed"
    {
        "speed ="       "1"
        "speed ="       "2"
    }
    "gravity"
    {
        "gravity ="     "1"
        "gravity ="     "0.5"
    }
}

Как рандомно выбрать один из ключей и также рандомно параметр?
Высчитываешь число ключей в структуре и при помощи GetRandomInt(1, N), там где N - число ключей, получаешь случайный ключ. Аналогично и с параметрами, когда выбрал ключ в нем пробегаешься по саб-ключам, вычисляешь их количество и получаешь случайный саб-ключ при помощи GetRandomInt(1, N), там где N - число саб-ключей.
 

Der Helfer

[WCS] Пытается оживить Страйкера
Сообщения
60
Реакции
20
Высчитываешь число ключей в структуре и при помощи GetRandomInt(1, N), там где N - число ключей, получаешь случайный ключ. Аналогично и с параметрами, когда выбрал ключ в нем пробегаешься по саб-ключам, вычисляешь их количество и получаешь случайный саб-ключ при помощи GetRandomInt(1, N), там где N - число саб-ключей.
Спасибо за помощь
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@Der Helfer, у тебя будет читаться только первая запись: имена ключей должны отличаться хотя бы одним символом
 

Der Helfer

[WCS] Пытается оживить Страйкера
Сообщения
60
Реакции
20

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Возьмем KV:
PHP:
"GlobalKey"
{
    "key1"
    {
        "param1"    "value1"
        "param2"    "value2"
    }

    "key2"
    {
        "param1"    "value1"
        "param2"    "value2"
    }

    "key3"
    {
        "param1"    "value1"
        "param2"    "value2"
    }

    "key4"
    {
        "param1"    "value1"
        "param2"    "value2"
    }
}
PHP:
// Вернем указатель в начало
hKeyValues.Rewind();
if(hKeyValues.GotoFirstSubKey()) // Переходим к первому ключу внутри "GlobalKey"
{
    // тут мы попали в ключ "key1"
    do    // Создаем цикл с послеусловием
    {
        // тут можем выполнять какие-то действия с ключем
    } while (hKeyValues.GotoNextKey()); // Условие продолжения цикла: До тех пор, пока можем перейти к следующему ключу
    // Это цикл поочередно пройдет по ключам: "key1" (тут мы уже и так стоим), "key2", "key3", "key4".
}
А как пробежать сразу и по Key1 и по всем их param1 и param2 ?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@Nekro, в do {%вот_тут%} while() читаешь значения просто
 
Сверху Снизу