/*
 *	Title:
 *		CS Armor Drop (on death)
 *
 *	Summary:
 *		When a player dies, if they have armor, they will drop their armor on the ground next to their corpse.
 *  	A player can then walk over it and pick it up, letting them get a "percentage" of the armor left behind.
 *		Also, the player will recieve the same armor type as what they picked up.
 *		All armor will be deleted when round ends. Or on specified time (see cvars).
 *
 *	Cvars: 	
 *			armor_pct - (По умолчанию 20) Сколько процентов получает игрок при поднятии брони.
 *			armor_max - (По умолчанию 100) Сколько игрок может максимум поднять  брони.		
 *			armor_min - (По умолчанию 15) Сколько игрок может минимум поднять  брони.
 *			armor_removetime - (По умолчанию 120 сек) Через сколько исчезнит броня после того как игрок её потеряет
 *
 *
 *	Requires : AMXX 1.60
 *	Modules : Engine, FakeMeta
 *	Tested : Win32 (Linux untested)
 *
 *	Author:	 OneEyed
 *	Version: 1.1
 *
 *	Thanks : ccnncc99, sXy-Schreck, phear of rice, and Aunt Friggin' Connie, 
 *			For helping me test and fix this plugin!
 *
 *
 *	- Change Log:
 *		-v1.1 
 *		- Fixed to work on AMXX 1.60
 *		- Added "Armor Drop" CVAR for queries to pick up.
 */

#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <zombieplague>

//---------------These values are default, they are added to the CVAR's---------------------
//---------------Change if you want these to be defaulted to the CVAR on SERVER RESTART-----

//----------------------------------------------------------------------
//This is percentage, if its 25, only 25% of dropped armor will be given.
#define ARMOR_TAX "25"
//----------------------------------------------------------------------
// MAX armor allowed, default = 100 (Set higher, if you want players to go over 100 armor.)
#define MAXARMOR "100"
//----------------------------------------------------------------------
// Minimum armor needed for armor to drop when player dies.
#define MINARMOR "15"
//----------------------------------------------------------------------
// Time before Armor is removed from the map in seconds (unless round ends) default=2mins
#define REMOVE_TIME "120"
//----------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------------------
//-----------------------------------DO NOT EDIT BELOW THIS LINE-----------------------------------------------
//-------------------------------------------------------------------------------------------------------------
#define KEVLAR 		1
#define VESTHELM 	2
#define ARMORTYPE_OFFSET 112

#define TITLE "Armor Drop"
#define VERSION "1.0"
#define AUTHOR "OneEyed"

new g_ArmorType[33], Float:g_ArmorAmount[33], fArmor[33]

//Change this if you want a custom kevlar model
new armormodel[] = "models/w_kevlar.mdl"
new Float:multiplier
//-------------------------------------------------------------------------------------------------------------
public plugin_precache()
	precache_model(armormodel)	
//-------------------------------------------------------------------------------------------------------------
public plugin_init() {
	register_plugin(TITLE, VERSION, AUTHOR)
	register_cvar(TITLE,VERSION,FCVAR_SERVER)
	
	if(!cvar_exists("armor_pct"))
		register_cvar("armor_pct",ARMOR_TAX)
	if(!cvar_exists("armor_max"))
		register_cvar("armor_max",MINARMOR)
	if(!cvar_exists("armor_min"))
		register_cvar("armor_min",MINARMOR)
	if(!cvar_exists("armor_removetime"))
		register_cvar("armor_removetime",REMOVE_TIME)
		
	register_touch("FakeArmor","player","grabArmor")
	
	register_event("DeathMsg","createArmor","a")
	register_event( "SendAudio", "EndRound", "a", "2=%!MRAD_terwin", "2=%!MRAD_ctwin", "2=%!MRAD_rounddraw" )
}
//-------------------------------------------------------------------------------------------------------------
//-----------Delayed it to be right at the end, (doesnt work if i try to erase it on Round Start)--------------
public EndRound()
	set_task(5.0,"removeArmor",1111)

public removeArmor() {
	new tempid = -1
	while ( ( tempid = find_ent_by_class(tempid, "FakeArmor") ) > 0)
		if(is_valid_ent(tempid)) {
			remove_entity(tempid)
			remove_task(tempid)
		}
	return PLUGIN_CONTINUE
}
//-------------------------------------------------------------------------------------------------------------
// Set task to this to remove the armor after specified amount of time. (armor_removetime)
public removeThisArmor(id)
	if(is_valid_ent(id))
		remove_entity(id)
//-------------------------------------------------------------------------------------------------------------
public grabArmor(pToucher, pTouched) {
	if(zp_get_user_zombie(pTouched)) 
	{
		client_print(pTouched, print_center, "Zombie cannot use kevlar!")
	}
	else 
	{
	if(is_user_alive(pTouched) && is_user_connected(pTouched) && entity_get_float(pTouched,EV_FL_armorvalue) < float(get_cvar_num("armor_max"))) {
		new owner = entity_get_int(pToucher, EV_INT_iuser1)
		if(is_valid_ent(fArmor[owner])) {
			get_armor_values(pTouched)
			multiplier = float(get_cvar_num("armor_pct")) * 0.01
			
			//Retrieve armor values left on the dropped kevlar
			new armortype = entity_get_int(fArmor[owner], EV_INT_iuser3)
			new armoramt = entity_get_int(fArmor[owner], EV_INT_iuser4)
			
			//Set armor accordingly to how player has theirs, and what type they grab.
			if(g_ArmorType[pTouched] == 0) 
				csset_user_armor(pTouched, armoramt*multiplier, (armortype==1?KEVLAR:VESTHELM))
			else if(g_ArmorType[pTouched] == 1 && armortype == 1) 
				csset_user_armor(pTouched, entity_get_float(pTouched,EV_FL_armorvalue)+(armoramt*multiplier), KEVLAR)
			else if((g_ArmorType[pTouched] == 1 && armortype == 2) || g_ArmorType[pTouched] == 2) 
				csset_user_armor(pTouched, entity_get_float(pTouched,EV_FL_armorvalue)+(armoramt*multiplier), VESTHELM)
			
			// If their armor goes over MAXARMOR set it to MAXARMOR
			if(entity_get_float(pTouched,EV_FL_armorvalue) > float(get_cvar_num("armor_max")))
				entity_set_float(pTouched,EV_FL_armorvalue, float(get_cvar_num("armor_max")))

			g_ArmorType[pTouched] = armortype
			remove_entity(fArmor[owner])
			remove_task(fArmor[owner])
		}
	}
	}
	return PLUGIN_HANDLED
}
//-------------------------------------------------------------------------------------------------------------
public createArmor(id) {
	new victim = read_data(2) //grab user ID who died
	
	get_armor_values(victim)
	
	if(g_ArmorType[victim] <= 0 || g_ArmorAmount[victim] <= float(get_cvar_num("armor_min")))
		return PLUGIN_CONTINUE
	new origin[3]
	new Float:fOrigin[3]
	get_user_origin(victim,origin)
	for(new a=0;a<3;a++)
		fOrigin[a]=float(origin[a])

	fArmor[victim] = create_entity("info_target")
	if(fArmor[victim]) {
		entity_set_string(fArmor[victim],EV_SZ_classname,"FakeArmor")
		entity_set_model(fArmor[victim], armormodel)
		
		new Float:MinBox[3]
		new Float:MaxBox[3]
		MinBox[0] = -6.0
		MinBox[1] = -8.0
		MinBox[2] = -1.5
		MaxBox[0] = 6.0
		MaxBox[1] = 8.0
		MaxBox[2] = 1.5
		
		entity_set_vector(fArmor[victim], EV_VEC_mins, MinBox)
		entity_set_vector(fArmor[victim], EV_VEC_maxs, MaxBox)
		
		entity_set_int(fArmor[victim], EV_INT_solid, SOLID_BBOX) 
		entity_set_int(fArmor[victim], EV_INT_movetype, MOVETYPE_TOSS)
		
		// Sets iuser1 to victim ID
		entity_set_int(fArmor[victim], EV_INT_iuser1, victim)
		// Sets iuser3 to Armor Type (kevlar of vest+helm)
		entity_set_int(fArmor[victim], EV_INT_iuser3, g_ArmorType[victim])
		// Sets iuser4 to Armor Value (amount victim had when he died)
		entity_set_int(fArmor[victim], EV_INT_iuser4, floatround(g_ArmorAmount[victim]))

		entity_set_origin(fArmor[victim], fOrigin)
		set_task(float(get_cvar_num("armor_removetime")),"removeThisArmor",fArmor[victim])
	}
	return PLUGIN_HANDLED
}
//-------------------------------------------------------------------------------------------------------------
public get_armor_values(id) {
	if(entity_get_float(id,EV_FL_armorvalue) <= 0.0)
		g_ArmorType[id] = 0
	else {
		g_ArmorAmount[id] = entity_get_float(id,EV_FL_armorvalue)
		g_ArmorType[id] = get_pdata_int(id,ARMORTYPE_OFFSET)
	}	
}
//-------------------------------------------------------------------------------------------------------------
//Cstrike.inc has this function, but its broken, so i made my own that works =).
public csset_user_armor(id, Float:amount, type) {
	entity_set_float(id,EV_FL_armorvalue, amount)
	set_pdata_int(id,ARMORTYPE_OFFSET,type)	
}
//-------------------------------------------------------------------------------------------------------------