Keyvalues

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Не создает больше 1 ящика, точнее записывается в конфиг всего лишь одна строка.
PHP:
public Action:Command_Create(client, args) 
{
	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(client, pos))
	{
		pos[2] += 30.0;
		KvJumpToKey(kv_cfg, g_cMap, true);
		{
			KvGotoFirstSubKey(kv_cfg);
			KvSetVector(kv_cfg, "crate", pos);
		}
		KvRewind(kv_cfg);
		KeyValuesToFile(kv_cfg, g_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_cfg, g_cfg_file)) 
		{
			CloseHandle(kv_cfg);
			kv_cfg = INVALID_HANDLE;
			ThrowError("Could not parse %s", g_cfg_file);
		}
	}
	
	if (KvJumpToKey(kv_cfg, g_cMap, false))
	{
		KvGotoFirstSubKey(kv_cfg);
		
		do
		{
			KvGetVector(kv_cfg, "crate", g_crate);
		}
		while (KvGotoNextKey(kv_cfg))
	}
	else
	{
	}
	KvRewind(kv_cfg);
}
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #2
Hejter, ты не загружаешь конфиг на каждой карте, а только на 1-й. Нужно делать клосе хандл и создавать кв заново.
KvJumpToKey(kv_cfg, g_cMap, true);
{
KvGotoFirstSubKey(kv_cfg);
KvSetVector(kv_cfg, "crate", pos);
}
KvRewind(kv_cfg);
KeyValuesToFile(kv_cfg, g_cfg_file);
Ниче не потерял?
Сначала нужно сделать ревинд, потом уже ставать на ключ.
И скинь структуру, которую ты хочешь видеть
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Hejter, ты не загружаешь конфиг на каждой карте, а только на 1-й. Нужно делать клосе хандл и создавать кв заново.

Ниче не потерял?
Сначала нужно сделать ревинд, потом уже ставать на ключ.
И скинь структуру, которую ты хочешь видеть

PHP:
"Crates"
{
	"Карта"
	{
		"crate" "координаты ящика"
		"crate 2" "координаты ящика"
	}
}
 

FrozDark

Участник
Сообщения
1,769
Реакции
2,050
Не создает больше 1 ящика, точнее записывается в конфиг всего лишь одна строка.
PHP:
public Action:Command_Create(client, args) 
{
	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(client, pos))
	{
		pos[2] += 30.0;
		KvJumpToKey(kv_cfg, g_cMap, true);
		{
			KvGotoFirstSubKey(kv_cfg);
			KvSetVector(kv_cfg, "crate", pos);
		}
		KvRewind(kv_cfg);
		KeyValuesToFile(kv_cfg, g_cfg_file);
		PrintToChat(client, "%s: %d:%d:%d", "Ящик создан", pos[0], pos[1], pos[2]);
	}
	else
	{
		PrintToChat(client, "%s", "Произошла ошибка.");
	}
	
	return Plugin_Handled;
}

Не удивительно, ведь ты перезаписываешь одно и тоже значение "crate"
Ещё здесь KvGotoFirstSubKey(kv_cfg) лишнее.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #5
PHP:
"crate" "координаты ящика"
        "crate 2" "координаты ящика"

PHP:
KvGetVector(kv_cfg, "crate", g_crate);

а где форматирование?
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Не удивительно, ведь ты перезаписываешь одно и тоже значение "crate"
Ещё здесь KvGotoFirstSubKey(kv_cfg) лишнее.

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

Добавлено через 56 секунд
PHP:
"crate" "координаты ящика"
        "crate 2" "координаты ящика"

PHP:
KvGetVector(kv_cfg, "crate", g_crate);

а где форматирование?

Вообще не шарю. Форматирование чего?
 
Последнее редактирование:

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #7
Hejter, ну по идее у тебя должно быть что-то типа:
PHP:
decl i, String:sBuffer[16];
for(new i = 1; i < кол-во; ++i)
{
	FormatEx(sBuffer, sizeof(sBuffer), "crate %i", i);
	KvGetVector(kv_cfg, sBuffer, g_crate);
	// ... 
}
Или под while переделать.
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Hejter, ну по идее у тебя должно быть что-то типа:
PHP:
decl i, String:sBuffer[16];
for(new i = 1; i < кол-во; ++i)
{
	FormatEx(sBuffer, sizeof(sBuffer), "crate %i", i);
	KvGetVector(kv_cfg, sBuffer, g_crate);
	// ... 
}
Или под while переделать.

Видел что делают цикл, но нормально примера найти не смог. Везде "вырви глаз" код.
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Построил новую структуру, теперь файл не перезаписывает, а перезаписывается ячейка crate 1
Стуктура:

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

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393

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_cfg, g_cfg_file)) 
		{
			CloseHandle(h_kv_cfg);
			h_kv_cfg = INVALID_HANDLE;
			ThrowError("Could not parse %s", g_cfg_file);
		}
	}
	
	GetCurrentMap(g_cMap, sizeof(g_cMap));
	if (KvJumpToKey(h_kv_cfg, g_cMap, false)) // Если ящик есть в нашем файле, то пропускаем его
	{
		KvGetVector(h_kv_cfg, sBuffer, g_MoneyPoint); // Получаем позицию ящика в файле.
	}
	KvRewind(h_kv_cfg);
}

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));
		pos[2] += 30.0;
		for (new i = 0; i < sizeof(crates_count); i++){
			if (KvJumpToKey(h_kv_cfg, g_cMap, true)){ // Если ящика нет в файле, то заносим его 
				FormatEx(sBuffer, sizeof(sBuffer), "crate %i", i + 1);
				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;
}
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #12
ревинд нужно делать до перемещения по ключам. (чтобы наверняка)
PHP:
 for (new i = 0; i < sizeof(crates_count); i++){
            if (KvJumpToKey(h_kv_cfg, g_cMap, true)){ // Если ящика нет в файле, то заносим его 
                FormatEx(sBuffer, sizeof(sBuffer), "crate %i", i + 1);
                KvSetVector(h_kv_cfg, sBuffer, pos); // Заносим позицию ящика в файл.
            }
        }
Вообще бред.
 

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
ревинд нужно делать до перемещения по ключам. (чтобы наверняка)
PHP:
 for (new i = 0; i < sizeof(crates_count); i++){
            if (KvJumpToKey(h_kv_cfg, g_cMap, true)){ // Если ящика нет в файле, то заносим его 
                FormatEx(sBuffer, sizeof(sBuffer), "crate %i", i + 1);
                KvSetVector(h_kv_cfg, sBuffer, pos); // Заносим позицию ящика в файл.
            }
        }
Вообще бред.

Соглашусь. По другому не смог придумать.
 

AlmazON

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

R1KO

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

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
Hejter, посмотри спавн тулс. там таким же способом сделано

Посмотрю.

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

Попробую.

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

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

C-подобный:
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;
}
 
Последнее редактирование:

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #17
что-то такое.
PHP:
new g_iNum;
new String:g_sMap[64];

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

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

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;
	}
	
	KvRewind(g_hKeyValues);
	if(KvJumpToKey(g_hKeyValues, g_cMap, true))
	{
		decl Float:fPos[3], String:sBuffer[32];
		GetPlayerEye(client, fPos);
		fPos[2] += 30.0;
		++g_iNum;
		FormatEx(sBuffer, sizeof(sBuffer), "crate %i", g_iNum);
		KvSetVector(g_hKeyValues, sBuffer, fPos); // Заносим позицию ящика в файл.
		KvRewind(g_hKeyValues); // Восстановить позицию.
		KeyValuesToFile(g_hKeyValues, g_cfg_file); // Сохраняем файл 
		PrintToChat(client, "Ящик установлен: %.2f:%.2f:%.2f", fPos[0], fPos[1], fPos[2]);
	}
	else
	{
		PrintToChat(client, "Произошла ошибка. Ящик не установлена");
	}
	
	return Plugin_Handled;
}

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

Hejter

xor ebx, ebx
Сообщения
1,759
Реакции
393
что-то такое.
PHP:
new g_iNum;
new String:g_sMap[64];

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

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

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;
	}
	
	KvRewind(g_hKeyValues);
	if(KvJumpToKey(g_hKeyValues, g_cMap, true))
	{
		decl Float:fPos[3], String:sBuffer[32];
		GetPlayerEye(client, fPos);
		fPos[2] += 30.0;
		++g_iNum;
		FormatEx(sBuffer, sizeof(sBuffer), "crate %i", g_iNum);
		KvSetVector(g_hKeyValues, sBuffer, fPos); // Заносим позицию ящика в файл.
		KvRewind(g_hKeyValues); // Восстановить позицию.
		KeyValuesToFile(g_hKeyValues, g_cfg_file); // Сохраняем файл 
		PrintToChat(client, "Ящик установлен: %.2f:%.2f:%.2f", fPos[0], fPos[1], fPos[2]);
	}
	else
	{
		PrintToChat(client, "Произошла ошибка. Ящик не установлена");
	}
	
	return Plugin_Handled;
}

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

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

Код ниже.

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_Reload, ADMFLAG_ROOT, "Reload cfgs");
	RegAdminCmd("sm_box", cmd_Crate, ADMFLAG_ROOT, "Set crate position");
	
	BuildPath(Path_SM, g_cfg_file, sizeof(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_cMap, sizeof(g_cMap));
	
	if (h_kv_cfg == INVALID_HANDLE)
	{
		h_kv_cfg = CreateKeyValues("Crates");
		if (!FileToKeyValues(h_kv_cfg, g_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_cfg, g_cMap)) 
	{ 
	    decl Float:fPos[3], String:sBuffer[32]; 
	    while(KvGotoNextKey(h_kv_cfg))
	    { 
	        FormatEx(sBuffer, sizeof(sBuffer), "crate %i", g_iNum+1); 
	        KvGetVector(h_kv_cfg, sBuffer, fPos); 
	        if(IsVectorEmpty(fPos)) 
	        { 
	            break; 
	        } 
	        ++g_iNum; 
	    } 
	} 
}

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

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;
	}
	
	KvRewind(h_kv_cfg); 
	if(KvJumpToKey(h_kv_cfg, g_cMap, true)) 
	{ 
	    decl Float:fPos[3], String:sBuffer[32]; 
	    GetPlayerEye(client, fPos); 
	    fPos[2] += 30.0; 
	    ++g_iNum; 
	    FormatEx(sBuffer, sizeof(sBuffer), "crate %i", g_iNum); 
	    KvSetVector(h_kv_cfg, sBuffer, fPos); // Заносим позицию ящика в файл. 
	    KvRewind(h_kv_cfg); // Восстановить позицию. 
	    KeyValuesToFile(h_kv_cfg, g_cfg_file); // Сохраняем файл  
	    PrintToChat(client, "Ящик установлен: %.2f:%.2f:%.2f", fPos[0], fPos[1], fPos[2]); 
	} 
	else 
	{ 
	    PrintToChat(client, "Произошла ошибка. Ящик не установлена"); 
	} 
	 
	return Plugin_Handled; 
}

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

	GetClientEyePosition(client, vOrigin);
	GetClientEyeAngles(client, vAngles);

	new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SOLID, RayType_Infinite, TraceEntityFilterPlayers);

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

	CloseHandle(trace);
	return false;
}

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

public bool:TraceEntityFilterPlayers(entity, contentsMask)
{
	return (!(0 < entity <= MaxClients));
}

public Action:cmd_Reload(client, argc)
{
	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(targetname, sizeof(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(ent, Prop_Send, "m_usSolidFlags",  152);
	SetEntProp(ent, Prop_Send, "m_CollisionGroup", 8);
	
	TeleportEntity(ent, g_MoneyPoint, NULL_VECTOR, NULL_VECTOR);		
}
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #19
Hejter, тебе в начале каждого раунда нужно опять идти по кв (или при подсчете ящиков запиливать их в массив и потом брать из него) и в начале каждого раунде выставлять ящики.

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

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Так ты ничего и не спавнишь, в принципе.
PHP:
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; 
    } 
     
    KvRewind(h_kv_cfg);  
    if(KvJumpToKey(h_kv_cfg, g_cMap, true))  
    {  
        decl String:sBuffer[32];  
        GetPlayerEye(client, g_MoneyPoint);  
        g_MoneyPoint[2] += 30.0;  
        ++g_iNum;  
        FormatEx(sBuffer, sizeof(sBuffer), "crate %i", g_iNum);  
        KvSetVector(h_kv_cfg, sBuffer, g_MoneyPoint); // Заносим позицию ящика в файл.  
        KvRewind(h_kv_cfg); // Восстановить позицию.  
        KeyValuesToFile(h_kv_cfg, g_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_cfg, g_cMap))  
    {
        decl String:sBuffer[32];
		new i;
        while(KvGotoNextKey(h_kv_cfg)) 
        {  
            FormatEx(sBuffer, sizeof(sBuffer), "crate %i", ++i);  
            KvGetVector(h_kv_cfg, sBuffer, g_MoneyPoint);
            if(IsVectorEmpty(g_MoneyPoint))  
            {  
                return; 
            }
			func_box();
        }  
    }  
}
 
Сверху Снизу