
//	VIETCONG 1
//	DM 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 GPHASE_BEGIN				1
#define GPHASE_GAME					2
#define GPHASE_BEFORE_RESTART		6
#define GPHASE_RESTARTING			7	


#define RESTART_TIMER				6	//time before actual restart


dword gPhase = 1;
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];



dword gEndRule;
dword gEndValue;
float gTime;
dword gPlayersConnected = 0;



BOOL    fade_off = TRUE;
float	client_fade_timer;
float	fade_off_timer;


BOOL SRV_CheckEndRule(float time){
	int frags;
	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 (SC_MP_GetMaxFragsPl(&frags)){
				if (frags>=gEndValue){
					SC_MP_LoadNextMap();
					return TRUE;
				}
			}
			break;
		default:
			SC_message("EndRule unsopported: %d",gEndRule);
			break;
	}// switch(gEndRule)
	return FALSE;
}// void SRV_CheckEndRule(float time)

int ScriptMain(s_SC_NET_info *info){
	char txt[128],*itxt;
	ushort wtxt[128],wtxt2[64],*witxt;
	dword i,j;
	s_SC_MP_Recover *precov;
	s_SC_MP_hud hudinfo;
	s_SC_MP_EnumPlayers enum_pl[64];
	s_SC_MP_SRV_settings SRVset;
	switch(info->message){
		case SC_NET_MES_SERVER_TICK:	
			//________________________________________________________________
			gPhase_timer -= info->elapsed_time;
			switch(gPhase){
			case GPHASE_BEGIN:
				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:
				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
				SC_MP_SRV_ClearPlsStats();
				SC_MP_SRV_InitGameAfterInactive();
				SC_MP_RecoverAllNoAiPlayers();		
				break;
			}
			//________________________________________________________________
			gPlayersConnected = 64;
			SC_MP_EnumPlayers(enum_pl,&gPlayersConnected,SC_MP_ENUMPLAYER_SIDE_ALL);			
			if (SRV_CheckEndRule(info->elapsed_time)) break;
			for (i=0;i<gRecs;i++)
				gRecTimer[i] -= info->elapsed_time;
			break;
		case SC_NET_MES_CLIENT_TICK:
			switch(SC_ggi(GVAR_GPHASE)){
			case GPHASE_BEGIN:
				if (!fade_off){
					fade_off_timer += info->elapsed_time;
					if (fade_off_timer >  0.2f){// looks better so because spawn is with short delay
						SC_FadeTo(FALSE, FADE_TIME);
						fade_off=TRUE;
					}
				}
				break;
			case GPHASE_BEFORE_RESTART:
				if (fade_off){
					client_fade_timer -= info->elapsed_time;
					if (client_fade_timer < (FADE_TIME + 0.1f)){	
						SC_FadeTo(TRUE, FADE_TIME);
						fade_off=FALSE;
						client_fade_timer=RESTART_TIMER;
						fade_off_timer=0;
					}
				}
				break;
			case GPHASE_RESTARTING:
				break;
			}// switch(gPhase)
			//_____________________________
			break;// SC_NET_MES_CLIENT_TICK
		case SC_NET_MES_LEVELPREINIT:
			client_fade_timer=RESTART_TIMER;

			SC_sgi(GVAR_MP_MISSIONTYPE,GVAR_MP_MISSIONTYPE_DM);
			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_HUD_DisableRadar(TRUE);			
			SC_MP_SRV_SetClassLimitsForDM();	
			CLEAR(hudinfo);
			hudinfo.title = 1050;
			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 = 0;
			SC_MP_HUD_SetTabInfo(&hudinfo);
			SC_MP_AllowStPwD(FALSE);
			SC_MP_AllowFriendlyFireOFF(FALSE);
			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);
					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,"DM 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
			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_MP_ENUMPLAYER_SIDE_ALL);
					if (j==1) player_s = SC_Wtxt(350); else player_s = SC_Wtxt(7001);
					swprintf(wtxt,SC_AnsiToUni("%d  %s", wtxt2),j,player_s);
					SC_Fnt_WriteW(100,25,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_RESTARTMAP:
			//___________________________________________________________
			gPhase_timer = RESTART_TIMER;
			gPhase = GPHASE_BEFORE_RESTART;	
			SC_sgi(GVAR_GPHASE,gPhase);

			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)
