2004-08-23 00:15:46 +00:00
/*
Teamplay . c
Contains various console stuff for improving the performance of a team . . .
Cheats I hear you say ? . . .
Personally , I ' d rather call it a hack job .
Most of it is dependant upon specific mod types - TF .
As far as split screen goes , this is all relative to player 0. We don ' t provide more than one say command .
*/
# include "quakedef.h"
# ifndef ZQUAKETEAMPLAY
cvar_t tp_name_armortype_ga = { " tp_name_armortype_ga " , " g " } ;
cvar_t tp_name_armortype_ya = { " tp_name_armortype_ya " , " y " } ;
cvar_t tp_name_armortype_ra = { " tp_name_armortype_ra " , " r " } ;
cvar_t tp_name_none = { " tp_name_none " , " " } ;
# define translatetext(i) #i
///////////////////////////////////////////////////////////////////
//Macros.
char * TP_ClassForTFSkin ( void )
{
char * skin ;
skin = Info_ValueForKey ( cls . userinfo , " skin " ) ;
if ( ! * skin )
return " Classless " ;
if ( skin [ 0 ] ! = ' t ' & & skin [ 1 ] ! = ' f ' & & skin [ 2 ] ! = ' _ ' )
return skin ;
if ( ! strcmp ( skin , " tf_sold " ) )
return translatetext ( TLTP_CLASS_SOLIDER ) ;
if ( ! strcmp ( skin , " tf_demo " ) )
return translatetext ( TLTP_CLASS_DEMOGUY ) ;
if ( ! strcmp ( skin , " tf_eng " ) )
return translatetext ( TLTP_CLASS_ENGINEER ) ;
if ( ! strcmp ( skin , " tf_snipe " ) )
return translatetext ( TLTP_CLASS_SNIPER ) ;
if ( ! strcmp ( skin , " tf_hwguy " ) )
return translatetext ( TLTP_CLASS_HWGUY ) ;
if ( ! strcmp ( skin , " tf_medic " ) )
return translatetext ( TLTP_CLASS_MEDIC ) ;
if ( ! strcmp ( skin , " tf_pyro " ) )
return translatetext ( TLTP_CLASS_PYRO ) ;
if ( ! strcmp ( skin , " tf_scout " ) )
return translatetext ( TLTP_CLASS_SCOUT ) ;
if ( ! strcmp ( skin , " tf_spy " ) )
return translatetext ( TLTP_CLASS_SPY ) ;
return skin ;
}
void * TP_ArmourType ( void )
{
if ( cl . stats [ 0 ] [ STAT_ITEMS ] & IT_ARMOR1 )
return tp_name_armortype_ga . string ;
else if ( cl . stats [ 0 ] [ STAT_ITEMS ] & IT_ARMOR2 )
return tp_name_armortype_ya . string ;
else if ( cl . stats [ 0 ] [ STAT_ITEMS ] & IT_ARMOR3 )
return tp_name_armortype_ra . string ;
else
return tp_name_none . string ;
}
///////////////////////////////////////////////////////////////////
//Locs
typedef struct location_s {
vec3_t pos ;
struct location_s * next ;
char name [ 0 ] ;
} location_t ;
location_t * location ;
char LocationLevel [ 64 ] ;
void CL_LoadLocs ( void )
{
location_t * newloc ;
vec3_t pos ;
char * file ;
char * end ;
char name [ MAX_QPATH ] ;
// if (!strcmp(LocationLevel, cl.model_name[1]))
// return;
while ( location )
{
newloc = location - > next ;
Z_Free ( location ) ;
location = newloc ;
}
strcpy ( LocationLevel , cl . model_name [ 1 ] ) ;
COM_StripExtension ( COM_SkipPath ( LocationLevel ) , name ) ;
file = COM_LoadTempFile ( va ( " locs/%s.loc " , name ) ) ;
if ( ! file )
return ;
for ( ; ; )
{
file = COM_Parse ( file ) ;
pos [ 0 ] = atof ( com_token ) / 8 ;
file = COM_Parse ( file ) ;
pos [ 1 ] = atof ( com_token ) / 8 ;
file = COM_Parse ( file ) ;
pos [ 2 ] = atof ( com_token ) / 8 ;
while ( * file & & * file < = ' \0 ' )
file + + ;
if ( ! file )
return ;
end = strchr ( file , ' \n ' ) ;
if ( ! end )
{
end = file + strlen ( file ) ;
}
newloc = Z_Malloc ( sizeof ( location_t ) + end - file + 1 ) ;
newloc - > next = location ;
location = newloc ;
Q_strncpyz ( newloc - > name , file , end - file ) ;
VectorCopy ( pos , newloc - > pos ) ;
if ( ! * end )
return ;
file = end + 1 ;
}
}
char * CL_LocationName ( float * pos )
{
location_t * loc ;
vec3_t dir ;
char * best ;
float dist , bestdist ;
CL_LoadLocs ( ) ;
if ( ! location )
return " somewhere " ;
//get the initial one
best = location - > name ;
VectorSubtract ( location - > pos , pos , dir ) ;
bestdist = VectorNormalize ( dir ) ;
//check for a closer one.
for ( loc = location - > next ; loc ; loc = loc - > next )
{
VectorSubtract ( loc - > pos , pos , dir ) ;
dist = VectorNormalize ( dir ) ;
if ( dist < bestdist )
{
best = loc - > name ;
bestdist = dist ;
}
}
return best ;
}
//////////////////////////////////////////////////////////
//Commands
# define INVIS_CHAR1 12
# define INVIS_CHAR2 138
# define INVIS_CHAR3 160
/*
= = = = = = = = = = = = = = =
CL_Say
Handles both say and say_team
= = = = = = = = = = = = = = =
*/
void CL_Say_f ( void )
{
char string [ 256 ] ;
char * msg ;
int c ;
if ( cls . state = = ca_disconnected | | cls . demoplayback )
{
# ifndef CLIENT_ONLY
if ( sv . state )
SV_ConSay_f ( ) ;
else
# endif
Con_TPrintf ( TL_CANTXNOTCONNECTED , Cmd_Argv ( 0 ) ) ;
return ;
}
if ( ! strcmp ( " sayone " , Cmd_Argv ( 0 ) ) )
{
if ( strcmp ( Info_ValueForKey ( cl . serverinfo , " *distrib " ) , DISTRIBUTION ) | | atoi ( Info_ValueForKey ( cl . serverinfo , " *ver " ) ) < PRE_SAYONE )
{
Con_TPrintf ( TLC_REQUIRESSERVERMOD , Cmd_Argv ( 0 ) ) ;
return ;
}
}
MSG_WriteByte ( & cls . netchan . message , clc_stringcmd ) ;
Q_strncpyz ( string , Cmd_Argv ( 0 ) , sizeof ( string ) ) ;
for ( msg = string ; * msg ; msg + + )
if ( * msg > = ' A ' & & * msg < = ' Z ' )
* msg = * msg - ' A ' + ' a ' ;
SZ_Print ( & cls . netchan . message , string ) ;
cls . netchan . message . cursize - - ;
msg = Cmd_Args ( ) ;
if ( Cmd_Argc ( ) > 1 )
{
SZ_Print ( & cls . netchan . message , " " ) ;
cls . netchan . message . cursize - - ;
MSG_WriteChar ( & cls . netchan . message , ' \" ' ) ;
while ( * msg )
{
c = * msg ;
if ( c = = ' % ' )
{
char * message = NULL ;
msg + + ;
if ( message = = NULL )
switch ( * msg )
{
case ' n ' :
SZ_Print ( & cls . netchan . message , name . string ) ;
cls . netchan . message . cursize - - ;
msg + + ;
continue ;
case ' h ' :
SZ_Print ( & cls . netchan . message , va ( " %i " , cl . stats [ 0 ] [ STAT_HEALTH ] ) ) ;
cls . netchan . message . cursize - - ; //remove the null term
msg + + ;
continue ;
case ' a ' :
SZ_Print ( & cls . netchan . message , va ( " %i " , cl . stats [ 0 ] [ STAT_ARMOR ] ) ) ;
cls . netchan . message . cursize - - ;
msg + + ;
continue ;
case ' A ' :
SZ_Print ( & cls . netchan . message , TP_ArmourType ( ) ) ;
cls . netchan . message . cursize - - ;
msg + + ;
continue ;
case ' l ' :
SZ_Print ( & cls . netchan . message , CL_LocationName ( r_refdef . vieworg ) ) ;
cls . netchan . message . cursize - - ;
msg + + ;
continue ;
case ' S ' :
SZ_Print ( & cls . netchan . message , TP_ClassForTFSkin ( ) ) ;
cls . netchan . message . cursize - - ;
msg + + ;
continue ;
case ' \0 ' : //whoops.
MSG_WriteChar ( & cls . netchan . message , ' % ' ) ;
MSG_WriteChar ( & cls . netchan . message , ' \" ' ) ;
MSG_WriteChar ( & cls . netchan . message , * msg ) ;
return ;
case ' % ' :
c = ' % ' ;
break ;
default :
c = ' % ' ;
msg - - ;
break ;
}
}
else if ( c = = ' $ ' )
{
msg + + ;
switch ( * msg )
{
case ' \\ ' : c = 0x0D ; break ;
case ' : ' : c = 0x0A ; break ;
case ' [ ' : c = 0x10 ; break ;
case ' ] ' : c = 0x11 ; break ;
case ' G ' : c = 0x86 ; break ;
case ' R ' : c = 0x87 ; break ;
case ' Y ' : c = 0x88 ; break ;
case ' B ' : c = 0x89 ; break ;
case ' ( ' : c = 0x80 ; break ;
case ' = ' : c = 0x81 ; break ;
case ' ) ' : c = 0x82 ; break ;
case ' a ' : c = 0x83 ; break ;
case ' < ' : c = 0x1d ; break ;
case ' - ' : c = 0x1e ; break ;
case ' > ' : c = 0x1f ; break ;
case ' , ' : c = 0x1c ; break ;
case ' . ' : c = 0x9c ; break ;
case ' b ' : c = 0x8b ; break ;
case ' c ' :
case ' d ' : c = 0x8d ; break ;
case ' $ ' : c = ' $ ' ; break ;
case ' ^ ' : c = ' ^ ' ; break ;
case ' x ' :
c = INVIS_CHAR1 ;
break ;
case ' y ' :
c = INVIS_CHAR2 ;
break ;
case ' z ' :
c = INVIS_CHAR3 ;
break ;
default :
msg - - ;
break ;
}
}
MSG_WriteChar ( & cls . netchan . message , c ) ;
msg + + ;
}
MSG_WriteChar ( & cls . netchan . message , ' \" ' ) ;
}
MSG_WriteChar ( & cls . netchan . message , ' \0 ' ) ;
}
2004-09-20 23:25:38 +00:00
void TP_Init ( void )
{
}
2004-08-23 00:15:46 +00:00
2004-09-20 23:25:38 +00:00
void TP_CheckPickupSound ( char * s , vec3_t org )
{
}
2004-08-23 00:15:46 +00:00
2004-09-20 23:25:38 +00:00
# endif
2004-08-23 00:15:46 +00:00
qboolean TP_SoundTrigger ( char * message ) //if there is a trigger there, play it. Return true if we found one, stripping off the file (it's neater that way).
{
char * strip ;
char * lineend = NULL ;
char soundname [ 128 ] ;
int filter = 0 ;
for ( strip = message + strlen ( message ) - 1 ; * strip & & strip > = message ; strip - - )
{
if ( * strip = = ' # ' )
filter + + ;
if ( * strip = = ' : ' )
break ; //if someone says just one word, we can take any tidles in thier name to be a voice command
if ( * strip = = ' \n ' )
lineend = strip ;
else if ( * strip < = ' ' )
{
if ( filter = = 0 | | filter = = 1 ) //allow one space in front of a filter.
{
filter + + ;
continue ;
}
break ;
}
else if ( * strip = = ' ~ ' )
{
//looks like a trigger, whoopie!
if ( lineend - strip > sizeof ( soundname ) - 1 )
{
Con_Printf ( " Sound trigger's file-name was too long \n " ) ;
return false ;
}
Q_strncpyz ( soundname , strip + 1 , lineend - strip ) ;
memmove ( strip , lineend , strlen ( lineend ) + 1 ) ;
Cbuf_AddText ( va ( " play %s \n " , soundname ) , RESTRICT_LOCAL ) ;
return true ;
}
}
return false ;
}