diff --git a/Source/Client/Defs.h b/Source/Client/Defs.h index fe7e00c4..838e92d8 100644 --- a/Source/Client/Defs.h +++ b/Source/Client/Defs.h @@ -24,6 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define DRAWFLAG_MODULATE 2 #define DRAWFLAG_2XMODULATE 3 +// Undocumented printcall types +#define PRINT_LOW 0 +#define PRINT_MEDIUM 1 +#define PRINT_HIGH 2 +#define PRINT_CHAT 3 + // Clientside cvars var vector autocvar_con_color = '255 128 0'; // autocvar of "con_color" var vector autocvar_vgui_color = '255 128 0'; // autocvar of "vgui_color" diff --git a/Source/Client/Draw.c b/Source/Client/Draw.c index d3a6960d..b5571129 100644 --- a/Source/Client/Draw.c +++ b/Source/Client/Draw.c @@ -18,11 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define PRINT_LOW 0 -#define PRINT_MEDIUM 1 -#define PRINT_HIGH 2 -#define PRINT_CHAT 3 - #define CHAT_LINES 5 #define CHAT_TIME 4 int iLineScroll; diff --git a/Source/Client/Event.c b/Source/Client/Event.c index b567b99e..880829ca 100644 --- a/Source/Client/Event.c +++ b/Source/Client/Event.c @@ -33,6 +33,63 @@ void CSQC_ConsoleCommand_Init( void ) { registercommand( "+showscores" ); registercommand( "-showscores" ); registercommand( "nightvision" ); + + registercommand( "glock" ); + registercommand( "usp" ); + registercommand( "p228" ); + registercommand( "deagle" ); + registercommand( "fn57" ); + registercommand( "elites" ); + registercommand( "m3" ); + registercommand( "xm1014" ); + registercommand( "tmp" ); + registercommand( "mac10" ); + registercommand( "mp5" ); + registercommand( "ump45" ); + registercommand( "p90" ); + registercommand( "ak47" ); + registercommand( "m4a1" ); + registercommand( "sg552" ); + registercommand( "aug" ); + registercommand( "scout" ); + registercommand( "sg550" ); + registercommand( "awp" ); + registercommand( "g3sg1" ); + registercommand( "m249" ); + + registercommand( "primammo" ); + registercommand( "secammo" ); + + registercommand( "vest" ); + registercommand( "vesthelm" ); + registercommand( "flash" ); + registercommand( "hegren" ); + registercommand( "vsgren" ); + registercommand( "defuser" ); + registercommand( "nvg" ); + + registercommand( "coverme" ); + registercommand( "takepoint" ); + registercommand( "regroup" ); + registercommand( "followme" ); + registercommand( "takingfire" ); + + registercommand( "go" ); + registercommand( "fallback" ); + registercommand( "sticktog" ); + registercommand( "getinpos" ); + registercommand( "stormfront" ); + registercommand( "report" ); + + registercommand( "roger" ); + registercommand( "enemyspot" ); + registercommand( "needbackup" ); + registercommand( "sectorclear" ); + registercommand( "inposition" ); + registercommand( "reportingin" ); + registercommand( "getout" ); + registercommand( "negative" ); + registercommand( "enemydown" ); } /* @@ -75,6 +132,179 @@ float CSQC_ConsoleCommand( string sCMD ) { Nightvision_Toggle(); return TRUE; break; + case "glock": + return TRUE; + break; + case "usp": + return TRUE; + break; + case "p228": + return TRUE; + break; + case "deagle": + return TRUE; + break; + case "fn57": + return TRUE; + break; + case "elites": + return TRUE; + break; + case "m3": + return TRUE; + break; + case "xm1014": + return TRUE; + break; + case "tmp": + return TRUE; + break; + case "mac10": + return TRUE; + break; + case "mp5": + return TRUE; + break; + case "ump45": + return TRUE; + break; + case "p90": + return TRUE; + break; + case "ak47": + return TRUE; + break; + case "m4a1": + return TRUE; + break; + case "sg552": + return TRUE; + break; + case "aug": + return TRUE; + break; + case "scout": + return TRUE; + break; + case "sg550": + return TRUE; + break; + case "awp": + return TRUE; + break; + case "g3sg1": + return TRUE; + break; + case "m249": + return TRUE; + break; + case "primammo": + return TRUE; + break; + case "secammo": + return TRUE; + break; + case "vest": + return TRUE; + break; + case "vesthelm": + return TRUE; + break; + case "flash": + return TRUE; + break; + case "hegren": + return TRUE; + break; + case "vsgren": + return TRUE; + break; + case "defuser": + return TRUE; + break; + case "nvg": + return TRUE; + break; + case "coverme": + sendevent( "RadioMessage", "f", RADIO_CT_COVERME ); + return TRUE; + break; + case "takepoint": + sendevent( "RadioMessage", "f", RADIO_CT_POINT ); + return TRUE; + break; + case "regroup": + sendevent( "RadioMessage", "f", RADIO_REGROUP ); + return TRUE; + break; + case "followme": + sendevent( "RadioMessage", "f", RADIO_FOLLOWME ); + return TRUE; + break; + case "takingfire": + sendevent( "RadioMessage", "f", RADIO_FIREASSIS ); + return TRUE; + break; + case "go": + sendevent( "RadioMessage", "f", RADIO_GO ); + return TRUE; + break; + case "fallback": + sendevent( "RadioMessage", "f", RADIO_FALLBACK ); + return TRUE; + break; + case "sticktog": + sendevent( "RadioMessage", "f", RADIO_STICKTOG ); + return TRUE; + break; + case "getinpos": + sendevent( "RadioMessage", "f", RADIO_COM_GETINPOS ); + return TRUE; + break; + case "stormfront": + sendevent( "RadioMessage", "f", RADIO_STORMFRONT ); + return TRUE; + break; + case "report": + sendevent( "RadioMessage", "f", RADIO_COM_REPORTIN ); + return TRUE; + break; + case "roger": + sendevent( "RadioMessage", "f", RADIO_ROGER ); + return TRUE; + break; + case "enemyspot": + sendevent( "RadioMessage", "f", RADIO_CT_ENEMYS ); + return TRUE; + break; + case "needbackup": + sendevent( "RadioMessage", "f", RADIO_CT_BACKUP ); + return TRUE; + break; + case "sectorclear": + sendevent( "RadioMessage", "f", RADIO_CLEAR ); + return TRUE; + break; + case "inposition": + sendevent( "RadioMessage", "f", RADIO_CT_INPOS ); + return TRUE; + break; + case "reportingin": + sendevent( "RadioMessage", "f", RADIO_CT_REPORTINGIN ); + return TRUE; + break; + case "getout": + sendevent( "RadioMessage", "f", RADIO_GETOUT ); + return TRUE; + break; + case "negative": + sendevent( "RadioMessage", "f", RADIO_NEGATIVE ); + return TRUE; + break; + case "enemydown": + sendevent( "RadioMessage", "f", RADIO_ENEMYDOWN ); + return TRUE; + break; } return FALSE; } @@ -121,7 +351,9 @@ void CSQC_Parse_Event( void ) { fCameraTime = time + readfloat(); } else if ( fHeader == EV_RADIOMSG ) { - Radio_BroadcastMessage( readbyte() ); + Radio_PlayMessage( readbyte() ); + } else if ( fHeader == EV_RADIOMSG2 ) { + Radio_PlayPlayerMessage( readbyte(), readbyte() ); } else if ( fHeader == EV_ORBITUARY ) { HUD_AddOrbituaries( readbyte(), readbyte(), readbyte(), readbyte(), readbyte(), readbyte()); } else if ( fHeader == EV_IMPACT ) { diff --git a/Source/Globals.h b/Source/Globals.h index b80379f0..5a2b5074 100644 --- a/Source/Globals.h +++ b/Source/Globals.h @@ -216,6 +216,7 @@ enum { EV_MODELGIB, EV_CAMERATRIGGER, EV_RADIOMSG, + EV_RADIOMSG2, EV_ORBITUARY }; diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 355a2c2d..9f5dfb8c 100644 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -75,6 +75,7 @@ float fGameTime; .int iCurrentCaliber; .float fSlotMelee, fSlotPrimary, fSlotSecondary, fSlotGrenade; .float fAttackFinished; +.float fRadioFinished; .float fAccuracy; .float fFallVelocity; @@ -84,6 +85,7 @@ int iBombZones; int iRescueZones; int iBuyZones; int iVIPZones; +int iEscapeZones; int iBuyRestriction; // For info_map_parameters int iBombRadius; // For info_map_parameters diff --git a/Source/Server/FuncEscapeZone.c b/Source/Server/FuncEscapeZone.c index e4d911ec..6a7830dc 100644 --- a/Source/Server/FuncEscapeZone.c +++ b/Source/Server/FuncEscapeZone.c @@ -67,4 +67,6 @@ void func_escapezone( void ) { self.model = 0; self.touch = func_escapezone_touch; + + iEscapeZones++; } diff --git a/Source/Server/Timer.c b/Source/Server/Timer.c index 1d0ca374..8e234298 100644 --- a/Source/Server/Timer.c +++ b/Source/Server/Timer.c @@ -18,19 +18,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// Detects the state of the game that we are in and cycles between them. INACTIVE > FREEZE > INGAME > ACTIVE void Timer_Begin( float fTime, float fMode) { if ( fMode == GAME_FREEZE ) { - dprint( "[DEBUG] Game Freezetime\n" ); fGameState = GAME_FREEZE; } else if ( fMode == GAME_ACTIVE ) { - dprint( "[DEBUG] Game Active\n" ); fGameState = GAME_ACTIVE; } else if ( fMode == GAME_END ) { - dprint( "[DEBUG] Game Ended\n" ); fGameState = GAME_END; } else if ( fMode == GAME_COMMENCING ) { - dprint( "[DEBUG] Game Commencing\n" ); fGameState = GAME_COMMENCING; } @@ -58,15 +53,7 @@ void Timer_Update( void ) { Timer_Begin( 5, GAME_END); // Round is over, 5 seconds til a new round starts } else { Timer_Begin( autocvar_mp_roundtime * 60, GAME_ACTIVE ); // Unfreeze - - float fRand = floor( random( 1, 4 ) ); - if ( fRand == 1 ) { - Radio_BroadcastMessage( RADIO_MOVEOUT ); - } else if ( fRand == 2 ) { - Radio_BroadcastMessage( RADIO_LOCKNLOAD ); - } else { - Radio_BroadcastMessage( RADIO_LETSGO ); - } + Radio_StartMessage(); } } } diff --git a/Source/Shared/Radio.c b/Source/Shared/Radio.c index 44f0dfe1..5834cd18 100644 --- a/Source/Shared/Radio.c +++ b/Source/Shared/Radio.c @@ -18,12 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -enum { - RADIO_MODE_ALL = 0, - RADIO_MODE_T, - RADIO_MODE_CT -}; - enum { RADIO_BLOW, RADIO_BOMBDEF, @@ -117,22 +111,211 @@ string sRadioSamples[43] = { "radio/vip.wav" }; +string sRadioChat[43] = { + "Get out of there, it's gonna blow!", + "The bomb has been defused.", + "The bomb has been planted.", + "Circle around back!", + "Sector clear.", + "Okay team, follow my command!", + "Get in position and wait for my go!", + "Go, go, go!", + "Report in, team!", + "Affirmative.", + "Need backup!", + "Cover me!", + "Enemy spotted.", + "Fire in the hole!", + "I'm hit!", + "I'm in position.", + "I'll take the point.", + "Reporting in.", + "Counter-Terrorists win!", + "Enemy down!", + "Team, fall back!", + "Taking fire, need assistance!", + "Follow me!", + "Team, let's get out of here!", + "Okay, let's go.", + "I'm hit! Need assistance!", + "Hostage down.", + "Okay, let's go.", + "Lock 'n load.", + "Teammate down.", + "Meet at the rendezvous point.", + "Alright, let's move out.", + "Negative.", + "Hold this position!", + "Regroup, team!", + "A hostage has been rescued.", + "Roger that.", + "Round draw!", + "Stick together, team!", + "Storm the front!", + "You take the point!", + "Terrorists win!", + "Protect the VIP, team!" +}; + +/* +================= +Radio_InitSounds + +Who doesn't love precaching sounds +================= +*/ void Radio_InitSounds( void ) { for ( int i = 0; i < 43; i++ ) { precache_sound( sRadioSamples[ i ] ); } } + +/* +================= +Radio_PlayMessage + +Play a radio message that doesn't come from a player +================= +*/ +void Radio_PlayMessage( float fMessage ) { + sound( world, CHAN_VOICE, sRadioSamples[ fMessage ], 1, ATTN_NONE, 0, SOUNDFLAG_NOSPACIALISE ); + CSQC_Parse_Print( sprintf( "[RADIO]: %s\n", sRadioChat[ fMessage ] ), PRINT_CHAT ); +} + +/* +================= +Radio_PlayPlayerMessage + +This radio message does come from a player +================= +*/ +void Radio_PlayPlayerMessage( float fPlayerNum, float fMessage ) { + sound( world, CHAN_VOICE, sRadioSamples[ fMessage ], 1, ATTN_NONE, 0, SOUNDFLAG_NOSPACIALISE ); + CSQC_Parse_Print( sprintf( "[RADIO] %s: %s\n", getplayerkeyvalue( fPlayerNum, "name" ), sRadioChat[ fMessage ] ), PRINT_CHAT ); +} #endif -void Radio_BroadcastMessage( float fMessage ) { + #ifdef SSQC +/* +================= +Radio_BroadcastMessage + +A global radio message for all players +================= +*/ +void Radio_BroadcastMessage( float fMessage ) { WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET ); WriteByte( MSG_MULTICAST, EV_RADIOMSG ); WriteByte( MSG_MULTICAST, fMessage ); - msg_entity = self; multicast( '0 0 0', MSG_BROADCAST ); -#else - sound( world, CHAN_VOICE, sRadioSamples[ fMessage ], 1, ATTN_NONE, 0, SOUNDFLAG_NOSPACIALISE ); -#endif } + +/* +================= +Radio_TeamMessage + +A radio message targetted at members of a specific team +================= +*/ +void Radio_TeamMessage( float fMessage, float fTeam ) { + static void Radio_TeamMessage_Send( float fMessage, entity eEnt ) { + WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET ); + WriteByte( MSG_MULTICAST, EV_RADIOMSG ); + WriteByte( MSG_MULTICAST, fMessage ); + msg_entity = eEnt; + multicast( '0 0 0', MULTICAST_ONE ); + } + + for ( entity eFind = world; ( eFind = find( eFind, classname, "player" ) ); ) { + if ( eFind.team == fTeam ) { + Radio_TeamMessage_Send( fMessage, eFind ); + } else if ( eFind.team == TEAM_VIP && fTeam == TEAM_CT ) { + Radio_TeamMessage_Send( fMessage, eFind ); + } + } +} + +/* +================= +Radio_DefaultStart + +Pick a generic, random radio string for global start messages +================= +*/ +float Radio_DefaultStart( void ) { + float fRand = floor( random( 1, 4 ) ); + + if ( fRand == 1 ) { + return RADIO_MOVEOUT; + } else if ( fRand == 2 ) { + return RADIO_LOCKNLOAD; + } else { + return RADIO_LETSGO; + } +} + +/* +================= +Radio_StartMessage + +Decide which startmessage to play at the beginning of each round +================= +*/ +void Radio_StartMessage( void ) { + if ( iVIPZones > 0 ) { + Radio_TeamMessage( RADIO_VIP, TEAM_CT ); + Radio_TeamMessage( Radio_DefaultStart(), TEAM_T ); + } else if ( iEscapeZones > 0 ) { + Radio_TeamMessage( RADIO_GETOUT, TEAM_T ); + Radio_TeamMessage( Radio_DefaultStart(), TEAM_CT ); + } else { + Radio_BroadcastMessage( Radio_DefaultStart() ); + } +} + +/* +================= +CSEv_RadioMessage_f + +Triggered by clients, plays a message to members of the same team +================= +*/ +void CSEv_RadioMessage_f( float fMessage ) { + static void CSEv_RadioMessage_Send( float fMessage, entity eEnt ) { + WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET ); + WriteByte( MSG_MULTICAST, EV_RADIOMSG2 ); + WriteByte( MSG_MULTICAST, num_for_edict( eEnt ) - 1 ); + WriteByte( MSG_MULTICAST, fMessage ); + msg_entity = eEnt; + multicast( '0 0 0', MULTICAST_ONE ); + } + + // Don't allow spamming + if ( self.fRadioFinished > time ) { + return; + } + + // When dead, don't talk + if ( self.health <= 0 ) { + return; + } + + // Make sure that VIPs and CTs get eachother + float fTargetTeam = self.team; + if ( fTargetTeam == TEAM_VIP ) { + fTargetTeam = TEAM_CT; + } + + for ( entity eFind = world; ( eFind = find( eFind, classname, "player" ) ); ) { + if ( eFind.team == fTargetTeam ) { + CSEv_RadioMessage_Send( fMessage, eFind ); + } else if ( eFind.team == TEAM_VIP && fTargetTeam == TEAM_CT ) { + CSEv_RadioMessage_Send( fMessage, eFind ); + } + } + + self.fRadioFinished = time + 3.0f; +} +#endif diff --git a/opencs/csprogs.dat b/opencs/csprogs.dat index 780b1d68..4a5664eb 100644 Binary files a/opencs/csprogs.dat and b/opencs/csprogs.dat differ diff --git a/opencs/progs.dat b/opencs/progs.dat index c2a25ca3..38f5640c 100644 Binary files a/opencs/progs.dat and b/opencs/progs.dat differ