/*
 *
 * bAnTAi - Y.A.S.C. (Yet Another Sniper Control)
 * (c) 2004-2005
 *
 * Code based on WillyYumYum's Sniper Control 
 * and ideas from SuicideDog's AWP Limiter.
 *
 * NOTE: This plugins requires the "Engine" module
 * to be active
 */

#include <amxmodx>
#include <amxmisc>
#include <engine>

#pragma semicolon                1      // force ; usage, just 'cause

#define INCLUDE_SCOUT            1      // Include scouts in sniper rifle

new g_scTitle[]   = "Y.A.S.C.";
new g_scVersion[] = "1.0";
new g_scAuthor[]  = "bAnTAi";

#define MAXAWPS 1 // Number of awps a team can have
#define MAXAUTOSNIPERS 1 // Number of autosnipers a team can have
#define MINPLAYERS 10 // How many players do we want on the server before we allow snipers?
#define WINSPREAD 5 // the difference when it starts restricting awps for winning team

#define TS 1
#define CTS 2

new bool:g_hasAwp[33];        
new bool:g_hasAutosniper[33];

new g_scLimitReached[] = "Sniper rifle limit reached for your team!";
new g_scNotEnoughPlayers[] = "Not enough players on the server to use snipers!";

new const AWP[] = "models/w_awp.mdl";

new const AUTOSNIPER[2][] =
{
    "models/w_sg550.mdl",               // CSW_SG550
    "models/w_g3sg1.mdl"                // CSW_G3SG1
};

new g_awps[3];
new g_autosnipers[3];

public menuAwp(id, key) {
	if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

	new players = get_playersnum(1);
	if (players<MINPLAYERS) {
		engclient_cmd(id, "menuselect" ,"10");
		client_print(id, print_center, g_scNotEnoughPlayers);
		return PLUGIN_HANDLED;
	}

	new team = get_user_team(id);

	/*
	 * TS: AWP Key 4, AUTOSNIPER Key 5
	 * CTS: AWP Key 5, AUTOSNIPER Key4
	 */
	if ((team==TS && key==5) || (team==CTS && key==4))
		menuAutosniper(id, key);
		
	if (g_awps[team]<MAXAWPS || g_hasAwp[id])
		return PLUGIN_CONTINUE;

	engclient_cmd(id, "menuselect" ,"10");
	client_print(id, print_center, g_scLimitReached);

	return PLUGIN_HANDLED;
}

public menuAutosniper(id, key) {
	if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

        new players = get_playersnum(1);
        if (players<MINPLAYERS) {
                engclient_cmd(id, "menuselect" ,"10");
                client_print(id, print_center, g_scNotEnoughPlayers);
                return PLUGIN_HANDLED;
        }
									
	new team = get_user_team(id);
	if(g_autosnipers[team]<MAXAUTOSNIPERS || g_hasAutosniper[id])
		return PLUGIN_CONTINUE;

	engclient_cmd(id, "menuselect" ,"10");
	client_print(id, print_center, g_scLimitReached);

	return PLUGIN_HANDLED;
}

public bool:check_primary( id ) {
	new iWeapons[32];
	new iTotalWeapons = 0;
	get_user_weapons(id, iWeapons, iTotalWeapons);

    	for ( new i = 0; i < iTotalWeapons; i++ ) {
		switch (iWeapons[i]) {
		        case CSW_M3:      return true;
	        	case CSW_XM1014:  return true;
			case CSW_MP5NAVY: return true;
	            	case CSW_TMP:     return true;
	            	case CSW_P90:     return true;
	            	case CSW_MAC10:   return true;
	            	case CSW_UMP45:   return true;
	            	case CSW_AK47:    return true;
	            	case CSW_SG552:   return true;
	            	case CSW_GALI:    return true;
	            	case CSW_FAMAS:   return true;
	            	case CSW_M4A1:    return true;
	            	case CSW_AUG:     return true;
	            	case CSW_SCOUT:   return true;
	            	case CSW_AWP:     return true;
	            	case CSW_G3SG1:   return true;
	            	case CSW_SG550:   return true;
	            	case CSW_M249:    return true;
		}
	}
	return false;
}

public bool:check_awp(id) {
    new iWeapons[32];
    new iTotalWeapons = 0;
    get_user_weapons(id, iWeapons, iTotalWeapons);

    for (new i = 0; i < iTotalWeapons; i++) {
        switch (iWeapons[i]) {
            case CSW_AWP:     return true;
        }
    }
    return false;
}

public bool:check_autosniper(id) {
    new iWeapons[32];
    new iTotalWeapons = 0;
    get_user_weapons(id, iWeapons, iTotalWeapons);

    for (new i = 0; i < iTotalWeapons; i++) {
        switch (iWeapons[i]) {
            case CSW_G3SG1:   return true;
            case CSW_SG550:   return true;
        }
    }
    return false;
}
									    

public vexd_pfntouch(pToucher, pTouched) {
    if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

    new iTouchId   = pToucher;
    new iPlayerId  = pTouched;

    if (iPlayerId < 0 || iPlayerId > 32 || !is_user_alive(iPlayerId))
        return PLUGIN_CONTINUE;

    new szClassName[32];
    entity_get_string(iTouchId, EV_SZ_classname, szClassName, 31);

    if (equal(szClassName, "weaponbox")) {
    	// a dropped or already 'fired' weapon
        new szGunModel[32];
        entity_get_string(iTouchId, EV_SZ_model, szGunModel, 31);

        new bool:bHasPrimaryWeapon = check_primary(iPlayerId);

	// Make a function which does this check instead cause this i really ugly!
	if (get_entity_flags(iTouchId) & FL_ONGROUND && !bHasPrimaryWeapon && (equal(szGunModel, AWP) || equal(szGunModel, AUTOSNIPER[0]) || equal(szGunModel, AUTOSNIPER[1]))) {
	        new players = get_playersnum(1);
	        if (players<MINPLAYERS) {
			// Let it lie on the ground
			set_entity_flags(iTouchId, FL_ONGROUND, 0);
			client_print(iPlayerId, print_center, g_scNotEnoughPlayers);
			return PLUGIN_CONTINUE;
		}

		if (equal(szGunModel, AWP)) {
			new team = get_user_team(iPlayerId);
			if (g_awps[team]<MAXAWPS) {
				set_entity_flags(iTouchId, FL_ONGROUND, 1);
			} else {
				client_print(iPlayerId, print_center , g_scLimitReached);
			}
		} else if (equal(szGunModel, AUTOSNIPER[0]) || equal(szGunModel, AUTOSNIPER[1])) {
                        new team = get_user_team(iPlayerId);
		    	if (g_autosnipers[team]<MAXAWPS) {
	                	set_entity_flags(iTouchId, FL_ONGROUND, 1);
	                } else {
	                        client_print(iPlayerId, print_center , g_scLimitReached);
	                }
		}
	}
    }
    return PLUGIN_CONTINUE;
}

public cmdDrop(id) {
    if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

    new team = get_user_team(id);

    new iAmmo, iClip;
    new iWeap = get_user_weapon(id, iAmmo, iClip);

    if (check_awp(id) && iWeap == CSW_AWP) {
	g_hasAwp[id] = false;
	--g_awps[team];
    } else if (check_autosniper(id) && (iWeap == CSW_G3SG1 || iWeap == CSW_SG550)) {
    	g_hasAutosniper[id] = false;
	--g_autosnipers[team];
    }

    return PLUGIN_CONTINUE;
}

public evPickUp(id) {
    if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

    new team = get_user_team(id);

    if(check_awp(id) && !g_hasAwp[id]) {
        g_hasAwp[id] = true;
        ++g_awps[team];
    } else if (check_autosniper(id) && !g_hasAutosniper[id]) {
    	g_hasAutosniper[id] = true;
	++g_autosnipers[team];
    }

    if (g_hasAwp[id] && !check_awp(id)) {
        // Has a primary weapon and HAD sniper, but bought new non-sniper rifle weapon ( no drop event )
        g_hasAwp[id] = false;
        --g_awps[team];
    } else if (g_hasAutosniper[id] && !check_autosniper(id)) {
    	g_hasAutosniper[id] = false;
	--g_autosnipers[team];
    }

    return PLUGIN_CONTINUE;
}

public evRestartRound() {
    if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

    for (new i=0; i<3; i++) {
    	g_awps[i] = 0;
	g_autosnipers[i] = 0;
    }

    for(new a=1; a<33; ++a) {
    	g_hasAwp[a] = false;
        g_hasAutosniper[a] = false;
    }

    return PLUGIN_CONTINUE;
}

public sc_remove_data(id) {
    new team = get_user_team(id);

    if (g_hasAwp[id]) {
    	g_hasAwp[id] = false;
	--g_awps[team];
    } else if (g_hasAutosniper[id]) {
        g_hasAutosniper[id] = false;
        --g_autosnipers[team];
    }

    return PLUGIN_CONTINUE;
}

public client_disconnect(id) {
    if (!get_cvar_num("yasc")) return PLUGIN_CONTINUE;

    sc_remove_data(id);

    return PLUGIN_CONTINUE;
}

public evDeath() {
    new id = read_data(2);
    sc_remove_data(id);

    return PLUGIN_CONTINUE;
}

public plugin_init() {
	register_plugin(g_scTitle, g_scVersion, g_scAuthor);

	register_cvar("yasc", "1");

	// Standard Menus
	register_menucmd(register_menuid("BuyRifle" , 1 ), (1<<4), "menuAwp" );        //  T: AWP, CT: Sig SG-550 Sniper
	register_menucmd(register_menuid("BuyRifle" , 1 ), (1<<5), "menuAwp" );        // CT: AWP,  T: H&K G3/SG-1 Sniper Rifle


	// Block Aliases and Vgui menus - because steam sucks and uses aliases to buy rifles ?!?!?
	register_clcmd("awp",      "menuAwp");
	register_clcmd("magnum",   "menuAwp");
	register_clcmd("g3sg1",    "menuAutosniper");
	register_clcmd("d3au1",    "menuAutosniper");
	register_clcmd("sg550",    "menuAutosniper");
	register_clcmd("krieg550", "menuAutosniper");

	// Not sure these are needed as key is always 0 when using VGUI
	register_menucmd( -31 ,(1<<4), "menuAwp" ); //  T: AWP, CT: Sig SG-550 Sniper        - VGUI
	register_menucmd( -31 ,(1<<5), "menuAwp" ); // CT: AWP,  T: H&K G3/SG-1 Sniper Rifle - VGUI

	register_event( "WeapPickup", "evPickUp", "b"); // 3 = Scout, 13 = SG-550, 18 = AWP, G3/SG-1
	register_clcmd( "drop", "cmdDrop");
	register_event( "DeathMsg", "evDeath", "a");
	register_event( "TextMsg", "evRestartRound", "a", "2&Game_C", "2&Game_w");

	return PLUGIN_CONTINUE;
}
