#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#include <jailbreak>
#include <cstrike>
#include <colorchat>
#include <nvault>

#define PLUGIN "Zadania JB"
#define VERSION "1.0"
#define AUTHOR "cypis"

#define PRZEZ_RUNDE (1<<1)
#define PRZEZ_MAPE (1<<2)
#define ZAPISZ (1<<3)

#define WYKONANE 99999

#define LIMIT_GRACZY 10

enum DANE
{
	ZADANIE[64],
	LIMIT,
	FLAGI
}

new zadania[][DANE] = 
{
	{"Zabij 20 CT w ciagu mapy", 			20, 	PRZEZ_MAPE}, 	//0
	{"Zdobadz 10 zyczen w ciagu mapy", 		10, 	PRZEZ_MAPE}, 	//1
	{"Zabij 5 graczy przez runde", 			5, 	PRZEZ_RUNDE},	//2
	{"Badz poszukiwany 10 razy w ciagu mapy", 	10, 	PRZEZ_MAPE}, 	//3
	{"Przegraj 3000 minut na serwerze", 		3000, 	ZAPISZ}, 	//4
	{"Zabij ogolnie 200 CT", 			200, 	ZAPISZ},	//5
	{"Ukradnij bron CT i zabij 3 CT w ciagu rundy", 3, 	PRZEZ_RUNDE}	//6
}

new vault;
new postep_gracza[33][sizeof zadania];
new user_get_weapon[33];
new bool:zyczenie;

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	RegisterHam(Ham_Killed, "player", "SmiercGraczaPost", 1);

	register_event("HLTV", "KoniecRundy", "a", "1=0", "2=0");
	register_message(SVC_INTERMISSION, "KoniecMapy");
	
	register_clcmd("say /misje", "MenuZadania");
	register_clcmd("say /zadania", "MenuZadania");
	
	vault = nvault_open("zadania");
}

public MenuZadania(id)
{
	new cb = menu_makecallback("CallbackZadania");
	new menu = menu_create("Zadania:", "HandleZadania");
	
	new szTemp[128], szInt[10];
	for(new i=0; i < sizeof zadania; i++)
	{
		num_to_str(i, szInt, 9);
		formatex(szTemp, 127, "%s [%i/%i]", zadania[i][ZADANIE], postep_gracza[id][i] == WYKONANE? zadania[i][LIMIT]: min(postep_gracza[id][i], zadania[i][LIMIT]), zadania[i][LIMIT]);
		menu_additem(menu, szTemp, szInt, .callback=cb);
	}
	menu_display(id, menu);
	return PLUGIN_HANDLED;
}

public CallbackZadania(id, menu, item)
{
	if(get_playersnum() < LIMIT_GRACZY)
		return ITEM_DISABLED;
	
	new info[10], i, callback;
	menu_item_getinfo(menu, item, i, info, 9, _, _, callback);
	i = str_to_num(info);
	if(postep_gracza[id][i] >= zadania[i][LIMIT] || postep_gracza[id][i] == WYKONANE)
		return ITEM_DISABLED;
	
	return ITEM_ENABLED;
}

public HandleZadania(id, menu, item)
{
	if(item == MENU_EXIT)
		return;

	MenuZadania(id);
}

public OnLastPrisonerShowWish(id)
{
	if(get_playersnum() < LIMIT_GRACZY)
		return;
	
	postep_gracza[id][1]++;
	zyczenie = true;
}

public OnPrisonerWanted(id)
{
	if(get_playersnum() < LIMIT_GRACZY)
		return;
	
	postep_gracza[id][3]++;
}

public OnPrisonerTakeWeapon(id, weapon)
{
	if(zyczenie)
		return;
	
	user_get_weapon[id] = weapon;
}

public SmiercGraczaPost(id, attacker, shouldgib)
{	
	if(zyczenie)
		return HAM_IGNORED;
	
	if(get_playersnum() < LIMIT_GRACZY)
		return HAM_IGNORED;
	
	if(!is_user_connected(id) || !is_user_connected(attacker) || get_user_team(attacker) != 1 || id == attacker)
		return HAM_IGNORED;
	
	if(get_user_team(id) == 2)
	{
		if(user_get_weapon[attacker] && user_get_weapon[attacker] == get_user_weapon(attacker))
		{
			postep_gracza[attacker][6]++;
		}
		postep_gracza[attacker][5]++;
		postep_gracza[attacker][0]++;
		SprawdzPostep(attacker, 5);
	}
	postep_gracza[attacker][2]++;
	return HAM_IGNORED;
}

public KoniecMapy()
{
	for(new i=0; i < sizeof zadania; i++)
	{
		if(!(zadania[i][FLAGI] & PRZEZ_MAPE))
			continue;

		for(new id=1; id<=32; id++)
		{
			if(!is_user_connected(id))
				continue;
			SprawdzPostep(id, i);
			if(postep_gracza[id][i] != WYKONANE)
				postep_gracza[id][i] = 0;
		}	
	}
}

public KoniecRundy()
{
	for(new i=0; i < sizeof zadania; i++)
	{
		if(!(zadania[i][FLAGI] & PRZEZ_RUNDE))
			continue

		for(new id=1; id<=32; id++)
		{
			if(!is_user_connected(id))
				continue;
				
			SprawdzPostep(id, i);
			user_get_weapon[id] = 0;
			if(postep_gracza[id][i] != WYKONANE)
				postep_gracza[id][i] = 0;
		}
	}
	zyczenie = false;
}

new nazwa_gracza[33][64];
public client_putinserver(id)
{
	get_user_name(id, nazwa_gracza[id], 63);
	WczytajPostep(id);
}

public client_disconnect(id)
{
	if(get_playersnum(1) < 4)
		return;
	
	postep_gracza[id][4] += get_user_time(id, 1)/60;
	SprawdzPostep(id, 4);
}

public WczytajPostep(id)
{
	new vaultkey[96], vaultdata[10], bool:wykonal = true;
	for(new i=0; i < sizeof zadania; i++)
	{
		format(vaultkey, 95,"nick-%s-zadanie-%i", nazwa_gracza[id], i);
		nvault_get(vault, vaultkey, vaultdata, 9);
		postep_gracza[id][i] = str_to_num(vaultdata);
		if(postep_gracza[id][i] >= zadania[i][LIMIT])
			postep_gracza[id][i] = WYKONANE;
		else
			wykonal = false;
	}
	
	if(wykonal)
	{
		new flagi = get_user_flags(id);
		flagi |= ADMIN_LEVEL_H;
		set_user_flags(id, flagi);
	}
}

public SprawdzPostep(id, zadanie)
{
	if(!zadanie)
	{
		for(new i=0; i < sizeof zadania; i++)
		{
			if(postep_gracza[id][i] == WYKONANE)
				continue;
			
			if(zadania[i][LIMIT] <= postep_gracza[id][i])
			{
				postep_gracza[id][i] = WYKONANE;
				ZapisDane(id, i, postep_gracza[id][i]);

				client_print(id, 3, "[ZADANIA] Wykonales zadanie ^"%s^"", zadania[i][ZADANIE]);
			
			}
			else if(zadania[i][FLAGI] & ZAPISZ)
			{
				ZapisDane(id, i, postep_gracza[id][i]);
			}
		}
		return;
	}
	if(postep_gracza[id][zadanie] == WYKONANE)
		return;

	if(zadania[zadanie][LIMIT] <= postep_gracza[id][zadanie])
	{
		postep_gracza[id][zadanie] = WYKONANE;
		ZapisDane(id, zadanie, postep_gracza[id][zadanie]);

		client_print(id, 3, "[ZADANIA] Wykonales zadanie ^"%s^"", zadania[zadanie][ZADANIE]);
	}
	else if(zadania[zadanie][FLAGI] & ZAPISZ)
	{
		ZapisDane(id, zadanie, postep_gracza[id][zadanie]);
	}
}

public ZapisDane(id, zadanie, postep)
{
	new vaultkey[96], vaultdata[10];
	format(vaultkey, 95,"nick-%s-zadanie-%i", nazwa_gracza[id], zadanie);
	num_to_str(postep, vaultdata, 9);
	nvault_set(vault, vaultkey, vaultdata);	
}
