
//	VIETCONG 1
//	TDM script (with automatic global variables for synchronized objects)
//	modified by Ando
//	v3.1


//	NOTES:
// 1.0 modyfied for global vriables
// 1.2 - added variable for server (600) to detect server from object scripts
// 1.2 - new G-var system (object scripts counting g-vars to channel 601 )
// 1.3 - added game phase for object scripts resets
// 2.0 - successfully tested with L|DC-78
// 3.0 - added fade for restart
// 3.1 - show player in fifferent color (on/off option in script)
// 3.1 - show players count when "TAB" is pressed (on/off option in script)


#include <inc\sc_global.h>
#include <inc\sc_def.h>

#define SHOW_PLAYER_COLOR			1
#define SHOW_PLAYERS_COUNT			1


#define FADE_TIME			0.8
//________________________________
//global variable system for object synchro
#define GVAR_SERVER			600 	//	server  ( dont add SC_MP_Gvar_SetSynchro for that) 0 - not server, 1 - server
#define GVAR_COUNT			601 	//  count of object variables ( dont add SC_MP_Gvar_SetSynchro for that)
#define GVAR_USE_start		602 		//start		Global variable
//________________________________

#define GVAR_GPHASE 500		// important to use  game phase and channel 500 for synchronised objects 
//________________________________

#define RECOVER_TIME	5.0f		// time to recover player after killed
#define NORECOV_TIME	3.0f		// disable time of recoverplace after recovering someone there
#define REC_WPNAME		"DM%d"
#define REC_MAX			64

#define GVAR_SIDE0FRAGS				501
#define GVAR_SIDE1FRAGS				502
//___________________________

#define GPHASE_BEGIN 1
#define GPHASE_GAME 2
//#define GPHASE_DONE 3
//#define GPHASE_FAILED 4

#define GPHASE_BEFORE_RESTART		6
#define GPHASE_RESTARTING			7	


#define RESTART_TIMER		6	//time before actual restart


dword gPhase = 0;
float gPhase_timer = 3.0f;
//___________________________

// for extra tab info
ushort *player_s; 


dword gRecs = 0;
s_SC_MP_Recover gRec[REC_MAX];
float gRecTimer[REC_MAX];

float gNextRecover = 0.0f;
int gSideFrags[2] = {0,0};
int gCLN_SideFrags[2];

dword gEndRule;
dword gEndValue;
float gTime;
dword gPlayersConnected = 0;

BOOL    fade_off = TRUE;
float	client_fade_timer;


BOOL SRV_CheckEndRule(float time){

	switch(gEndRule){
		case SC_MP_ENDRULE_TIME:
			if (gPlayersConnected>0) gTime += time;
			SC_MP_EndRule_SetTimeLeft(gTime,gPlayersConnected>0);
			if (gTime>gEndValue){
				SC_MP_LoadNextMap();
				return TRUE;
			}
			break;
		case SC_MP_ENDRULE_FRAGS:
			if (((gSideFrags[0]>0)&&(gSideFrags[0]>=gEndValue))
				||((gSideFrags[1]>1)&&(gSideFrags[1]>=gEndValue))){
				SC_MP_LoadNextMap();
				return TRUE;
			}
			break;
		default:
			SC_message("EndRule unsopported: %d",gEndRule);
			break;
	}// switch(gEndRule)
	return FALSE;
}// void SRV_CheckEndRule(float time)

void UpdateSideFrags(void){
	SC_sgi(GVAR_SIDE0FRAGS,gSideFrags[0]);
	SC_sgi(GVAR_SIDE1FRAGS,gSideFrags[1]);
}


int ScriptMain(s_SC_NET_info *info){
	char txt[128],*itxt;
	ushort wtxt[128],wtxt2[64],*witxt;
	dword i,j,sideA,sideB;
	s_SC_MP_Recover *precov;
	s_SC_MP_hud hudinfo;
	s_SC_P_getinfo plinfo;
	s_SC_HUD_MP_icon icon[2];
	s_SC_MP_EnumPlayers enum_pl[64];
	s_SC_MP_SRV_settings SRVset;
	switch(info->message){
		case SC_NET_MES_SERVER_TICK:	
			//________________________________________________________________
			switch(gPhase){
			case GPHASE_BEGIN:
			
				gPhase_timer -= info->elapsed_time;
				if (gPhase_timer <= 0.0f){
					gPhase = GPHASE_GAME;
					SC_sgi(GVAR_GPHASE,gPhase);//(1 = begin) For sync. objects.  server restart_________________________________________
				}
				break;// GPHASE_BEGIN
			case GPHASE_GAME:

				break;
			case GPHASE_BEFORE_RESTART:
				gPhase_timer -= info->elapsed_time;
				if (gPhase_timer<0.0f){	//wait before restart
					gPhase = GPHASE_RESTARTING;
					SC_sgi(GVAR_GPHASE,gPhase);//(1 = begin) For sync. objects.  server restart
				}
				break;
			case GPHASE_RESTARTING:
				gTime = 0;
				gPhase=GPHASE_BEGIN;
				gPhase_timer = 3.0f;
				SC_sgi(GVAR_GPHASE,gPhase);//(1 = begin) For sync. objects.  server restart
				CLEAR(gSideFrags);
				UpdateSideFrags();
				SC_MP_SRV_ClearPlsStats();
				SC_MP_SRV_InitGameAfterInactive();
				SC_MP_RecoverAllNoAiPlayers();		
				break;

			}
			//________________________________________________________________
	
			if (SRV_CheckEndRule(info->elapsed_time)) break;
			for (i=0;i<gRecs;i++)
				gRecTimer[i] -= info->elapsed_time;
			j = 64;
			if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL)){
				if ((j==0)&&((gSideFrags[0]+gSideFrags[1])!=0)){
					gSideFrags[0] = 0;
					gSideFrags[1] = 0;
					UpdateSideFrags();
				}// if ((side[0]+side[1])==0)
			}// if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL))
			gPlayersConnected = j;
			break;
		case SC_NET_MES_CLIENT_TICK:
			switch(SC_ggi(GVAR_GPHASE)){
			case GPHASE_BEGIN:
				if (fade_off == FALSE){
					SC_FadeTo(FALSE, FADE_TIME);
					fade_off=TRUE;
				}
				break;
			case GPHASE_BEFORE_RESTART:
				if (fade_off == TRUE){
					client_fade_timer -= info->elapsed_time;
					if (client_fade_timer < FADE_TIME){	
						SC_FadeTo(TRUE, FADE_TIME);
						fade_off=FALSE;
						client_fade_timer=RESTART_TIMER;
					}
				}
				break;
			case GPHASE_RESTARTING:
				break;
			}// switch(gPhase)
			//_____________________________

			gCLN_SideFrags[0] = SC_ggi(GVAR_SIDE0FRAGS);
			gCLN_SideFrags[1] = SC_ggi(GVAR_SIDE1FRAGS);
			SC_MP_SetSideStats(0,gCLN_SideFrags[0],0);
			SC_MP_SetSideStats(1,gCLN_SideFrags[1],0);
			for (i=0;i<2;i++){
				icon[i].type = SC_HUD_MP_ICON_TYPE_NUMBER;
				icon[i].icon_id = 3*i;
				icon[i].value = gCLN_SideFrags[i];
				icon[i].color = 0xffffffff;
			}
			SC_MP_SetIconHUD(icon,2);
			break;// SC_NET_MES_CLIENT_TICK
		case SC_NET_MES_LEVELPREINIT:
			client_fade_timer=RESTART_TIMER;

			SC_sgi(GVAR_MP_MISSIONTYPE,GVAR_MP_MISSIONTYPE_TDM);
			gEndRule = info->param1;
			gEndValue = info->param2;
			gTime = 0.0f;

			SC_MP_EnableBotsFromScene(FALSE);
			break;// SC_NET_MES_LEVELPREINIT
		case SC_NET_MES_LEVELINIT:
			//_____________________________________automatic custom global variables_________________
			for (i=GVAR_USE_start;i<GVAR_USE_start+SC_ggi(GVAR_COUNT)+1;i++){	//custom global variables
				SC_MP_Gvar_SetSynchro(i); 
			}
			//_______________________________________________________________________________________
			
			SC_MP_SRV_SetForceSide(0xffffffff);
			SC_MP_SetChooseValidSides(3);
			SC_MP_SRV_SetClassLimitsForDM();
			CLEAR(hudinfo);
			hudinfo.title = 1051;
			hudinfo.sort_by[0] = SC_HUD_MP_SORTBY_FRAGS;
			hudinfo.sort_by[1] = SC_HUD_MP_SORTBY_KILLS;
			hudinfo.sort_by[2] = SC_HUD_MP_SORTBY_DEATHS | SC_HUD_MP_SORT_DOWNUP;
			hudinfo.sort_by[3] = SC_HUD_MP_SORTBY_PINGS | SC_HUD_MP_SORT_DOWNUP;
			hudinfo.pl_mask = SC_HUD_MP_PL_MASK_FRAGS | SC_HUD_MP_PL_MASK_KILLS | SC_HUD_MP_PL_MASK_DEATHS;
			hudinfo.use_sides = TRUE;
			hudinfo.side_name[0] = 1010;
			hudinfo.side_color[0] = 0x440000ff;
			hudinfo.side_name[1] = 1011;
			hudinfo.side_color[1] = 0x44ff0000;
			hudinfo.side_mask = SC_HUD_MP_SIDE_MASK_FRAGS;
			SC_MP_HUD_SetTabInfo(&hudinfo);
			SC_MP_AllowStPwD(TRUE);
			SC_MP_AllowFriendlyFireOFF(TRUE);
			SC_MP_SetItemsNoDisappear(FALSE);
			if (info->param2){
				if (info->param1){
					// it's server		
					//_______________________________________________________________________________________
					SC_sgi(GVAR_SERVER,1); 
					SC_MP_Gvar_SetSynchro(GVAR_GPHASE);
					SC_sgi(GVAR_GPHASE,gPhase);
					//_______________________________________________________________________________________
					

					SC_MP_GetSRVsettings(&SRVset);
					SC_MP_SRV_InitWeaponsRecovery((float)SRVset.dm_weap_resp_time);
					SC_MP_Gvar_SetSynchro(GVAR_SIDE0FRAGS);
					SC_MP_Gvar_SetSynchro(GVAR_SIDE1FRAGS);
					UpdateSideFrags();
					gRecs = 0;
					for (i=0;i<REC_MAX;i++){		
						sprintf(txt,REC_WPNAME,i);			
						if (SC_NET_FillRecover(&gRec[gRecs],txt)) gRecs++;
					}					
#if _GE_VERSION_ >= 133
					i = REC_MAX - gRecs;
					SC_MP_GetRecovers(SC_MP_RESPAWN_DM,&gRec[gRecs],&i);
					gRecs += i;
#endif
					SC_Log(3,"TDM respawns: %d",gRecs);
					if (gRecs==0) SC_message("no recover place defined!");
					CLEAR(gRecTimer);					
				}// if (info->param1)
			}//if (info->param2)
			break;// SC_NET_MES_LEVELINIT
		case SC_NET_MES_RENDERHUD:
// EXTRA TAB INFO TEST
			if(SC_KeyPressed(0x0F)){//TAB pressed
				
				if(SHOW_PLAYER_COLOR){
					SC_MP_HUD_SelectPl(SC_PC_Get(),0x1100ffff);
				}

				if (SHOW_PLAYERS_COUNT){
					SC_MP_EnumPlayers(enum_pl,&j,SC_P_SIDE_US);
					if (j==1) player_s = SC_Wtxt(350); else player_s = SC_Wtxt(7001);
					swprintf(wtxt,SC_AnsiToUni("%d %s  %s", wtxt2),j,SC_Wtxt(102),player_s);
					SC_Fnt_WriteW(100,25,wtxt,1,0xffffffff);

					SC_MP_EnumPlayers(enum_pl,&j,SC_P_SIDE_VC);
					if (j==1) player_s = SC_Wtxt(350); else player_s = SC_Wtxt(7001);
					swprintf(wtxt,SC_AnsiToUni("%d %s  %s", wtxt2),j,SC_Wtxt(103),player_s);
					SC_Fnt_WriteW(100,65,wtxt,1,0xffffffff);
				}
			}
// end of extra tab info
			break;
		case SC_NET_MES_SERVER_RECOVER_TIME:
			if (info->param2){
					info->fval1 = 0.1f;
			}
			else{
				// killed
				info->fval1 = RECOVER_TIME;
			}
			break;
		case SC_NET_MES_SERVER_RECOVER_PLACE:
			precov = (s_SC_MP_Recover*)info->param2;

			i = SC_MP_SRV_GetBestDMrecov(gRec,gRecs,gRecTimer,NORECOV_TIME);
			
			gRecTimer[i] = NORECOV_TIME;
			*precov = gRec[i];
						
			break;
			

		case SC_NET_MES_SERVER_KILL:
			SC_P_GetInfo(info->param1,&plinfo);		
			sideA = plinfo.side;
			if (info->param2){
				SC_P_GetInfo(info->param2,&plinfo);		
				sideB = plinfo.side;
			}
			else sideB = 0xffffffff;
			if (sideA==sideB){
				gSideFrags[sideB]--;
			}
			else{
				if (sideB!=0xffffffff) gSideFrags[sideB]++;					
			}
			UpdateSideFrags();
			break;// SC_NET_MES_SERVER_KILL
		case SC_NET_MES_RESTARTMAP:
			gPhase_timer = RESTART_TIMER;
			gPhase = GPHASE_BEFORE_RESTART;	
			SC_sgi(GVAR_GPHASE,gPhase);//(1 = begin) For sync. objects.  server restart	
			break;// SC_NET_MES_RESTARTMAP
		case SC_NET_MES_RULESCHANGED:			
			gEndRule = info->param1;
			gEndValue = info->param2;
			gTime = 0.0f;
			break;		
	}// switch(info->message)
	return 1;
}// int ScriptMain(void)

