Keyvalues

Тема в разделе "Программирование / Скриптинг", создана пользователем Hejter, 10 дек 2015.

  1. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Не создает больше 1 ящика, точнее записывается в конфиг всего лишь одна строка.
    PHP:
    public Action:Command_Create(clientargs
    {
        if (!
    client || !IsClientInGame(client))
        {
            
    ReplyToCommand(client"ERROR: You can't use that command while not in game!");
            return 
    Plugin_Handled;
        }
        
        
    decl Float:pos[3];
        if (
    kv_cfg != INVALID_HANDLE && GetPlayerEye(clientpos))
        {
            
    pos[2] += 30.0;
            
    KvJumpToKey(kv_cfgg_cMaptrue);
            {
                
    KvGotoFirstSubKey(kv_cfg);
                
    KvSetVector(kv_cfg"crate"pos);
            }
            
    KvRewind(kv_cfg);
            
    KeyValuesToFile(kv_cfgg_cfg_file);
            
    PrintToChat(client"%s: %d:%d:%d""Ящик создан"pos[0], pos[1], pos[2]);
        }
        else
        {
            
    PrintToChat(client"%s""Произошла ошибка.");
        }
        
        return 
    Plugin_Handled;
    }

    Каждую новую карту загружаю конфиг.

    PHP:
    LoadCfg()
    {
        if (
    kv_cfg == INVALID_HANDLE)
        {
            
    kv_cfg CreateKeyValues("Crates");
            if (!
    FileToKeyValues(kv_cfgg_cfg_file)) 
            {
                
    CloseHandle(kv_cfg);
                
    kv_cfg INVALID_HANDLE;
                
    ThrowError("Could not parse %s"g_cfg_file);
            }
        }
        
        if (
    KvJumpToKey(kv_cfgg_cMapfalse))
        {
            
    KvGotoFirstSubKey(kv_cfg);
            
            do
            {
                
    KvGetVector(kv_cfg"crate"g_crate);
            }
            while (
    KvGotoNextKey(kv_cfg))
        }
        else
        {
        }
        
    KvRewind(kv_cfg);
    }
     
  2. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    Hejter, ты не загружаешь конфиг на каждой карте, а только на 1-й. Нужно делать клосе хандл и создавать кв заново.
    Ниче не потерял?
    Сначала нужно сделать ревинд, потом уже ставать на ключ.
    И скинь структуру, которую ты хочешь видеть
     
  3. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    PHP:
    "Crates"
    {
        
    "Карта"
        
    {
            
    "crate" "координаты ящика"
            "crate 2" "координаты ящика"
        
    }
    }
     
  4. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
    Не удивительно, ведь ты перезаписываешь одно и тоже значение "crate"
    Ещё здесь KvGotoFirstSubKey(kv_cfg) лишнее.
     
  5. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    PHP:
    "crate" "координаты ящика"
            "crate 2" "координаты ящика"
    PHP:
    KvGetVector(kv_cfg, "crate", g_crate);
    а где форматирование?
     
  6. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Смотрел в других плагин и уроках, подобное там было, решил влепить.

    Добавлено через 56 секунд
    Вообще не шарю. Форматирование чего?
     
    Последнее редактирование: 10 дек 2015
  7. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    Hejter, ну по идее у тебя должно быть что-то типа:
    PHP:
    decl iString:sBuffer[16];
    for(new 
    1кол-во; ++i)
    {
        
    FormatEx(sBuffersizeof(sBuffer), "crate %i"i);
        
    KvGetVector(kv_cfgsBufferg_crate);
        
    // ... 
    }
    Или под while переделать.
     
  8. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Видел что делают цикл, но нормально примера найти не смог. Везде "вырви глаз" код.
     
  9. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Построил новую структуру, теперь файл не перезаписывает, а перезаписывается ячейка crate 1
    Стуктура:

    Код:
    "Crates"
    {
    	"pd_payday"
    	{
    		"crate 1"		"353.230713 -2023.917847 -114.968750"
    	}
    }
    Делал цикл как примерно подсказал R1KO, но там создается сразу X ящиков.
     
  10. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    Hejter, код
     
  11. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    PHP:
    new String:g_cfg_file[PLATFORM_MAX_PATH];
    new 
    String:g_cMap[256];
    new 
    Handle:h_kv_cfg;
    new 
    Float:g_MoneyPoint[3];
    new 
    String:sBuffer[256];

    new 
    crates_count;


    LoadCfg()
    {
        
    crates_count 0;
        if (
    h_kv_cfg == INVALID_HANDLE)
        {
            
    h_kv_cfg CreateKeyValues("Crates");
            if (!
    FileToKeyValues(h_kv_cfgg_cfg_file)) 
            {
                
    CloseHandle(h_kv_cfg);
                
    h_kv_cfg INVALID_HANDLE;
                
    ThrowError("Could not parse %s"g_cfg_file);
            }
        }
        
        
    GetCurrentMap(g_cMapsizeof(g_cMap));
        if (
    KvJumpToKey(h_kv_cfgg_cMapfalse)) // Если ящик есть в нашем файле, то пропускаем его
        
    {
            
    KvGetVector(h_kv_cfgsBufferg_MoneyPoint); // Получаем позицию ящика в файле.
        
    }
        
    KvRewind(h_kv_cfg);
    }

    public 
    Action:cmd_Crate(clientargc)
    {
        if (!
    client || !IsClientInGame(client))
        {
            
    ReplyToCommand(client"ERROR: You can't use that command while not in game!");
            return 
    Plugin_Handled;
        }
        
        
    decl Float:pos[3];
        if (
    h_kv_cfg != INVALID_HANDLE && GetPlayerEye(clientpos))
        {
            
    GetCurrentMap(g_cMapsizeof(g_cMap));
            
    pos[2] += 30.0;
            for (new 
    0sizeof(crates_count); i++){
                if (
    KvJumpToKey(h_kv_cfgg_cMaptrue)){ // Если ящика нет в файле, то заносим его 
                    
    FormatEx(sBuffersizeof(sBuffer), "crate %i"1);
                    
    KvSetVector(h_kv_cfgsBufferpos); // Заносим позицию ящика в файл.
                
    }
            }
            
    KvRewind(h_kv_cfg); // Восстановить позицию.
            
    KeyValuesToFile(h_kv_cfgg_cfg_file); // Сохраняем файл 
            
    PrintToChat(client"%s: %d:%d:%d""Ящик установлен"pos[0], pos[1], pos[2]);
        }
        else
        {
            
    PrintToChat(client"%s""Произошла ошибка. Ящик не установлена");
        }
        
        return 
    Plugin_Handled;
    }
     
  12. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    ревинд нужно делать до перемещения по ключам. (чтобы наверняка)
    PHP:
     for (new 0sizeof(crates_count); i++){
                if (
    KvJumpToKey(h_kv_cfgg_cMaptrue)){ // Если ящика нет в файле, то заносим его 
                    
    FormatEx(sBuffersizeof(sBuffer), "crate %i"1);
                    
    KvSetVector(h_kv_cfgsBufferpos); // Заносим позицию ящика в файл.
                
    }
            }
    Вообще бред.
     
  13. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Соглашусь. По другому не смог придумать.
     
  14. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.579
    Симпатии:
    1.989
    При загрузке конфига, но точно на каждой карте (так как первое сравнение - карта) нужно проверять существующие crate. На найденном по циклу несуществующем значении, например, crate 5, делаем сохранение: CrateCount = 5;
    При создании ведём отсчёт от этой переменной, создавая вышеупомянутый и нужный нам следующий ящик на карте. После создания просто добавляем: ++CrateCount;
     
  15. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    Hejter, посмотри спавн тулс. там таким же способом сделано
     
  16. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Посмотрю.

    Добавлено через 45 секунд
    Попробую.

    Добавлено через 1 час 8 минут
    Не получается.
    Пробовал как алмазон объяснял, не работает.
    Пробовал разобрать spawntools, крутил, вертел, тоже не получается.

    Добавлено через 1 час 16 минут
    Если делать так, то записывается в файл два ящика, но с одинаковыми координатами.

    Код:
    public Action:cmd_Crate(client, argc)
    {
    	if (!client || !IsClientInGame(client))
    	{
    		ReplyToCommand(client, "ERROR: You can't use that command while not in game!");
    		return Plugin_Handled;
    	}
    	
    	decl Float:pos[3];
    	if (h_kv_cfg != INVALID_HANDLE && GetPlayerEye(client, pos))
    	{
    		GetCurrentMap(g_cMap, sizeof(g_cMap));
    		KvJumpToKey(h_kv_cfg, g_cMap, true); // Если ящика нет в файле, то заносим его
    		pos[2] += 30.0;
    		for (new i = 0; i < 2; i++){
    			FormatEx(sBuffer, sizeof(sBuffer), "crate %i", i);
    			KvSetVector(h_kv_cfg, sBuffer, pos); // Заносим позицию ящика в файл.
    		}
    		KvRewind(h_kv_cfg); // Восстановить позицию.
    		KeyValuesToFile(h_kv_cfg, g_cfg_file); // Сохраняем файл 
    		PrintToChat(client, "%s: %d:%d:%d", "Ящик установлен", pos[0], pos[1], pos[2]);
    	}
    	else
    	{
    		PrintToChat(client, "%s", "Произошла ошибка. Ящик не установлена");
    	}
    	
    	return Plugin_Handled;
    }
    
     
    Последнее редактирование: 13 дек 2015
  17. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    что-то такое.
    PHP:

    new g_iNum;
    new 
    String:g_sMap[64];

    public 
    OnMapStart()
    {
        
    g_iNum 0;
        
    GetCurrentMap(g_cMapsizeof(g_cMap));
        
        
    // открываешь g_hKeyValues
        
        
    KvRewind(g_hKeyValues);
        if(
    KvJumpToKey(g_hKeyValuesg_cMap))
        {
            
    decl Float:fPos[3], String:sBuffer[32];
            while(
    true)
            {
                
    FormatEx(sBuffersizeof(sBuffer), "crate %i"g_iNum+1);
                
    KvGetVector(g_hKeyValuessBufferfPos);
                if(
    IsVectorEmpty(fPos))
                {
                    break;
                }
                ++
    g_iNum;
            }
        }
    }

    bool:IsVectorEmpty(const Float:fPos[3])
    {
        for (new 
    03; ++i)
        {
            if(
    fPos[i])
            {
                return 
    false;
            }
        }
        return 
    true;
    }

    public 
    Action:cmd_Crate(clientargc)
    {
        if (!
    client || !IsClientInGame(client))
        {
            
    ReplyToCommand(client"ERROR: You can't use that command while not in game!");
            return 
    Plugin_Handled;
        }
        
        
    KvRewind(g_hKeyValues);
        if(
    KvJumpToKey(g_hKeyValuesg_cMaptrue))
        {
            
    decl Float:fPos[3], String:sBuffer[32];
            
    GetPlayerEye(clientfPos);
            
    fPos[2] += 30.0;
            ++
    g_iNum;
            
    FormatEx(sBuffersizeof(sBuffer), "crate %i"g_iNum);
            
    KvSetVector(g_hKeyValuessBufferfPos); // Заносим позицию ящика в файл.
            
    KvRewind(g_hKeyValues); // Восстановить позицию.
            
    KeyValuesToFile(g_hKeyValuesg_cfg_file); // Сохраняем файл 
            
    PrintToChat(client"Ящик установлен: %.2f:%.2f:%.2f"fPos[0], fPos[1], fPos[2]);
        }
        else
        {
            
    PrintToChat(client"Произошла ошибка. Ящик не установлена");
        }
        
        return 
    Plugin_Handled;
    }

    P.S.Компилировать не пробывал. Возможны ошибки и опечатки
     
  18. Hejter

    Hejter Mapper Source Engine

    Сообщения:
    1.771
    Симпатии:
    259
    Записывает теперь нормально, как нужно, но не спавнит. Пробовал и перезагружать конфиг и перезапускать карту, не хочет.

    Код ниже.

    PHP:
    #pragma semicolon 1
    #include <sdktools>

    new String:g_cfg_file[PLATFORM_MAX_PATH];
    new 
    g_iNum;
    new 
    String:g_cMap[256];
    new 
    Handle:h_kv_cfg;
    new 
    Float:g_MoneyPoint[3];

    public 
    OnPluginStart() 
    {
        
    HookEvent("round_start"RoundStart);
        
        
    RegAdminCmd("sm_box_reload"cmd_ReloadADMFLAG_ROOT"Reload cfgs");
        
    RegAdminCmd("sm_box"cmd_CrateADMFLAG_ROOT"Set crate position");
        
        
    BuildPath(Path_SMg_cfg_filesizeof(g_cfg_file), "configs/crates/crates.txt");
    }

    public 
    OnMapStart()
    {
        
    LoadCfg();
        
    PrecacheModel("models/props/cs_militia/footlocker01_closed.mdl"true);
    }

    LoadCfg()
    {
        
    g_iNum 0;
        
    GetCurrentMap(g_cMapsizeof(g_cMap));
        
        if (
    h_kv_cfg == INVALID_HANDLE)
        {
            
    h_kv_cfg CreateKeyValues("Crates");
            if (!
    FileToKeyValues(h_kv_cfgg_cfg_file)) 
            {
                
    CloseHandle(h_kv_cfg);
                
    h_kv_cfg INVALID_HANDLE;
                
    ThrowError("Could not parse %s"g_cfg_file);
            }
        }
        
        
    KvRewind(h_kv_cfg); 
        if(
    KvJumpToKey(h_kv_cfgg_cMap)) 
        { 
            
    decl Float:fPos[3], String:sBuffer[32]; 
            while(
    KvGotoNextKey(h_kv_cfg))
            { 
                
    FormatEx(sBuffersizeof(sBuffer), "crate %i"g_iNum+1); 
                
    KvGetVector(h_kv_cfgsBufferfPos); 
                if(
    IsVectorEmpty(fPos)) 
                { 
                    break; 
                } 
                ++
    g_iNum
            } 
        } 
    }

    bool:IsVectorEmpty(const Float:fPos[3]) 

        for (new 
    03; ++i
        { 
            if(
    fPos[i]) 
            { 
                return 
    false
            } 
        } 
        return 
    true
    }

    public 
    Action:cmd_Crate(clientargc)
    {
        if (!
    client || !IsClientInGame(client))
        {
            
    ReplyToCommand(client"ERROR: You can't use that command while not in game!");
            return 
    Plugin_Handled;
        }
        
        
    KvRewind(h_kv_cfg); 
        if(
    KvJumpToKey(h_kv_cfgg_cMaptrue)) 
        { 
            
    decl Float:fPos[3], String:sBuffer[32]; 
            
    GetPlayerEye(clientfPos); 
            
    fPos[2] += 30.0
            ++
    g_iNum
            
    FormatEx(sBuffersizeof(sBuffer), "crate %i"g_iNum); 
            
    KvSetVector(h_kv_cfgsBufferfPos); // Заносим позицию ящика в файл. 
            
    KvRewind(h_kv_cfg); // Восстановить позицию. 
            
    KeyValuesToFile(h_kv_cfgg_cfg_file); // Сохраняем файл  
            
    PrintToChat(client"Ящик установлен: %.2f:%.2f:%.2f"fPos[0], fPos[1], fPos[2]); 
        } 
        else 
        { 
            
    PrintToChat(client"Произошла ошибка. Ящик не установлена"); 
        } 
         
        return 
    Plugin_Handled
    }

    stock bool:GetPlayerEye(clientFloat:fPos[3])
    {
        
    decl Float:vAngles[3], Float:vOrigin[3];

        
    GetClientEyePosition(clientvOrigin);
        
    GetClientEyeAngles(clientvAngles);

        new 
    Handle:trace TR_TraceRayFilterEx(vOriginvAnglesMASK_SOLIDRayType_InfiniteTraceEntityFilterPlayers);

        if (
    TR_DidHit(trace))
        {
            
    TR_GetEndPosition(fPostrace);
            
    CloseHandle(trace);
            return 
    true;
        }

        
    CloseHandle(trace);
        return 
    false;
    }

    public 
    RoundStart(Handle:event, const String:name[], bool:dontBroadcast
    {
        
    func_box();
    }

    public 
    bool:TraceEntityFilterPlayers(entitycontentsMask)
    {
        return (!(
    entity <= MaxClients));
    }

    public 
    Action:cmd_Reload(clientargc)
    {
        if (
    h_kv_cfg != INVALID_HANDLE)
        {
            
    CloseHandle(h_kv_cfg);
            
    h_kv_cfg INVALID_HANDLE;
        }
        
    LoadCfg();
        
    ReplyToCommand(client"Настройки перезагружены!");
    }

    func_box()
    {
        new 
    ent CreateEntityByName("prop_physics_override");
        
    decl String:targetname[64];

        
    FormatEx(targetnamesizeof(targetname), "crate_%i"ent);

        
    DispatchKeyValue(ent"model""models/props/cs_militia/footlocker01_closed.mdl");
        
    DispatchKeyValue(ent"physicsmode""2");
        
    DispatchKeyValue(ent"massScale""1.0");
        
    DispatchKeyValue(ent"targetname"targetname);
        
    DispatchKeyValue(ent"spawnflags""0");    
        
    DispatchSpawn(ent);
        
        
    SetEntProp(entProp_Send"m_usSolidFlags",  152);
        
    SetEntProp(entProp_Send"m_CollisionGroup"8);
        
        
    TeleportEntity(entg_MoneyPointNULL_VECTORNULL_VECTOR);        
    }
     
  19. R1KO

    R1KO Супер-модератор

    Сообщения:
    6.001
    Симпатии:
    2.992
    Hejter, тебе в начале каждого раунда нужно опять идти по кв (или при подсчете ящиков запиливать их в массив и потом брать из него) и в начале каждого раунде выставлять ящики.

    Он спавнит. Просто посмотри куда ты его спавнишь
    TeleportEntity(ent, g_MoneyPoint, NULL_VECTOR, NULL_VECTOR);
    а g_MoneyPoint создается {0.0, 0.0, 0.0} и туда телепортится ящик.
    Передавай координаты в func_box()
     
  20. AlmazON

    AlmazON деревянный © yand3xmail

    Сообщения:
    4.579
    Симпатии:
    1.989
    Так ты ничего и не спавнишь, в принципе.
    PHP:
    public Action:cmd_Crate(clientargc

        if (!
    client || !IsClientInGame(client)) 
        { 
            
    ReplyToCommand(client"ERROR: You can't use that command while not in game!"); 
            return 
    Plugin_Handled
        } 
         
        
    KvRewind(h_kv_cfg);  
        if(
    KvJumpToKey(h_kv_cfgg_cMaptrue))  
        {  
            
    decl String:sBuffer[32];  
            
    GetPlayerEye(clientg_MoneyPoint);  
            
    g_MoneyPoint[2] += 30.0;  
            ++
    g_iNum;  
            
    FormatEx(sBuffersizeof(sBuffer), "crate %i"g_iNum);  
            
    KvSetVector(h_kv_cfgsBufferg_MoneyPoint); // Заносим позицию ящика в файл.  
            
    KvRewind(h_kv_cfg); // Восстановить позицию.  
            
    KeyValuesToFile(h_kv_cfgg_cfg_file); // Сохраняем файл 
            
    func_box();
            
    PrintToChat(client"Ящик установлен: %.2f:%.2f:%.2f"g_MoneyPoint[0], g_MoneyPoint[1], g_MoneyPoint[2]);  
        }  
        else  
        {  
            
    PrintToChat(client"Произошла ошибка. Ящик не установлена");  
        }  
          
      
    При старте раунда аналогично, но циклом по ключам файла, вроде такого:
    PHP:
    public RoundStart(Handle:event, const String:name[], bool:dontBroadcast)  
    {
        
    KvRewind(h_kv_cfg);  
        if(
    KvJumpToKey(h_kv_cfgg_cMap))  
        {
            
    decl String:sBuffer[32];
            new 
    i;
            while(
    KvGotoNextKey(h_kv_cfg)) 
            {  
                
    FormatEx(sBuffersizeof(sBuffer), "crate %i", ++i);  
                
    KvGetVector(h_kv_cfgsBufferg_MoneyPoint);
                if(
    IsVectorEmpty(g_MoneyPoint))  
                {  
                    return; 
                }
                
    func_box();
            }  
        }