/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <amxmisc>
#include <dodx>
#include <dodfun>
#include <fakemeta>
#include <fun>

#define PLUGIN "Dod Realism Match"
#define VERSION "1.0"
#define AUTHOR "29th ID"

#define ADMIN_REQ ADMIN_CVAR
#define ROCK_MIN 2
#define ROCK_RATIO 0.75 // %
new g_server_pass[] = "29th";

new g_rocked[33];

new g_cvarBriefingTime;

new isLive
new readyAllies
new readyAxis
new gmsgTextMsg
new gmsgClanTimer
new g_pcvarJoin

new g_validservers[3][24] =
	{ "209.40.101.115:27015",
	  "209.40.101.114:27015",
	  "209.40.101.113:27015"  }

// Displays the menus
#include realismmatch/menu_mainmenu.inl
#include realismmatch/menu_enable.inl
#include realismmatch/menu_settings.inl
#include realismmatch/menu_extracommands.inl


public plugin_init() {
	new serverip[24];
	get_cvar_string( "net_address", serverip, 23 );
	if( !equal( serverip, g_validservers[0] )
	 && !equal( serverip, g_validservers[1] )
	 && !equal( serverip, g_validservers[2] ) )
		return PLUGIN_HANDLED;
		
	register_plugin(PLUGIN, VERSION, AUTHOR)
	g_pcvarJoin = register_cvar("match_joiniflive", "0")
	register_concmd("match_menu", "menu_mainmenu", ADMIN_REQ)
	register_concmd("alltalk_on", "enable_alltalk", ADMIN_REQ)
	register_concmd("alltalk_off", "disable_alltalk", ADMIN_REQ)
	register_concmd("respawn", "match_respawn")
	register_concmd("switchteams", "match_switchteams")
	register_clcmd("say /alliesready", "ready_allies")
	register_clcmd("say /axisready", "ready_axis")
	register_clcmd("say /alive", "hook_alive")
	register_clcmd("say rockthescrim", "hook_rock")
	register_clcmd("say_team %h", "hook_health")
	register_clcmd("jointeam", "match_switchteams")
	
	g_cvarBriefingTime = register_cvar( "mp_clan_briefingtime", "0" );
	
	register_menucmd(register_menuid("Match Menu"),1023,"menu_choice_mainmenu")
	register_menucmd(register_menuid("Enable Match Mode"),1023,"menu_choice_enable")
	register_menucmd(register_menuid("Settings"),1023,"menu_choice_settings")
	register_menucmd(register_menuid("Extra Commands"),1023,"menu_choice_extracommands")
	
	//register_event("ResetHUD", "reset_hud", "be")
	gmsgTextMsg = get_user_msgid("TextMsg")
	register_message(gmsgTextMsg, "timer_block")
	gmsgClanTimer = get_user_msgid("ClanTimer")
	register_message(gmsgClanTimer, "timer_block")
	register_statsfwd(XMF_DEATH)
	register_forward(FM_ClientCommand, "check_class")
	
	isLive = 0
	readyAllies = 0
	readyAxis = 0
	
	return PLUGIN_CONTINUE;
}	

public dod_client_spawn(id) {
	if( (!get_cvar_num("mp_clan_match")) || (get_pcvar_num(g_pcvarJoin)) || (!isLive) )
		return PLUGIN_HANDLED
		
	// Kill user and echo to world & user
	dod_user_kill(id)
	send_message(id, "has died due to match being live", print_chat)
	client_print(id, print_center, "Match is live - must wait until end of round to spawn.")
	
	return PLUGIN_HANDLED
}

public check_class(id) {
	if( (!get_cvar_num("mp_clan_match")) || (isLive) || !is_user_alive(id))
		return PLUGIN_CONTINUE
	new arg[200]
	read_argv(0,arg,199)
	
	if(equali(arg,"cls_",4))
		set_task(0.1,"match_respawn",id)
		
	return PLUGIN_CONTINUE
}

// Blocks the white text from Day of Defeat's match system
// that does not match the actual setup of these matches
public timer_block( msgid, msgDest, msgEnt ) {
	if( msgid == gmsgTextMsg )
	{
		new msgArg[64]
		get_msg_arg_string(2, msgArg, 63)
		if( (!equali(msgArg, "#Clan_time_remaining")) && (!equali(msgArg, "#Clan_warmup_rules")) )
			return PLUGIN_CONTINUE
	}
	return PLUGIN_HANDLED
}

public hook_alive(id) {
	if(!get_cvar_num("mp_clan_match") || is_user_alive(id))
		return PLUGIN_CONTINUE
		
	new g_alliesalive, g_axisalive
	for (new i = 1; i <= 32; i++) { 
		if (!is_user_alive(i)) continue 
		if (get_user_team(i) == 1)
			g_alliesalive++
		else
			g_axisalive++
	}
	
	client_print(id, print_chat, "Allies Alive: %i - Axis Alive: %i", g_alliesalive, g_axisalive)
	
	return PLUGIN_CONTINUE
}

public hook_health(id) {
	if(!get_cvar_num("amx_textprox") || !is_user_alive(id))
		return PLUGIN_CONTINUE
		
	client_print(id, print_chat, "Health: %i%", get_user_health(id))
	return PLUGIN_HANDLED
}

public hook_rock( id ) {
	new players = get_playersnum();
	if( players >= ROCK_MIN && !g_rocked[id] )
	{
		g_rocked[id] = 1;
		check_rock( id, players );
	}
	return PLUGIN_CONTINUE;
}

public check_rock( id, players ) {
	new amt = 0;
	for( new i; i < sizeof g_rocked; i++ )
	{
		if( g_rocked[i] ) amt++;
	}
	// Formula: z/100 * y == x (x=amt, y=players, z=%)
	if( amt >= ( ROCK_RATIO * players ) )
	{
		//new players_needed = floatround(ROCK_RATIO * players);
		//new szMsg[64];
		//format( szMsg, 63, "Amt: %i, Players: %i, Need: %i", amt, players, players_needed );
		send_message( 0, "75% Vote Received - Realism Match Beginning Momentarily.", print_center );
		set_task( 5.0, "enable_match" );
		
		// Set timelimit in case there is no admin
		set_cvar_num("mp_timelimit", 90)
		set_cvar_num("sv_alltalk", 0)
		set_cvar_num("dod_ceasefire", 1)
		set_cvar_num("match_joiniflive", 0)
		
		send_message(0, "********ALL TALK: OFF********", print_chat)
		send_message(0, "*CEASE FIRE: ON*", print_chat)
	}
	else
	{	
		new votesneeded = floatround(ROCK_RATIO * players) - amt;
		new szMsg[128];
		format( szMsg, 127, " has voted for a realism scrimmage. %i more votes are needed. Type 'rockthescrim' to vote.", votesneeded );
		send_message( id, szMsg, print_chat );
	}
}

public client_connect( id ) g_rocked[id] = 0;
	

// Sets client's status to "alive" (instead of dead)
public set_status(param[2]) {
	message_begin(MSG_ALL,get_user_msgid("PStatus"),{0,0,0})
	write_byte(param[0])
	write_byte(0)
	message_end()
	
	return PLUGIN_CONTINUE
}

// Sets client's score-kills-deaths to 0-0-0 and updates the scoreboard
public set_score(param[2]) {

	// VICTIM

	// Set actual score/kills/deaths
	dod_set_user_score(param[0],0,1)
	dod_set_user_kills(param[0],0,1)
	dod_set_pl_deaths(param[0],0,1)

	// Display score/kills/deaths
	new vTeam = get_user_team(param[0])
	new vClass = dod_get_user_class(param[0])
	message_begin(MSG_ALL, get_user_msgid("ScoreInfo"))
	write_byte(param[0])
	write_byte(0)
	write_byte(0)
	write_byte(0)
	write_byte(vClass)
	write_byte(vTeam)
	write_byte(0)
	message_end()

	// KILLER

	// Set actual score/kills/deaths
	dod_set_user_score(param[1],0,1)
	dod_set_user_kills(param[1],0,1)
	dod_set_pl_deaths(param[1],0,1)

	// Display score/kills/deaths
	new kTeam = get_user_team(param[1])
	new kClass = dod_get_user_class(param[1])
	message_begin(MSG_ALL, get_user_msgid("ScoreInfo"))
	write_byte(param[1])
	write_byte(0)
	write_byte(0)
	write_byte(0)
	write_byte(kClass)
	write_byte(kTeam)
	write_byte(0)
	message_end()
	
	return PLUGIN_CONTINUE
}

// The most important function. Called on client death.
// This sets scores to 0 for killer and victim, and 
// will restart the round & play music if settings are right.
// This is the foundation of the plugin.
public client_death(killer,victim,wpnindex,hitplace,TK) {
	if(!get_cvar_num("mp_clan_match"))
		return PLUGIN_HANDLED
	new restartRound = 1 
	new team = get_user_team(victim) 
	
	if(!get_cvar_num("mp_deathmsg")) {
		// Blocking Messages
		new param[2]
		param[0] = victim
		param[1] = killer
		set_task(0.1,"set_status",victim+543,param,2)
		set_task(0.1,"set_score",victim+544,param,2)
	}
  
	for (new i = 1; i <= 32; i++) { 
		if (!is_user_alive(i)) continue 
		if (team == get_user_team(i)) { 
			restartRound = 0 
			break 
		} 
	} 
	if ( (restartRound) && (!get_pcvar_num(g_pcvarJoin)) ) { 
		if(team == ALLIES)
			axis_win()
		else
			allies_win()
	}
	return PLUGIN_HANDLED
}

// Called when clients type /respawn
public match_respawn(id) {
	if( (!get_cvar_num("mp_clan_match")) || (isLive) || !is_user_alive(id))
		return PLUGIN_CONTINUE
	strip_user_weapons(id)
	spawn(id)
	send_message(id, "has respawned", print_chat)
	return PLUGIN_HANDLED
}

// Called when clients type /switchteams
public match_switchteams(id) {
	if( (!get_cvar_num("mp_clan_match")) || (isLive) || !is_user_alive(id))
		return PLUGIN_CONTINUE
		
	new arg[2]
	read_argv(1,arg,1)
	new g_team = str_to_num(arg)
	
	// If client chose spectators
	if(g_team == 3) 
	{
		dod_set_user_team(id, 3, 1)
		return PLUGIN_HANDLED
	}
	
	// Otherwise it's a team
	new myTeam = get_user_team(id)
	if(myTeam == ALLIES)
	{
		if(g_team == 1) return PLUGIN_HANDLED
		dod_set_user_team(id, AXIS, 1)
		client_cmd(id, "changeclass")
	}
	else
	{
		if(g_team == 2) return PLUGIN_HANDLED
		dod_set_user_team(id, ALLIES, 1)
		client_cmd(id, "changeclass")
	}
	strip_user_weapons(id)
	spawn(id)
	send_message(id, "has switched teams", print_chat)
	return PLUGIN_HANDLED
}

// Called when client on allies types /alliesready
public ready_allies(id) {
	if(!get_cvar_num("mp_clan_match"))
		return PLUGIN_HANDLED
	new myTeam = get_user_team(id)
	if(myTeam != ALLIES)
		return PLUGIN_HANDLED
	if(readyAllies == 1) {
		readyAllies = 0
		send_message(id, "Allies team NOT READY", print_chat)
	} else {
		readyAllies = 1
		send_message(id, "Allies team READY", print_chat)
	}
	if( (readyAllies == 1) && (readyAxis == 1) ) go_live(id)
	return PLUGIN_HANDLED
}

// Called when client on axis types /axisready
public ready_axis(id) {
	if(!get_cvar_num("mp_clan_match"))
		return PLUGIN_HANDLED
	new myTeam = get_user_team(id)
	if(myTeam != AXIS)
		return PLUGIN_HANDLED
	if(readyAxis == 1) {
		readyAxis = 0
		send_message(id, "Axis team NOT READY", print_chat)
	} else {
		readyAxis = 1
		send_message(id, "Axis team READY", print_chat)
	}
	if( (readyAllies == 1) && (readyAxis == 1) ) go_live(id)
	return PLUGIN_HANDLED
}

// Stock command to send messages. But I'm scared to make it "stock"
// instead of "public" because it might not work. Go away.
public send_message(id, strMsg[], printmode) {
	new players[32],pNum,strName[32]
	if(id) get_user_name(id, strName, 31)
	get_players(players,pNum)
	for(new i=0;i<pNum;i++)
		client_print(players[i],printmode,"%s %s", strName, strMsg)
}

// Called from client death. This displays the happy text and victory music
public allies_win() {
	message_begin(MSG_ALL,get_user_msgid("HudText"),{0,0,0})
	write_string("#MAP_ALLIED_VICTORY2")
	write_byte(0)
	message_end()
	
	new players[32],pNum,iSound[32]
	get_players(players,pNum)
	for(new i=0;i<pNum;i++) {
		if(dod_get_map_info(MI_ALLIES_TEAM) == 0)
			iSound = "sound/ambience/uswin.wav"
		else
			iSound = "sound/ambience/britwin.wav"
		client_cmd(players[i],"spk %s", iSound)
	}
	
	set_task(8.0, "restart_round")
}

// Called from client death. This displays the happy text and victory music
public axis_win() {
	message_begin(MSG_ALL,get_user_msgid("HudText"),{0,0,0})
	write_string("#MAP_AXIS_VICTORY2")
	write_byte(0)
	message_end()
	
	new players[32],pNum,iSound[32]
	get_players(players,pNum)
	for(new i=0;i<pNum;i++) {
		iSound = "sound/ambience/germanwin.wav"
		client_cmd(players[i],"spk %s", iSound)
	}
	
	set_task(8.0, "restart_round")
}



// Sets server password.
public server_pass(id,pass[]) {
	set_cvar_string("sv_password", pass)
	if(!pass[0]) {
		send_message(id, "***SERVER OPEN TO PUBLIC***", print_chat)
		send_message(id, "***SERVER OPEN TO PUBLIC***", print_chat)
		send_message(id, "***SERVER OPEN TO PUBLIC***", print_chat)
	} else {
		client_print(id, print_chat, "(Private Text) Server password set to: %s", pass)
		client_print(id, print_chat, "(Private Text) Server password set to: %s", pass)
		client_print(id, print_chat, "(Private Text) Server password set to: %s", pass)
		send_message(id, "Server Password Set", print_chat)
	}
}

// Enables realism match mode and sets all settings
public enable_match() {
	set_cvar_num("dod_fadetoblack", 0)
	set_cvar_num("mp_timelimit", 0)
	set_cvar_num("mp_teamlimit", 0)
	set_cvar_num("mp_tkpenalty", 0)
	set_cvar_num("mp_clan_match", 1)
	if(!get_cvar_num("mp_clan_respawntime")) {
		set_cvar_num("mp_clan_respawntime", 99999999)
		set_cvar_num("match_joiniflive", 0)
	} else set_cvar_num("match_joiniflive", 1)
	set_cvar_num("mp_clan_scoring_delay", 99999999)
	set_cvar_num("mp_clan_scoring", 99999999)
	set_cvar_num("mp_clan_timer", 0)
	set_cvar_num("mp_clan_restartround", 1)
	// Disable amx sounds/messages
	set_cvar_num("amx_scrollmsg", 0)
	set_cvar_num("amx_freq_imessage", 0)
	set_cvar_num("amx_flood_time", 0)
	set_cvar_num("amx_time_display", 0)
	set_cvar_num("amx_time_voice", 0)
	isLive = 0
	readyAllies = 0
	readyAxis = 0
	
	new briefing_time = get_pcvar_num( g_cvarBriefingTime );
	if( briefing_time )
		set_task( float(briefing_time), "go_live" );
}

// Called when round restarts
public restart_round() {
	set_cvar_num("mp_allowspectators", 1)
	set_cvar_num("mp_clan_restartround", 1)
	isLive = 0
	readyAllies = 0
	readyAxis = 0
	
	new briefing_time = get_pcvar_num( g_cvarBriefingTime );
	if( briefing_time )
		set_task( float(briefing_time), "go_live" );
}

// Called when both teams call ready or "live" is pressed from menu
public go_live(id) {
	if(!get_cvar_num("mp_clan_match") || isLive)
		return PLUGIN_HANDLED
	set_cvar_num("mp_allowspectators", 0)
	if( get_cvar_num("sv_alltalk") )
	{
		set_cvar_num("sv_alltalk", 0)
		send_message(id, "********ALL TALK: OFF********", print_chat)
	}
	if( get_cvar_num("dod_ceasefire") )
	{
		set_cvar_num("dod_ceasefire", 0);
		send_message(id, "*CEASE FIRE: OFF*", print_chat);
	}
	
	new players[32],pNum,iTeam,iSound[32]
	get_players(players,pNum)
	for(new i=0;i<pNum;i++) {
		iTeam = get_user_team(players[i])
		if( (iTeam == ALLIES) && (dod_get_map_info(MI_ALLIES_TEAM) == 0) )
			iSound = "sound/player/usprepare.wav"
		else if( (iTeam == ALLIES) && (dod_get_map_info(MI_ALLIES_TEAM) == 1) )
			iSound = "sound/player/britprepare.wav"
		else
			iSound = "sound/player/gerprepare.wav"
		client_cmd(players[i],"spk %s", iSound)
		client_print(players[i],print_center,"LIVE LIVE LIVE LIVE LIVE LIVE")
	}
	isLive = 1
	readyAllies = 0
	readyAxis = 0
	return PLUGIN_HANDLED
}

// Disables the realism match mode. If respawning was off, you will have to restart the map
public disable_match(id) {
	new g_message[64] = "Match Mode Disabled"
	new oldSpawntime = get_cvar_num("mp_clan_respawntime")
	if(oldSpawntime == 99999999)
		g_message = "Match Mode Disabled (Must reload map to enable respawning)"
	set_cvar_num("mp_clan_respawntime", 0)
	set_cvar_num("mp_clan_match", 0)
	server_cmd("exec addons/amxmodx/configs/amxx.cfg")
	send_message(id, g_message, print_chat)
	send_message(id, g_message, print_chat)
	send_message(id, g_message, print_chat)
	isLive = 0
	readyAllies = 0
	readyAxis = 0
}

public enable_alltalk(id,level,cid) {
	if(!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED
	set_cvar_num("sv_alltalk", 1)
	send_message(id, "********ALL TALK: ON********", print_chat)
	return PLUGIN_HANDLED
}

public disable_alltalk(id,level,cid) {
	if(!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED
	set_cvar_num("sv_alltalk", 0)
	send_message(id, "********ALL TALK: OFF********", print_chat)
	return PLUGIN_HANDLED
}

// Toggles for menu
public server_pass_tog(id) {
	if(get_cvar_num("sv_password")) {
		server_pass(id, "")
	}
	else {
		server_pass(id, g_server_pass)
	}
}

public death_msg_tog(id) {
	if(get_cvar_num("mp_deathmsg")) {
		set_cvar_num("mp_deathmsg", 0)
		send_message(id, "*Death Messages Disabled*", print_chat)
	}
	else {
		set_cvar_num("mp_deathmsg", 1)
		send_message(id, "*Death Messages Enabled*", print_chat)
	}
}

public voice_prox_tog(id) {
	if(get_cvar_num("amx_voiceprox") && get_cvar_num("amx_textprox")) {
		set_cvar_num("amx_textprox", 0)
		send_message(id, "*Voice Proximity ON - Text Proximity OFF*", print_chat)
	}
	else if(!get_cvar_num("amx_voiceprox") && !get_cvar_num("amx_textprox")) {
		set_cvar_num("amx_voiceprox", 1)
		set_cvar_num("amx_textprox", 1)
		send_message(id, "*Voice Proximity ON - Text Proximity ON*", print_chat)
	}
	else {
		set_cvar_num("amx_voiceprox", 0)
		set_cvar_num("amx_textprox", 0)
		send_message(id, "*Voice Proximity OFF - Text Proximity OFF*", print_chat)
	}
}

public all_talk_tog(id) {
	if(get_cvar_num("sv_alltalk")) {
		set_cvar_num("sv_alltalk", 0)
		send_message(id, "********ALL TALK: OFF********", print_chat)
	}
	else {
		set_cvar_num("sv_alltalk", 1)
		send_message(id, "********ALL TALK: ON********", print_chat)
	}
}

public cease_fire_tog(id) {
	if(get_cvar_num("dod_ceasefire")) {
		set_cvar_num("dod_ceasefire", 0)
		send_message(id, "*CEASE FIRE: OFF*", print_chat)
	}
	else {
		set_cvar_num("dod_ceasefire", 1)
		send_message(id, "*CEASE FIRE: ON*", print_chat)
	}
}

public stamina_hp_tog(id) {
	if(get_cvar_num("dod_staminahp")) {
		set_cvar_num("dod_staminahp", 0)
		send_message(id, "*STAMINA-HP: OFF*", print_chat)
	}
	else {
		set_cvar_num("dod_staminahp", 1)
		send_message(id, "*STAMINA-HP: ON*", print_chat)
	}
}

public ironsights_tog(id) {
	if(get_cvar_num("dod_ironsights")) {
		set_cvar_num("dod_ironsights", 0)
	}
	else {
		set_cvar_num("dod_ironsights", 1)
		send_message(id, "Ironsights Enabled (Must Reload Map to Take Effect)", print_chat)
	}
}

public reinforcements_tog(id) {
	new newvalue, g_respawntime = get_cvar_num("mp_clan_respawntime")

	switch ( g_respawntime )
	{
		case  0:  newvalue = 30;
		case 30:  newvalue = 60;
		case 60:  newvalue = 90;
		case 90:  newvalue = 120;
		case 120: newvalue = 150;
		case 150: newvalue = 180;
		case 180: newvalue = 210;
		case 210: newvalue = 240;
		case 240: newvalue = 270;
		case 270: newvalue = 300;
		case 300: newvalue = 360;
		case 360: newvalue = 420;
		case 420: newvalue = 480;
		case 480: newvalue = 540;
		case 540: newvalue = 600;
		case 600: newvalue = 900;
		case 900: newvalue = 1200;
		default: newvalue = 0;
	}
	set_cvar_num("mp_clan_respawntime", newvalue );
}

public briefing_tog(id) {
	new newvalue, g_briefingtime = get_pcvar_num(g_cvarBriefingTime)

	switch ( g_briefingtime )
	{
		case  0:  newvalue = 30;
		case 30:  newvalue = 60;
		case 60:  newvalue = 90;
		case 90:  newvalue = 120;
		case 120: newvalue = 150;
		case 150: newvalue = 180;
		case 180: newvalue = 210;
		case 210: newvalue = 240;
		case 240: newvalue = 270;
		case 270: newvalue = 300;
		case 300: newvalue = 360;
		case 360: newvalue = 420;
		case 420: newvalue = 480;
		case 480: newvalue = 540;
		case 540: newvalue = 600;
		case 600: newvalue = 900;
		case 900: newvalue = 1200;
		default: newvalue = 0;
	}
	set_pcvar_num( g_cvarBriefingTime, newvalue );
}

public swap_teams(id) {
	for( new i; i <= 32; i++ )
	{
		if( is_user_connected(i) )
		{
			switch( get_user_team(i) )
			{
				case ALLIES: dod_set_user_team( i, AXIS, 1 );
				case AXIS: dod_set_user_team( i, ALLIES, 1 );
			}
			strip_user_weapons( i );
			spawn( i );
		}
	}
	send_message( id, "has swapped the teams", print_chat );
	return PLUGIN_HANDLED;
}
