#include <amxmodx>
#include <hamsandwich>
#include <engine>
#include <cstrike>
#include <fun>
#include <reapi>

#pragma semicolon 1

new const PLUGIN[] = "Re GunGame";
new const VERSION[] = "1.5.2";
new const AUTHOR[] = "gyxoBka";

/*---------------EDIT ME------------------*/

#define RED_TEAM_COLOUR   	255, 0, 0    	// Цвет RGB во время защиты для ТТ ( рендеринг )
#define BLUE_TEAM_COLOUR   	0, 0, 255		// Цвет RGB во время защиты для CT ( рендеринг )
#define GLOW_THICK         	10				// "Плотность" цвета защиты. Закомментируйте, чтобы отключить свечение

#define MAXPLAYERS 			32				// Максимальное количество игроков на сервере
#define REFRESH_INTERVAL 	5.0				// С какой периодичностью обновляется HUD лидера

#define MAX_SAVES 			32				// Максимальное количество сохраненных игроков

/*----------------------------------------*/

#define CheckFlag(%1,%2)  			(%1 &   (1 << (%2 & 31)))
#define SetFlag(%1,%2)    			(%1 |=  (1 << (%2 & 31)))
#define ClearFlag(%1,%2)			(%1 &= ~(1 << (%2 & 31)))

#define FIRST_PLAYER_ID 	1
#define MAX_LEVELS 			26
#define START_LEVEL			1
#define	MAX_SPAWNS			60
#define WEAPON_LEN 			16
#define SOUND_SIZE 			100

#define TASK_RESPAWN_ID		32
#define TASK_NEWSPAWN_ID	64
#define TASK_PROTECTION_ID	96
#define TASK_GIVEGRENADE_ID 128
#define TASK_LEADER_DISPLAY 500

#define IsPlayer(%1) ( FIRST_PLAYER_ID <= %1 <= MAXPLAYERS )
#define IsMp3Format(%1)  equali( %1[strlen( %1 ) - 4 ], ".mp3" )

enum Team
{
	TT = 1,
	CT
}

enum
{
	WORLD = 0,
	BULLET,
	KNIFE,
	GRENADE
}

enum
{
	SECTION_NONE = 0,
	BASIC,
	DEATHMATCH,
	WARMUP,
	SOUND,
	WEAPON
}

enum
{
	LEVELUP = 0,
	LEVELDOWN,
	LEVELSTEAL,
	LEVELNADE,
	LEVELKNIFE,
	LEVELWELCOME,
	LEVELWINNER,
	LEVELLEAD,
	LEVELTIEDLEAD,
	LEVELLOSTLEAD
}

enum SaveData
{
	szAuth[35],
	iSavedLevel,
	iSavedKills,
	iTimeStamp
}

//new const g_szScenarioIcons[][] ={ "", "number_1", "number_2", "number_3", "number_4", "number_5", "number_6", "number_7", "number_8", "number_9" };

new g_eSavedData[MAX_SAVES + 1][SaveData];

new Array:g_aLevelUp, Array:g_aLevelDown, Array:g_aLevelSteal, Array:g_aLevelNade, Array:g_aLevelKnife, 
Array:g_aLevelWelcome, Array:g_aLevelWinner, Array:g_aLevelLead, Array:g_aLevelTiedLead, Array:g_aLevelLostLead;
new g_aLevelUp_size, g_aLevelDown_size, g_aLevelSteal_size, g_aLevelNade_size, g_aLevelKnife_size, 
g_aLevelWelcome_size, g_aLevelWinner_size, g_aLevelLead_size, g_aLevelTiedLead_size, g_aLevelLostLead_size;

new g_szWeaponLevelName[MAX_LEVELS + 1][WEAPON_LEN + 1], g_szShortWeaponName[MAX_LEVELS + 1][WEAPON_LEN + 1], g_iNeedFrags[MAX_LEVELS + 1], 
g_iMaxBpAmmoLevel[MAX_LEVELS + 1], g_iCswLevel[MAX_LEVELS + 1], g_iWeaponLevelSlot[MAX_LEVELS + 1], g_szWeaponIcon[MAX_LEVELS + 2][12];

new g_iPlayerLevel[MAXPLAYERS + 1] = {1, 1, ...}, g_iPlayerFrags[MAXPLAYERS + 1], g_iTiedLeaderId[MAXPLAYERS + 1];

new g_iSpawnVecs[MAX_SPAWNS][3], g_iSpawnAngles[MAX_SPAWNS][3], g_iSpawnVAngles[MAX_SPAWNS][3], g_iSpawnTeam[MAX_SPAWNS];

new g_szGameName[32], g_szVoteFunction[50], g_szCallPluginName[24], g_szLeaderName[32], g_szTiedLeaderName[32], g_szWarmUpWeapon[WEAPON_LEN + 1];

new g_iMaxLevels = START_LEVEL, g_iLevelVote, g_iLevelBeforeVote, g_iWinnerMotd, g_iAfkProtection, g_iArmorValue, g_iRandomSpawn, g_iWarmUpTime,
g_iHeLevel, g_iKnifeLevel, g_iNewPlayerLevel, g_iAwpAmmo, g_iColorRed, g_iColorGreen, g_iColorBlue, g_iLevelSaveType, g_iDisplayLeader,
g_iLeaderLevel = START_LEVEL, g_iLeaderId, g_iTiedLeaderNum, g_iWinnerId, g_iLastKilled, g_iWarmUpLevel, g_iProtectionBar, g_iGlowEffect, g_iNoShotProtection;

new Float:g_fDisplayPosX, Float:g_fDisplayPosY, Float:g_fSpawnDelay, Float:g_fProtectionTime,  Float:g_fNadeRefreshTime;

new bool:g_bGameCommencing, bool:g_bIsWarpUp, bool:g_bVoteStarted; 

new g_MsgCrosshair, g_MsgHideWeapon, g_MsgCurWeapon, g_MsgRoundTime, g_MsgBarTime, g_hookMsgRoundTime, g_MsgStatusIcon /**,g_MsgScenarioIcon**/; 

new g_iHudLeaderSync, g_iHudFragSync, g_iMaxPlayers, g_iTotalSpawns;

new IsPlayerAlive, IsPlayerConnected, IsPlayerBot;

public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR);

	register_cvar( "regungame", VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED );
	
	register_logevent("EventGameCommencing", 2, "0=World triggered", "1=Game_Commencing") ;
	register_event("CurWeapon","EventCurWeapon","be","1=1");
	register_event("AmmoX","EventAmmoX","be");
	
	RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", true);
	RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed", true);
	RegisterHookChain(RG_CBasePlayer_DropPlayerItem, "CBasePlayer_DropPlayerItem", false);
	RegisterHookChain(RG_HandleMenu_ChooseAppearance, "HandleMenu_ChooseAppearance", true);
	RegisterHookChain(RG_CSGameRules_DeadPlayerWeapons, "CSGameRules_DeadPlayerWeapons", false);
	RegisterHookChain(RG_CSGameRules_GiveC4, "CSGameRules_GiveC4", false);
	RegisterHookChain(RH_SV_DropClient, "SV_DropClient", true); /** !!!!!!!!!! **/

	//register_clcmd("drop", "ClientDrop");
	
	g_iHudLeaderSync = CreateHudSyncObj();
	g_iHudFragSync = CreateHudSyncObj();
	g_iMaxPlayers = get_maxplayers();
	g_MsgCurWeapon = get_user_msgid("CurWeapon");
	g_MsgRoundTime = get_user_msgid("RoundTime");
	//g_MsgScenarioIcon = get_user_msgid( "Scenario" );
	g_MsgStatusIcon = get_user_msgid("StatusIcon");
	g_MsgHideWeapon = get_user_msgid("HideWeapon");
	g_MsgCrosshair = get_user_msgid("Crosshair");
	g_MsgBarTime = get_user_msgid("BarTime");
	
	remove_entity_name("armoury_entity");
	remove_entity_name("info_bomb_target");
	remove_entity_name("func_bomb_target");
}

public SV_DropClient(id, bCrash, szFmt[])
//public client_disconnect(id)
{
	ClearFlag(IsPlayerAlive, id);
	remove_task(id + TASK_RESPAWN_ID);
	ClearFlag(IsPlayerConnected, id);
	remove_task(id + TASK_PROTECTION_ID);
	ClearFlag(IsPlayerBot, id);
	remove_task(id + TASK_GIVEGRENADE_ID);
	
	if(g_iLevelSaveType >= 0)
	{
		SaveDisconnectPlayer(id);
	}
	
	g_iPlayerLevel[id] = START_LEVEL;
	g_iPlayerFrags[id] = 0;
	
	CalculateNewLeader();
}

public CBasePlayer_DropPlayerItem() return HC_SUPERCEDE;

//public ClientDrop(id) return PLUGIN_HANDLED;
public client_kill(id) return PLUGIN_HANDLED;

public plugin_precache()
{	
	ReadCfg();
	if(g_iRandomSpawn)
	{
		readSpawns();
	}

	if(g_aLevelUp_size)
	{
		PrecacheSounds(g_aLevelUp, g_aLevelUp_size);
	}

	if(g_aLevelDown_size)
	{
		PrecacheSounds(g_aLevelDown, g_aLevelDown_size);
	}
	
	if(g_aLevelSteal_size)
	{
		PrecacheSounds(g_aLevelSteal, g_aLevelSteal_size);
	}
	
	if(g_aLevelNade_size)
	{
		PrecacheSounds(g_aLevelNade, g_aLevelNade_size);
	}
	
	if(g_aLevelWelcome_size)
	{
		PrecacheSounds(g_aLevelWelcome, g_aLevelWelcome_size);
	}
	
	if(g_aLevelWinner_size)
	{
		PrecacheSounds(g_aLevelWinner, g_aLevelWinner_size);
	}
	
	if(g_aLevelLead_size)
	{
		PrecacheSounds(g_aLevelLead, g_aLevelLead_size);
	}

	if(g_aLevelTiedLead_size)
	{
		PrecacheSounds(g_aLevelTiedLead, g_aLevelTiedLead_size);
	}
	
	if(g_aLevelLostLead_size)
	{
		PrecacheSounds(g_aLevelLostLead, g_aLevelLostLead_size);
	}
	
	if(g_aLevelKnife_size)
	{
		PrecacheSounds(g_aLevelKnife, g_aLevelKnife_size);
	}
}

public plugin_cfg()
{
	set_cvar_num("mp_freezetime", 0);
	set_cvar_num("mp_timelimit", 0);
	set_cvar_num("mp_round_infinite", 0);
	set_cvar_num("mp_refill_bpammo_weapons", 2);
	
	set_member_game(m_bCTCantBuy, true);
	set_member_game(m_bTCantBuy, true);
	set_member_game(m_GameDesc, g_szGameName);
	
	g_iLevelVote = g_iMaxLevels - g_iLevelBeforeVote;
	
	if(g_iDisplayLeader) set_task(REFRESH_INTERVAL, "ShowLeader", TASK_LEADER_DISPLAY, .flags = "b");
}

NewPlayerMiddleLevel()
{
	new iLevel, iMaxLevel = START_LEVEL, iMinLevel = 100;		/** Level 100 just big value to get min ; ) **/
	
	for(new id = 1; id <= g_iMaxPlayers; id++)
	{
		if(!CheckFlag(IsPlayerConnected, id)) continue;
		
		iLevel = g_iPlayerLevel[id];
		if(iMinLevel > iLevel) 
		{
			iMinLevel = iLevel;
			continue;
		}
		
		if(iMaxLevel < iLevel) iMaxLevel = iLevel;
	}
	
	if(iMinLevel > MAX_LEVELS) return START_LEVEL;
	
	return (iMaxLevel + iMinLevel) / 2;
}

public client_connect(id)
{
	ClearFlag(IsPlayerConnected, id);
	ClearFlag(IsPlayerAlive, id);
}

public client_putinserver(id)
{	
	if(GetPlayerData(id))
	{
		CalculateNewLeader();
	}
	else
	{
		switch(g_iNewPlayerLevel)
		{
			case 0:
			{
				g_iPlayerLevel[id] = NewPlayerMiddleLevel();
			}
			default:
			{
				new iLevel; iLevel = g_iPlayerLevel[g_iLeaderId] - g_iNewPlayerLevel;
				g_iPlayerLevel[id] = iLevel > START_LEVEL ? iLevel : START_LEVEL;
			}
		}
	}
	
	if(is_user_connected(id))
	{
		SetFlag(IsPlayerConnected, id);
	}
	
	if(is_user_bot(id) || is_user_hltv(id))
	{
		SetFlag(IsPlayerBot, id);
		return;
	}
	
	set_task(0.5, "PlayWelcomeSound", id);
}

public CSGameRules_DeadPlayerWeapons(const wEnt)
{
	SetHookChainReturn(ATYPE_INTEGER, GR_PLR_DROP_GUN_NO);
	return HC_SUPERCEDE;
}

public HandleMenu_ChooseAppearance(id, iSlot)
{
	remove_task(TASK_NEWSPAWN_ID + id);
	set_task( g_fSpawnDelay, "SpawnNewPlayer", TASK_NEWSPAWN_ID + id);
	
	return HC_CONTINUE;
}

public CSGameRules_GiveC4() return HC_SUPERCEDE; 

public SpawnNewPlayer(id)
{
	id -= TASK_NEWSPAWN_ID;
	
	if(CheckFlag(IsPlayerAlive, id) || !CheckFlag(IsPlayerConnected, id)) 
		return;

	switch(get_member(id, m_iTeam)) 
	{
		case TT, CT: ExecuteHamB(Ham_CS_RoundRespawn, id);
	}
}

public CBasePlayer_Killed(id, pevAttacker, iGib)
{
	static TaskID, bool:bGrenadeSound, bool:bKnifeSound; 
	static bool:bGiveNewWeapon; bGiveNewWeapon = false;
	static bool:bWinner;
	
	if(bWinner) return HC_CONTINUE;
	
	ClearFlag(IsPlayerAlive, id);
	
	TaskID = TASK_RESPAWN_ID + id;
	remove_task(TaskID);
	set_task( g_fSpawnDelay, "Respawn", TaskID );
	
	if(!IsPlayer(pevAttacker) || id == pevAttacker || !CheckFlag(IsPlayerConnected, pevAttacker) || get_member(id, m_iTeam) == get_member(pevAttacker, m_iTeam))
		return HC_CONTINUE;
		
	if(g_bIsWarpUp) 
	{
		if(g_iWarmUpLevel == g_iHeLevel || g_iWarmUpLevel == g_iKnifeLevel)
			return HC_CONTINUE;
		
		rg_instant_reload_weapons(pevAttacker);		
		//cs_set_weapon_ammo(get_member(pevAttacker, m_pActiveItem), g_iMaxClipLevel[g_iWarmUpLevel]);
		return HC_CONTINUE;
	}
	
	if(g_iAfkProtection)
	{
		if(get_gametime() - cs_get_user_lastactivity(id) > g_iAfkProtection)
			return HC_CONTINUE;
	}

	static iAttackerLevel, iAttackerFrags, iNeedFrags, iInflictor;
	iAttackerLevel = g_iPlayerLevel[pevAttacker];
	iAttackerFrags = g_iPlayerFrags[pevAttacker];
	iNeedFrags = g_iNeedFrags[iAttackerLevel];

	get_death_reason(id, pevAttacker, iInflictor);
	
	// We have to know weapon ;)
	switch(iInflictor)
	{
		case BULLET:
		{
			iAttackerFrags++;
			if(iNeedFrags <= iAttackerFrags)
			{
				iAttackerFrags = 0;
				iAttackerLevel++;
				
				bGiveNewWeapon = true;
				// GIVE NEW WEAPON
				//GiveBetterWeapon(pevAttacker, iAttackerLevel);
				
				// PLAY SOUND LEVEL UP
				if(g_aLevelUp_size)
				{
					PlaySound(pevAttacker, g_aLevelUp, g_aLevelUp_size);
				}
			}
			else rg_instant_reload_weapons(pevAttacker);
			//cs_set_weapon_ammo(get_member(pevAttacker, m_pActiveItem), g_iMaxClipLevel[iAttackerLevel]);
		}
		case KNIFE:
		{
			if(g_iPlayerLevel[id] > START_LEVEL)
			{
				g_iPlayerLevel[id]--;
				
				if(g_iLeaderId == id)
				{
					switch(g_iTiedLeaderNum)
					{
						case 0:
						{
							CalculateNewLeader();
						}
						case 1: 
						{
							g_iLeaderId = g_iTiedLeaderId[g_iTiedLeaderNum];
							g_iTiedLeaderId[g_iTiedLeaderNum] = 0;
							g_iTiedLeaderNum--;
							
							get_user_name(g_iLeaderId, g_szLeaderName, charsmax(g_szLeaderName));
						}
						default:
						{
							g_iLeaderId = g_iTiedLeaderId[g_iTiedLeaderNum];
							g_iTiedLeaderId[g_iTiedLeaderNum] = 0;
							g_iTiedLeaderNum--;

							get_user_name(g_iLeaderId, g_szLeaderName, charsmax(g_szLeaderName));
							get_user_name(g_iTiedLeaderId[g_iTiedLeaderNum], g_szTiedLeaderName, charsmax(g_szTiedLeaderName));
						}	
					}
				}
				
				// PLAY SOUND LEVEL DOWN
				if(g_aLevelDown_size)
				{
					PlaySound(id, g_aLevelDown, g_aLevelDown_size);
				}
			}
			
			if(iAttackerLevel != g_iHeLevel)
			{
				iAttackerLevel++;
				
				// PLAY SOUND LEVEL STEAL
				if(g_aLevelSteal_size)
				{
					PlaySound(pevAttacker, g_aLevelSteal, g_aLevelSteal_size);
				}
				
				// GIVE NEW WEAPON
				//GiveBetterWeapon(pevAttacker, iAttackerLevel);
				bGiveNewWeapon = true;
			}
			else rg_give_item(id, "weapon_hegrenade", GT_APPEND);
		}
		case GRENADE:
		{
			remove_task(pevAttacker + TASK_GIVEGRENADE_ID);
			iAttackerLevel++;
			
			// GIVE NEW WEAPON
			//GiveBetterWeapon(pevAttacker, iAttackerLevel);
			bGiveNewWeapon = true;
		}
	}
	
	// PLAY GRENADE SOUND
	if(iAttackerLevel == g_iHeLevel && !bGrenadeSound && g_aLevelNade_size)
	{
		PlaySound(pevAttacker, g_aLevelNade, g_aLevelNade_size);
		bGrenadeSound = true;
	}
	
	if(iAttackerLevel == g_iKnifeLevel && !bKnifeSound && g_aLevelKnife_size)
	{
		PlaySound(pevAttacker, g_aLevelKnife, g_aLevelKnife_size);
		bKnifeSound = true;
	}
	
	if(g_iLeaderLevel == iAttackerLevel && g_iLeaderId != pevAttacker)
	{
		new bool:bIsPlayerTied = false;
		for(new i = 1; i <= g_iTiedLeaderNum; i++)
		{
			if(g_iTiedLeaderId[i] == pevAttacker) 
			{
				bIsPlayerTied = true;
				break;
			}
		}
		
		if(!bIsPlayerTied)
		{
			// PLAY SOUND TIED LEADER TO EACH PLAYER
			if(g_aLevelTiedLead_size && g_iLeaderId)
			{
				PlaySound(pevAttacker, g_aLevelTiedLead, g_aLevelTiedLead_size);
				PlaySound(g_iLeaderId, g_aLevelTiedLead, g_aLevelTiedLead_size);
			}
			g_iTiedLeaderNum++;
			g_iTiedLeaderId[g_iTiedLeaderNum] = pevAttacker;
			
			get_user_name(pevAttacker, g_szTiedLeaderName, charsmax(g_szTiedLeaderName));
		}
	}
	
	if(iAttackerLevel > g_iLeaderLevel)
	{
		if(g_iLeaderId != pevAttacker)
		{
			// PLAY SOUND LOST LEAD
			if(g_aLevelLostLead_size && g_iLeaderId)
			{
				PlaySound(g_iLeaderId, g_aLevelLostLead, g_aLevelLostLead_size);
			}
			
			// PLAY SOUND LEAD
			if(g_aLevelLead_size)
			{
				PlaySound(pevAttacker, g_aLevelLead, g_aLevelLead_size);
			}
			g_iLeaderId = pevAttacker; 
			get_user_name(g_iLeaderId, g_szLeaderName, charsmax(g_szLeaderName));
		}
		ResetTiedLeader();
		g_iLeaderLevel = iAttackerLevel;
	}
	
	// Time to vote for map?
	if(iAttackerLevel == g_iLevelVote && !g_bVoteStarted)
	{
		g_bVoteStarted = true;		// just to vote once
		StartMapVote();
	}
	
	// Attacker can be winner
	if(iAttackerLevel > g_iMaxLevels)
	{
		bWinner = true;
		
		remove_task(TASK_LEADER_DISPLAY);
		
		g_iWinnerId = pevAttacker;			// GAME OVER. Winner detected ;)
		g_iLastKilled = id;					// We have looser, too : D
		
		//PLAY WINNER SOUND
		if(g_aLevelWinner_size)
		{
			PlaySound(0, g_aLevelWinner, g_aLevelWinner_size);
		}
		
		// If default MOTD used let's show it
		if(g_iWinnerMotd)
		{
			set_task( 1.0, "ShowWinnerMotd" );
			//ShowWinnerMotd();
		}
		set_task( 6.0, "DelayedMapChange" );
		
		return HC_CONTINUE; 
	}
	
	if(bGiveNewWeapon) GiveBetterWeapon(pevAttacker, iAttackerLevel);

	//SendScenarioIcon(pevAttacker, iNeedFrags, iAttackerFrags);
	RefreshFragInformer(pevAttacker, iNeedFrags, iAttackerFrags, iAttackerLevel);
	
	g_iPlayerLevel[pevAttacker] = iAttackerLevel;
	g_iPlayerFrags[pevAttacker] = iAttackerFrags;
	
	return HC_CONTINUE;
}

public DelayedMapChange()
{
	new szNextMap[32];
	get_cvar_string("amx_nextmap", szNextMap, charsmax(szNextMap));
	
	server_cmd("changelevel %s", szNextMap);
}

public CBasePlayer_Spawn(id)
{
	if(!is_user_alive(id))
	{
		ClearFlag(IsPlayerAlive, id);
		return HC_CONTINUE;
	}
	
	SetFlag(IsPlayerAlive, id);
	
	if(g_iRandomSpawn)
	{
		spawn_Preset(id);
	}
	
	new iLevel;
	
	if(g_bIsWarpUp) iLevel = g_iWarmUpLevel;
	else 
	{
		iLevel = g_iPlayerLevel[id];
		//DeleteStatusIcon(id, iLevel)
		SendStatusIcon(id, iLevel);
		RefreshFragInformer(id, g_iNeedFrags[iLevel], g_iPlayerFrags[id], iLevel);
		hide_hud(id);
	}
	
	if(g_fProtectionTime) PlayerProtection(id);
	
	rg_remove_all_items(id, false);
	
	if(g_iArmorValue) rg_set_user_armor(id, g_iArmorValue, ARMOR_VESTHELM);
	
	rg_give_item(id, "weapon_knife", GT_APPEND);
	
	if(!iLevel || iLevel == g_iKnifeLevel) return HC_CONTINUE;
	else if( iLevel == g_iHeLevel ) rg_give_item(id, "weapon_hegrenade", GT_APPEND);
	else
	{
		rg_give_item(id, g_szWeaponLevelName[iLevel], GT_APPEND);
		cs_set_user_bpammo(id, g_iCswLevel[iLevel], g_iMaxBpAmmoLevel[iLevel]);
		ExecuteHamB(Ham_Weapon_RetireWeapon, get_member(id, m_rgpPlayerItems, 3));
	}	
		
	return HC_CONTINUE;
}

public EventGameCommencing()
{
	if(g_bGameCommencing) return;
	
	g_bGameCommencing = true;
	
	set_cvar_num("mp_round_infinite", 1);
	
	if(g_iWarmUpTime)
	{
		g_bIsWarpUp = true;
		g_hookMsgRoundTime = register_message( g_MsgRoundTime, "Message_RoundTime" );
		set_task(1.0, "TaskCountdownRestart", _, _, _, "a", g_iWarmUpTime);
		
		set_task( 5.0, "WarmpupStart" );
	}
}

public WarmpupStart()
{
	set_hudmessage(g_iColorRed, g_iColorGreen, g_iColorBlue, -1.0, 0.3, 0, 0.0, 5.0, 0.0, 0.0);
	ShowSyncHudMsg(0, CreateHudSyncObj(), "Bemelegítő kör!");
}

public EventAmmoX(id)
{
	new iLevel;

	if(g_bIsWarpUp) iLevel = g_iWarmUpLevel;
	else iLevel = g_iPlayerLevel[id];

	if(iLevel == g_iHeLevel)
	{
		new iAmount = read_data(2);
		
		if(iAmount > 0)
		{
			remove_task(id + TASK_GIVEGRENADE_ID);
			return;
		}
		
		set_task(g_fNadeRefreshTime, "GiveGrenade", id + TASK_GIVEGRENADE_ID);
		
		if(!CheckFlag(IsPlayerBot, id)) ShowBar(id, g_fNadeRefreshTime);
	}
}

public EventCurWeapon(id)
{
	if(!CheckFlag(IsPlayerAlive, id)) return;

	// have at least one bullet in AWP clip
	if(read_data(2) == CSW_AWP && read_data(3) > g_iAwpAmmo)
	{
		new wEnt = get_member(id, m_pActiveItem);
		cs_set_weapon_ammo(wEnt, g_iAwpAmmo);

		message_begin(MSG_ONE,g_MsgCurWeapon,_,id);
		write_byte(g_iAwpAmmo); // current?
		write_byte(CSW_AWP); // weapon
		write_byte(g_iAwpAmmo); // clip
		message_end();
	}
}

public Respawn(id) 
{
	id -= TASK_RESPAWN_ID;
	
	if(CheckFlag(IsPlayerAlive, id) || !CheckFlag(IsPlayerConnected, id))
		return;
	
	switch(get_member(id, m_iTeam)) 
	{
		case TT, CT:  ExecuteHamB(Ham_CS_RoundRespawn, id);
	}
}

public DisableProtection(id)
{
	id -= TASK_PROTECTION_ID;
	//if(!CheckFlag(IsPlayerAlive, id) || !is_user_connected(id)) return;
	if(!is_user_alive(id)) return;
	
	set_user_godmode(id);
	
	if(g_iNoShotProtection) set_member(id, m_bIsDefusing, false);
	
	if(g_iGlowEffect) set_user_rendering( id, kRenderFxNone, 0, 0, 0, kRenderNormal, 0 );
}

public TaskCountdownRestart()
{
	switch(	--g_iWarmUpTime )
	{
		case 0:
		{
			g_bIsWarpUp = false;
			unregister_message( g_MsgRoundTime, g_hookMsgRoundTime );
			
			set_cvar_num("sv_restart", 1);
		
			set_task( 2.0, "EndHud" );
		}
	}
}

public EndHud()
{
	set_hudmessage(g_iColorRed, g_iColorGreen, g_iColorBlue, -1.0, 0.3, 0, 0.0, 5.0, 0.0, 0.0);
	ShowSyncHudMsg(0, CreateHudSyncObj(), "Bemelegítő kör vége!^nÉles kör!");
}

public Message_RoundTime( msgid, dest, receiver ) 
{
	const ARG_TIME_REMAINING = 1;
	if(g_bIsWarpUp) set_msg_arg_int( ARG_TIME_REMAINING, ARG_SHORT, g_iWarmUpTime );
	else set_msg_arg_int( ARG_TIME_REMAINING, ARG_SHORT, g_iPlayerFrags[receiver] );
}

public ShowLeader()
{
	if(!g_iLeaderId) return;
	
	set_hudmessage( g_iColorRed, g_iColorGreen, g_iColorBlue, g_fDisplayPosX, g_fDisplayPosY, 0, 0.0, REFRESH_INTERVAL, 0.0, 0.0 );
	
	switch(g_iTiedLeaderNum)
	{
		case 0: ShowSyncHudMsg(0, g_iHudLeaderSync, "Vezet: %s (%d - %s)", g_szLeaderName, g_iLeaderLevel, g_szShortWeaponName[g_iLeaderLevel]);
		case 1: ShowSyncHudMsg(0, g_iHudLeaderSync, "Vezetnek: %s + %s (%d - %s)", g_szLeaderName, g_szTiedLeaderName, g_iLeaderLevel, g_szShortWeaponName[g_iLeaderLevel]);
		default: ShowSyncHudMsg(0, g_iHudLeaderSync, "Vezetnek: %s + %d (%d - %s)", g_szLeaderName, g_iTiedLeaderNum, g_iLeaderLevel, g_szShortWeaponName[g_iLeaderLevel]);
	}
}

public PlayWelcomeSound(id)
{
	if(g_aLevelWelcome_size && CheckFlag(IsPlayerConnected, id))
	{
		PlaySound(id, g_aLevelWelcome, g_aLevelWelcome_size);
	}
}

public GiveGrenade(id)
{
	remove_task(id);
	id -= TASK_GIVEGRENADE_ID;
	
	if(CheckFlag(IsPlayerAlive, id))
		rg_give_item(id, "weapon_hegrenade", GT_APPEND);
}

public ShowWinnerMotd()
{
	new szNextMap[32];
	new szNewMotd[2048], iLen = 0, iMax = charsmax(szNewMotd);
	new szWinnerName[32], szLastKilledName[32], szWinnerColor[8], szLoserColor[8];
	get_user_name(g_iWinnerId, szWinnerName, charsmax(szWinnerName));
	get_user_name(g_iLastKilled, szLastKilledName, charsmax(szLastKilledName));
	
	get_team_color(g_iWinnerId, szWinnerColor, charsmax(szWinnerColor));
	get_team_color(g_iLastKilled, szLoserColor, charsmax(szLoserColor));
	
	get_cvar_string("amx_nextmap", szNextMap, charsmax(szNextMap));
	

	iLen = copy(szNewMotd, charsmax(szNewMotd), "<!DOCTYPE html><html><head><meta charset='utf-8' /><style type='text/css'>body \
	{font-family:consolas;color:#00FF00;background-color:#000000;font-size: 20pt;}");
	iLen += formatex(szNewMotd[iLen], iMax - iLen, "hr {border:body;background-color:#%s;color:#%s;height:2px;}	h3 {text-align:center;} #ul {text-align:center;} \
	wn {color:#%s;} ln {color:#%s;} wc {color:#FFFFFF;} nm {font-size: 17pt;}</style></head>",szWinnerColor, szWinnerColor, szWinnerColor, szLoserColor);
	iLen += formatex(szNewMotd[iLen], iMax - iLen, "<body><h3>[GUNGAME]</h3><div id='ul'><ul><hr><wn>%s</wn> <wc>nyert!</wc><hr></ul></div>", szWinnerName);
	iLen += formatex(szNewMotd[iLen], iMax - iLen, "<h3>utolsó halál: <ln>%s</ln></h3><h3><wc><nm>Következő pálya:</nm></wc>%s</h3></body></html>", szLastKilledName, szNextMap);
	/**width:100%; margin:0px auto;**/
	for(new id = 1; id <= g_iMaxPlayers; id++)
	{
		if(!CheckFlag(IsPlayerConnected, id)) continue;
		
		show_motd(id, szNewMotd);
	}	
}

StartMapVote()
{
	if(callfunc_begin(g_szVoteFunction, g_szCallPluginName) == 1)
	{
		//callfunc_push_int(0);
		callfunc_end();	
	}
}

PlayerProtection(id)
{
	//if(!CheckFlag(IsPlayerAlive, id) || !is_user_connected(id)) return;
	if(!is_user_alive(id)) return;
	
	set_user_godmode( id, .godmode = 1 );
	
	if(g_iGlowEffect)
	{
		switch(get_member(id, m_iTeam)) 
		{
			case TT: set_user_rendering( id, kRenderFxGlowShell, RED_TEAM_COLOUR, kRenderNormal, GLOW_THICK );
			case CT: set_user_rendering( id, kRenderFxGlowShell, BLUE_TEAM_COLOUR, kRenderNormal, GLOW_THICK );
		}
	}
	
	if(g_iProtectionBar) ShowBar(id, g_fProtectionTime);
	
	if(g_iNoShotProtection) set_member(id, m_bIsDefusing, true);
	
	new TaskID = TASK_PROTECTION_ID + id;
	
	remove_task(TaskID);
	set_task( g_fProtectionTime, "DisableProtection", TaskID );
}

ReadCfg()
{
	new szFilePath[64];
	
	get_localinfo("amxx_configsdir", szFilePath, charsmax(szFilePath));
	formatex(szFilePath, charsmax(szFilePath), "%s/re_gungame.ini",szFilePath);
	
	new FileHandle = fopen(szFilePath, "rt");
	
	if(!FileHandle)
	{
		new szErrorMsg[64];
		formatex(szErrorMsg, charsmax(szErrorMsg), "File doesnt exists: %s",szFilePath);
		
		return set_fail_state(szErrorMsg);
	}
	
	new szTemp[250], szKey[32], szValue[512];
	new iSection;
	
	while(!feof(FileHandle))
	{
		fgets(FileHandle, szTemp, charsmax(szTemp));
		trim(szTemp);
		
		if (szTemp[0] == '[')
		{
			iSection++;
			continue;
		}
		
		if(!szTemp[0] || szTemp[0] == ';' || szTemp[0] == '/') continue;
		
		strtok(szTemp, szKey, charsmax(szKey), szValue, charsmax(szValue), '=');
		trim(szKey);
		trim(szValue);

		switch(iSection)
		{
			case BASIC:
			{
				if(equal(szKey, "game_name"))
				{
					copy(g_szGameName, charsmax(g_szGameName), szValue);
				}
				if(equal(szKey, "vote_before"))
				{
					g_iLevelBeforeVote = str_to_num(szValue);
				}
				else if(equal(szKey, "vote_function"))
				{
					copy(g_szVoteFunction, charsmax(g_szVoteFunction), szValue);
				}
				else if(equal(szKey, "vote_plugin"))
				{
					copy(g_szCallPluginName, charsmax(g_szCallPluginName), szValue);
				}
				else if(equal(szKey, "save_type"))
				{
					g_iLevelSaveType = str_to_num(szValue);
				}
				else if(equal(szKey, "newplayer_level"))
				{
					g_iNewPlayerLevel = str_to_num(szValue);
				}
				else if(equal(szKey, "display_leader"))
				{
					g_iDisplayLeader = str_to_num(szValue);
				}
				else if(equal(szKey, "display_pos_x"))
				{
					g_fDisplayPosX = str_to_float(szValue);
				}
				else if(equal(szKey, "display_pos_y"))
				{
					g_fDisplayPosY = str_to_float(szValue);
				}
				else if(equal(szKey, "hud_color_red"))
				{
					g_iColorRed = str_to_num(szValue);
				}
				else if(equal(szKey, "hud_color_green"))
				{
					g_iColorGreen = str_to_num(szValue);
				}
				else if(equal(szKey, "hud_color_blue"))
				{
					g_iColorBlue = str_to_num(szValue);
				}
				else if(equal(szKey, "winner_motd"))
				{
					g_iWinnerMotd = str_to_num(szValue);
				}
				else if(equal(szKey, "afk_protection"))
				{
					g_iAfkProtection = str_to_num(szValue);
				}
				else if(equal(szKey, "nade_refresh"))
				{
					g_fNadeRefreshTime = str_to_float(szValue);
				}
				else if(equal(szKey, "give_armor"))
				{
					g_iArmorValue = str_to_num(szValue);
				}
				else if(equal(szKey, "awp_ammo"))
				{
					g_iAwpAmmo = str_to_num(szValue);
				}
			}
			case DEATHMATCH:
			{
				if(equal(szKey, "spawn_delay"))
				{
					g_fSpawnDelay = str_to_float(szValue);
				}
				else if(equal(szKey, "protection_time"))
				{
					g_fProtectionTime = str_to_float(szValue);
				}
				else if(equal(szKey, "protection_bar"))
				{
					g_iProtectionBar = str_to_num(szValue);
				}
				else if(equal(szKey, "noshot_protection"))
				{
					g_iNoShotProtection = str_to_num(szValue);
				}
				else if(equal(szKey, "glow_effect"))
				{
					g_iGlowEffect = str_to_num(szValue);
				}
				else if(equal(szKey, "random_spawn"))
				{
					g_iRandomSpawn = str_to_num(szValue);
				}
			}
			case WARMUP:
			{
				if(equal(szKey, "warmup_time"))
				{
					g_iWarmUpTime = str_to_num(szValue);
				}
				else if(equal(szKey, "warmup_weapon"))
				{
					formatex(g_szWarmUpWeapon, charsmax(g_szWarmUpWeapon), "weapon_%s", szValue);
				}
			}
			case SOUND:
			{ 
				if(equal(szKey, "levelup"))
				{
					g_aLevelUp = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELUP);
				}
				else if(equal(szKey, "leveldown"))
				{
					g_aLevelDown = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELDOWN);
				}
				else if(equal(szKey, "levelsteal"))
				{
					g_aLevelSteal = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELSTEAL);
				}
				else if(equal(szKey, "nade"))
				{
					g_aLevelNade = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELNADE);
				}
				else if(equal(szKey, "knife"))
				{
					g_aLevelKnife = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELKNIFE);
				}
				else if(equal(szKey, "welcome"))
				{
					g_aLevelWelcome = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELWELCOME);
				}
				else if(equal(szKey, "winner"))
				{
					g_aLevelWinner = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELWINNER);
				}
				else if(equal(szKey, "lead"))
				{
					g_aLevelLead = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELLEAD);
				}
				else if(equal(szKey, "tiedlead"))
				{
					g_aLevelTiedLead = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELTIEDLEAD);
				}
				else if(equal(szKey, "lostlead"))
				{
					g_aLevelLostLead = ArrayCreate(SOUND_SIZE+1);
					CopyToArray(szValue, LEVELLOSTLEAD);
				}
			}
			case WEAPON:
			{
				if(equal(szKey, "glock18"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_glock18";
					SaveWeaponData(2, str_to_num(szValue), CSW_GLOCK18, 120, "weapon_glock18", szKey);
				}
				else if(equal(szKey, "usp"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_usp";
					SaveWeaponData(2, str_to_num(szValue), CSW_USP, 100, "weapon_usp", szKey);
				}
				else if(equal(szKey, "p228"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_p228";
					SaveWeaponData(2, str_to_num(szValue), CSW_P228, 52, "weapon_p228", szKey);
				}
				else if(equal(szKey, "deagle"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_deagle";
					SaveWeaponData(2, str_to_num(szValue), CSW_DEAGLE, 35, "weapon_deagle", szKey);
				}
				else if(equal(szKey, "fiveseven"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_fiveseven";
					SaveWeaponData(2, str_to_num(szValue), CSW_FIVESEVEN, 100, "weapon_fiveseven", szKey);
				}
				else if(equal(szKey, "elite"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_elite";
					SaveWeaponData(2, str_to_num(szValue), CSW_ELITE, 120, "weapon_elite", szKey);
				}
				else if(equal(szKey, "m3"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_m3";
					SaveWeaponData(1, str_to_num(szValue), CSW_M3, 32, "weapon_m3", szKey);
				}
				else if(equal(szKey, "xm1014"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_xm1014";
					SaveWeaponData(1, str_to_num(szValue), CSW_XM1014, 32, "weapon_xm1014", szKey);
				}
				if(equal(szKey, "tmp"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_tmp";
					SaveWeaponData(1, str_to_num(szValue), CSW_TMP, 120, "weapon_tmp", szKey);
				}
				else if(equal(szKey, "mac10"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_mac10";
					SaveWeaponData(1, str_to_num(szValue), CSW_MAC10, 100, "weapon_mac10", szKey);
				}
				else if(equal(szKey, "mp5navy"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_mp5navy";
					SaveWeaponData(1, str_to_num(szValue), CSW_MP5NAVY, 120, "weapon_mp5navy", szKey);
				}
				else if(equal(szKey, "ump45"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_ump45";
					SaveWeaponData(1, str_to_num(szValue), CSW_UMP45, 100, "weapon_ump45", szKey);
				}
				else if(equal(szKey, "p90"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_p90";
					SaveWeaponData(1, str_to_num(szValue), CSW_P90, 100, "weapon_p90", szKey);
				}
				else if(equal(szKey, "galil"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_galil";
					SaveWeaponData(1, str_to_num(szValue), CSW_GALIL, 90, "weapon_galil", szKey);
				}
				else if(equal(szKey, "famas"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_famas";
					SaveWeaponData(1, str_to_num(szValue), CSW_FAMAS, 90, "weapon_famas", szKey);
				}
				else if(equal(szKey, "ak47"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_ak47";
					SaveWeaponData(1, str_to_num(szValue), CSW_AK47, 90, "weapon_ak47", szKey);
				}
				if(equal(szKey, "scout"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_scout";
					SaveWeaponData(1, str_to_num(szValue), CSW_SCOUT, 90, "weapon_scout", szKey);
				}
				else if(equal(szKey, "m4a1"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_m4a1";
					SaveWeaponData(1, str_to_num(szValue), CSW_M4A1, 90, "weapon_m4a1", szKey);
				}
				else if(equal(szKey, "sg552"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_sg552";
					SaveWeaponData(1, str_to_num(szValue), CSW_SG552, 90, "weapon_sg552", szKey);
				}
				else if(equal(szKey, "sg550"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_sg550";
					SaveWeaponData(1, str_to_num(szValue), CSW_SG550, 90, "weapon_sg550", szKey);
				}
				else if(equal(szKey, "g3sg1"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_g3sg1";
					SaveWeaponData(1, str_to_num(szValue), CSW_G3SG1, 90, "weapon_g3sg1", szKey);
				}
				else if(equal(szKey, "aug"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_aug";
					SaveWeaponData(1, str_to_num(szValue), CSW_AUG, 90, "weapon_aug", szKey);
				}
				else if(equal(szKey, "m249"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_m249";
					SaveWeaponData(1, str_to_num(szValue), CSW_M249, 200, "weapon_m249", szKey);
				}
				else if(equal(szKey, "awp"))
				{
					g_szWeaponIcon[g_iMaxLevels] = "d_awp";
					SaveWeaponData(1, str_to_num(szValue), CSW_AWP, 30, "weapon_awp", szKey);
				}
				else if(equal(szKey, "hegrenade"))
				{
					g_iHeLevel = g_iMaxLevels;
					g_szWeaponIcon[g_iMaxLevels] = "d_grenade";
					SaveWeaponData(4, str_to_num(szValue), CSW_HEGRENADE, 1, "weapon_hegrenade", szKey);
				}
				else if(equal(szKey, "knife"))
				{
					g_iKnifeLevel = g_iMaxLevels;
					g_szWeaponIcon[g_iMaxLevels] = "d_knife";
					SaveWeaponData(3, str_to_num(szValue), CSW_KNIFE, 1, "weapon_knife", szKey);
				}
			}
		}
	}
	fclose(FileHandle);

	if(g_iMaxLevels > MAX_LEVELS)
		g_iMaxLevels = MAX_LEVELS;
	
	return PLUGIN_CONTINUE;
}

SaveWeaponData(iSlot, iNeedFrags, CSW_ID, iMaxAmmo, szWeaponName[], szShortName[])
{
	if(equali(szWeaponName,g_szWarmUpWeapon))
	{
		g_iWarmUpLevel = g_iMaxLevels;
	}
	g_iWeaponLevelSlot[g_iMaxLevels] = iSlot;
	g_iCswLevel[g_iMaxLevels] = CSW_ID;
	g_iMaxBpAmmoLevel[g_iMaxLevels] = iMaxAmmo;
	formatex(g_szShortWeaponName[g_iMaxLevels], WEAPON_LEN, "%s", szShortName);
	formatex(g_szWeaponLevelName[g_iMaxLevels], WEAPON_LEN, "%s", szWeaponName);
	g_iNeedFrags[g_iMaxLevels] = iNeedFrags;
	g_iMaxLevels++;
}

CopyToArray(szValue[], iArray)
{
	new szTemp2[512], szSound[SOUND_SIZE + 1];
	copy(szTemp2, SOUND_SIZE, szValue);
	
	
	while(szTemp2[0])
	{
		strtok(szTemp2, szSound, SOUND_SIZE, szTemp2, charsmax(szTemp2), ';');
		trim(szSound);
		
		if(!file_exists(szSound)) 
		{
			log_to_file("GunGame_Error.txt", "File '%s' doesn't exist", szSound);
			continue;
		}
		
		switch(iArray)
		{
			case LEVELUP:
			{
				ArrayPushString(g_aLevelUp, szSound);
				g_aLevelUp_size++;
			}
			case LEVELDOWN:
			{
				ArrayPushString(g_aLevelDown, szSound);
				g_aLevelDown_size++;
			}
			case LEVELSTEAL:
			{
				ArrayPushString(g_aLevelSteal, szSound);
				g_aLevelSteal_size++;
			}
			case LEVELNADE:
			{
				ArrayPushString(g_aLevelNade, szSound);
				g_aLevelNade_size++;
			}
			case LEVELKNIFE:
			{
				ArrayPushString(g_aLevelKnife, szSound);
				g_aLevelKnife_size++;
			}
			case LEVELWELCOME:
			{
				ArrayPushString(g_aLevelWelcome, szSound);
				g_aLevelWelcome_size++;
			}
			case LEVELWINNER:
			{
				ArrayPushString(g_aLevelWinner, szSound);
				g_aLevelWinner_size++;
			}
			case LEVELLEAD:
			{
				ArrayPushString(g_aLevelLead, szSound);
				g_aLevelLead_size++;
			}
			case LEVELTIEDLEAD:
			{
				ArrayPushString(g_aLevelTiedLead, szSound);
				g_aLevelTiedLead_size++;
			}
			case LEVELLOSTLEAD:
			{
				ArrayPushString(g_aLevelLostLead, szSound);
				g_aLevelLostLead_size++;
			}
		}
	}
}

#define HUD_HIDE_TIMER (1<<4)
#define HUD_HIDE_MONEY (1<<5)

hide_hud(id)
{
	if(CheckFlag(IsPlayerBot, id)) return;
	
	// hide money
	emessage_begin(MSG_ONE, g_MsgHideWeapon, _, id);
	ewrite_byte(HUD_HIDE_TIMER|HUD_HIDE_MONEY);
	emessage_end();

	// hide crosshair that appears from hiding money
	emessage_begin(MSG_ONE, g_MsgCrosshair, _, id);
	ewrite_byte(0);
	emessage_end();
}

#define NAME_LEN	31
#define IP_LEN		22
#define STEAM_LEN	34

SavePlayerData(id, CellNum)
{
	g_eSavedData[CellNum][iSavedLevel] = g_iPlayerLevel[id];
	g_eSavedData[CellNum][iSavedKills] = g_iPlayerFrags[id];
	g_eSavedData[CellNum][iTimeStamp] = _:get_gametime();
	
	switch(g_iLevelSaveType)
	{
		case 0: get_user_name(id, g_eSavedData[CellNum][szAuth], NAME_LEN);
		case 1: get_user_ip(id, g_eSavedData[CellNum][szAuth], IP_LEN);
		case 2: get_user_authid(id, g_eSavedData[CellNum][szAuth], STEAM_LEN);
	}	
}

bool:GetPlayerData(id)
{
	new szAuthData[STEAM_LEN+1];
	switch(g_iLevelSaveType)
	{
		case 0: get_user_name(id, szAuthData, NAME_LEN);
		case 1: get_user_ip(id, szAuthData, IP_LEN);
		case 2: get_user_authid(id, szAuthData, STEAM_LEN);
	}
	
	for( new i; i < MAX_SAVES + 1; i++)
	{
		if(!g_eSavedData[i][iSavedLevel]) continue;

		if(!equal(szAuthData, g_eSavedData[i][szAuth])) continue; 
		
		g_iPlayerLevel[id] = g_eSavedData[i][iSavedLevel];
		g_iPlayerFrags[id] = g_eSavedData[i][iSavedKills];
		
		g_eSavedData[i][iSavedLevel] = 0;
		g_eSavedData[i][iSavedKills] = 0;
		g_eSavedData[i][iTimeStamp] = 0;
		arrayset(g_eSavedData[i][szAuth], 0, STEAM_LEN + 1);
		
		return true;
	}
	return false;
}

SaveDisconnectPlayer(id)
{
	new iOldestStamp, iOldestPlayer;
	new bool:bSaved = false;
	
	for( new i; i < MAX_SAVES + 1; i++)
	{
		if(g_eSavedData[i][iTimeStamp] > iOldestStamp)
		{
			iOldestStamp = g_eSavedData[i][iTimeStamp];
			iOldestPlayer = i;
		}
		
		if(g_eSavedData[i][iSavedLevel]) continue;
		
		SavePlayerData(id, i);
		
		bSaved = true;
		
		break;
	}
	if(!bSaved)
	{
		SavePlayerData(id, iOldestPlayer);
	}
}

ResetTiedLeader()
{
	for(new i = 1; i <= g_iTiedLeaderNum; i++)
	{
		g_iTiedLeaderId[i] = 0;
	}
	g_iTiedLeaderNum = 0;
}

CalculateNewLeader()
{
	g_iLeaderId = 0;
	g_iLeaderLevel = 0;
	ResetTiedLeader();
	
	new iTempPlayerLevel;
	
	for(new id = 1; id <= g_iMaxPlayers; id++)
	{
		if(!CheckFlag(IsPlayerConnected, id)) continue;
		
		iTempPlayerLevel = g_iPlayerLevel[id];
		if(iTempPlayerLevel == START_LEVEL) continue;
		
		if(iTempPlayerLevel > g_iLeaderLevel)
		{
			g_iLeaderLevel = iTempPlayerLevel;
			g_iLeaderId = id;
			ResetTiedLeader();
		}
		else if(iTempPlayerLevel == g_iLeaderLevel)
		{
			g_iTiedLeaderNum++;
			g_iTiedLeaderId[g_iTiedLeaderNum] = id;
		}	
	}
	
	if(g_iLeaderId) 
	{
		get_user_name(g_iLeaderId, g_szLeaderName, charsmax(g_szLeaderName));
		// PLAY SOUND LEAD
		if(g_aLevelLead_size)
		{
			PlaySound(g_iLeaderId, g_aLevelLead, g_aLevelLead_size);
		}
	}
	if(g_iTiedLeaderNum) 
	{
		get_user_name(g_iTiedLeaderId[g_iTiedLeaderNum], g_szTiedLeaderName, charsmax(g_szTiedLeaderName));
		
		for(new i = 1; i <= g_iTiedLeaderNum; i++)
		{
			if(g_aLevelTiedLead_size)
			{
				PlaySound(g_iTiedLeaderId[i], g_aLevelTiedLead, g_aLevelTiedLead_size);
			}
		}
	}
}

get_death_reason(const id, const pevAttacker, &iType)
{
	new iInflictor = get_entvar(id, var_dmg_inflictor);
	
	if( iInflictor == pevAttacker )
	{
		new iWpnId = get_member(get_member(pevAttacker, m_pActiveItem), m_iId);

		if(iWpnId == CSW_KNIFE) iType = KNIFE;
		else iType = BULLET;
	}
	else
	{
		if(get_member(id, m_bKilledByGrenade)) iType = GRENADE;
		else  iType = WORLD;
	}
}

GiveBetterWeapon(const id, const iLevel)
{
	if(iLevel <= g_iMaxLevels && CheckFlag(IsPlayerAlive, id))
	{
		DeleteStatusIcon(id, iLevel);
		SendStatusIcon(id, iLevel);
		rg_remove_item(id, g_szWeaponLevelName[iLevel-1]);
		rg_give_item(id, g_szWeaponLevelName[iLevel], GT_APPEND);
		if(iLevel != g_iHeLevel && iLevel != g_iKnifeLevel)
		{
			cs_set_user_bpammo(id, g_iCswLevel[iLevel], g_iMaxBpAmmoLevel[iLevel]);
			ExecuteHamB(Ham_Weapon_RetireWeapon, get_member(id, m_rgpPlayerItems, 3));
		}
	}
}

PlaySound(const id, Array:aArray, aSize)
{
	if(CheckFlag(IsPlayerBot, id) || !CheckFlag(IsPlayerConnected, id)) return;
	
	new szSound[SOUND_SIZE];
	ArrayGetString(aArray, random_num(0, aSize-1), szSound, charsmax(szSound));
	
	if(IsMp3Format(szSound)) client_cmd(id, "mp3 play %s", szSound);
	else rh_emit_sound2(id, id, CHAN_STATIC, szSound[6], VOL_NORM, ATTN_NORM);
	//client_cmd(id, "spk %s", szSound[6]);
}

PrecacheSounds(Array:aArray, aSize)
{
	new szSound[SOUND_SIZE];
	new iLen = charsmax(szSound);
	
	for(new i; i < aSize; i++)
	{
		ArrayGetString(aArray, i, szSound, iLen );
		
		if(IsMp3Format(szSound)) precache_generic(szSound);
		else precache_sound(szSound[6]);
	}
}

RefreshFragInformer(const id, const iNeedFrags, const iAttackerFrags, const iLevel)
{
	if(CheckFlag(IsPlayerBot, id)) return;
	
	static iLeftFrags; iLeftFrags = iNeedFrags - iAttackerFrags;
	
	set_hudmessage( g_iColorRed, g_iColorGreen, g_iColorBlue, -1.0, 0.95, 0, 0.0, 20.0, 0.0, 0.0, -1);
	ShowSyncHudMsg(id, g_iHudFragSync, "Jelenlegi szinted: %d - %s^nfegyverrel, hátravan: %d ölés", iLevel, g_szShortWeaponName[iLevel], iLeftFrags);
}

readSpawns()
{
	//-617 2648 179 16 -22 0 0 -5 -22 0
	// Origin (x,y,z), Angles (x,y,z), Team (0 = ALL, 1 = T, 2 = CT), vAngles(x,y,z), 

	new szMap[32], szConfig[32],  MapFile[256];

	get_mapname(szMap, 31);
	get_localinfo("amxx_configsdir", szConfig, charsmax(szConfig));
	format(MapFile, 255, "%s\gungame\%s.spawns.cfg", szConfig, szMap);
	g_iTotalSpawns = 0;

	if (file_exists(MapFile)) 
	{
		new szData[124], iLen;
		new iLine = 0;
		new pos[12][8];

		while(g_iTotalSpawns < MAX_SPAWNS && (iLine = read_file(MapFile , iLine , szData , 123 , iLen) ) != 0 ) 
		{
			if (strlen(szData)<2 || szData[0] == '[')
				continue;

			parse(szData, pos[1], 7, pos[2], 7, pos[3], 7, pos[4], 7, pos[5], 7, pos[6], 7, pos[7], 7, pos[8], 7, pos[9], 7, pos[10], 7);

			// Origin
			g_iSpawnVecs[g_iTotalSpawns][0] = str_to_num(pos[1]);
			g_iSpawnVecs[g_iTotalSpawns][1] = str_to_num(pos[2]);
			g_iSpawnVecs[g_iTotalSpawns][2] = str_to_num(pos[3]);

			//Angles
			g_iSpawnAngles[g_iTotalSpawns][0] = str_to_num(pos[4]);
			g_iSpawnAngles[g_iTotalSpawns][1] = str_to_num(pos[5]);
			g_iSpawnAngles[g_iTotalSpawns][2] = str_to_num(pos[6]);

			// Teams
			g_iSpawnTeam[g_iTotalSpawns] = str_to_num(pos[7]);

			//v-Angles
			g_iSpawnVAngles[g_iTotalSpawns][0] = str_to_num(pos[8]);
			g_iSpawnVAngles[g_iTotalSpawns][1] = str_to_num(pos[9]);
			g_iSpawnVAngles[g_iTotalSpawns][2] = str_to_num(pos[10]);

			g_iTotalSpawns++;
		}
	}
	return PLUGIN_CONTINUE;
}

public spawn_Preset(id)
{
	if (g_iTotalSpawns < 2) return PLUGIN_CONTINUE;

	new Float:fSpawnVecs[3], Float:fSpawnAngles[3], Float:fSpawnVAngles[3];
	new Float:loc[32][3], locnum;
	new n, x, iNum, iFinal = -1;
	new team = get_member(id, m_iTeam);
	
	//cache locations
	for(new pId; pId <= g_iMaxPlayers; pId++)
	{
		if(CheckFlag(IsPlayerAlive, pId) && pId != id && get_member(pId, m_iTeam) != team)
		{
			get_entvar(pId, var_origin, loc[locnum]);
			locnum++;
		}
	}
	
	iNum = 0;
	
	//get a random spawn
	n = random_num(0, g_iTotalSpawns-1);
	
	while (iNum <= g_iTotalSpawns)
	{
		//have we visited all the spawns yet?
		if(iNum == g_iTotalSpawns) break;
	
		if(n < g_iTotalSpawns - 1) n++;
		else n = 0;
	
		// inc the number of spawns we've visited
		iNum++;

		if((team == 1 && g_iSpawnTeam[n] == 2) || (team == 2 && g_iSpawnTeam[n] == 1)) continue;

		iFinal = n;
		IVecFVec(g_iSpawnVecs[n], fSpawnVecs);
		
		for (x = 0; x < locnum; x++)
		{
			new Float:distance = get_distance_f(fSpawnVecs, loc[x]);
			if (distance < 500.0)
			{
				//invalidate
				iFinal = -1;
				break;
			}
		}

		if (iFinal == -1) continue;

		new trace = trace_hull(fSpawnVecs,1);
	
		if(trace) continue;

		if(locnum < 1) break;

		if(iFinal != -1) break;
	}

	if (iFinal != -1)
	{
		new Float:mins[3], Float:maxs[3], Float:size[3];
	
		IVecFVec(g_iSpawnVecs[iFinal], fSpawnVecs);
		IVecFVec(g_iSpawnAngles[iFinal], fSpawnAngles);
		IVecFVec(g_iSpawnVAngles[iFinal], fSpawnVAngles);
	
		get_entvar(id, var_mins, mins);
		get_entvar(id, var_maxs, maxs);
		
		size[0] = maxs[0] - mins[0];
		size[1] = maxs[1] - mins[1];
		size[2] = maxs[2] - mins[2];
		
		set_entvar(id, var_size, size);
		set_entvar(id, var_origin, fSpawnVecs);
		set_entvar(id, var_fixangle, 1);

		set_entvar(id, var_angles, fSpawnAngles);
		set_entvar(id, var_v_angle, fSpawnVAngles);
		set_entvar(id, var_fixangle, 1);

		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

stock ShowBar(id, Float:fTime)
{
	message_begin(MSG_ONE, g_MsgBarTime, _, id);
	write_short(floatround(fTime, floatround_round));
	message_end();
}

stock get_team_color(const id, szColor[], const iLen)
{
	switch(get_member(id, m_iTeam)) 
	{
		case TT: formatex(szColor, iLen,"FF0000");
		case CT: formatex(szColor, iLen,"1E90FF");
		default: formatex(szColor, iLen,"FFFFFF");
	}
}

/**
stock get_team_color(const id, szColor[], const iLen)
{
	switch(get_member(id, m_iTeam)) 
	{
		case TT: formatex(szColor, iLen,"FF3F3F");
		case CT: formatex(szColor, iLen,"99CCFF");
		default: formatex(szColor, iLen,"FFFFFF");
	}
}
**/

const ICON_ON  	= 1;
const ICON_OF	= 0;
/**
stock SendScenarioIcon(id, iLevelKills, iKills)
{
	static iKillsLeft; iKillsLeft = iLevelKills - iKills;
	
	message_begin(MSG_ONE, g_MsgScenarioIcon, _, id);
	write_byte(ICON_ON);
	write_string(g_szScenarioIcons[iKillsLeft]);
	write_byte(0);	// no alpha value
	message_end();
}
**/
stock SendStatusIcon(id, iLevel)
{
	message_begin(MSG_ONE, g_MsgStatusIcon, {0,0,0}, id);
	write_byte(ICON_ON);
	write_string(g_szWeaponIcon[iLevel + 1]);
	write_byte(g_iColorRed);
	write_byte(g_iColorGreen);
	write_byte(g_iColorBlue);
	message_end();
}

stock DeleteStatusIcon(id, iLevel)
{
	message_begin(MSG_ONE, g_MsgStatusIcon, {0,0,0}, id);
	write_byte(ICON_OF);
	write_string(g_szWeaponIcon[iLevel]);
	message_end();
}