diff --git a/include/mathlib.h b/include/mathlib.h index 9e1efab..0d747be 100644 --- a/include/mathlib.h +++ b/include/mathlib.h @@ -48,6 +48,19 @@ extern int nanmask; #define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];} #define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];} +/* + * VectorDistance, the distance between two points. + * Yes, this is the same as sqrt(VectorSubtract then DotProduct), + * however that way would involve more vars, this is cheaper. + */ +#define VectorDistance(a, b) sqrt(((a[0] - b[0]) * (a[0] - b[0])) + \ + ((a[1] - b[1]) * (a[1] - b[1])) + \ + ((a[2] - b[2]) * (a[2] - b[2]))) + +#define VectorDistance_fast(a, b) (((a[0] - b[0]) * (a[0] - b[0])) + \ + ((a[1] - b[1]) * (a[1] - b[1])) + \ + ((a[2] - b[2]) * (a[2] - b[2]))) + // up / down #define PITCH 0 // left / right diff --git a/include/teamplay.h b/include/teamplay.h index 771758a..3b203c6 100644 --- a/include/teamplay.h +++ b/include/teamplay.h @@ -34,6 +34,8 @@ extern cvar_t *cl_parsesay; extern cvar_t *cl_nofake; // FIXME: prefix these with TP_ or Team_ ? -void CL_InitTeamplay (void); -void CL_BestWeaponImpulse (void); -char *CL_ParseSay (char *); +void Team_InitTeamplay (void); +void Team_BestWeaponImpulse (void); +void Team_Dead (void); +void Team_NewMap (void); +char *Team_ParseSay (char *); diff --git a/source/Makefile.am b/source/Makefile.am index 316b89a..5f7d8a0 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -44,9 +44,10 @@ if ASM_ARCH math_ASM = math.S endif common_SOURCES= net_chan.c net_com.c net_udp.c pmove.c pmovetst.c zone.c \ - mdfour.c mathlib.c cvar.c crc.c cmd.c \ - qargs.c qendian.c quakefs.c quakeio.c msg.c sizebuf.c info.c \ - checksum.c link.c buildnum.c va.c com.c model.c model_brush.c $(math_ASM) + mdfour.c mathlib.c cvar.c crc.c cmd.c qargs.c qendian.c \ + quakefs.c quakeio.c msg.c sizebuf.c info.c checksum.c \ + link.c buildnum.c va.c com.c model.c model_brush.c locs.c \ + $(math_ASM) # # Server builds diff --git a/source/cl_cmd.c b/source/cl_cmd.c index 709b212..14c3e45 100644 --- a/source/cl_cmd.c +++ b/source/cl_cmd.c @@ -71,7 +71,7 @@ void Cmd_ForwardToServer (void) !strcasecmp(Cmd_Argv(0), "say_team")) { char *s; - s = CL_ParseSay(Cmd_Args()); + s = Team_ParseSay(Cmd_Args()); if (*s && *s < 32 && *s != 10) { // otherwise the server would eat leading characters diff --git a/source/cl_input.c b/source/cl_input.c index 8fdc299..1b99696 100644 --- a/source/cl_input.c +++ b/source/cl_input.c @@ -188,7 +188,7 @@ void IN_Impulse (void) if (Cmd_Argc() <= 2) return; - CL_BestWeaponImpulse(); // HACK HACK HACK + Team_BestWeaponImpulse(); // HACK HACK HACK } /* diff --git a/source/cl_main.c b/source/cl_main.c index c074c1e..59a2df0 100644 --- a/source/cl_main.c +++ b/source/cl_main.c @@ -1593,12 +1593,12 @@ void Host_Init (quakeparms_t *parms) SCR_InitCvars (); VID_InitCvars (); COM_Init (); - CL_InitTeamplay (); + Team_InitTeamplay (); // reparse the command line for + commands other than set // (sets still done, but it doesn't matter) - Cmd_StuffCmds_f (); - Cbuf_Execute (); + //Cmd_StuffCmds_f (); + //Cbuf_Execute (); Host_FixupModelNames(); diff --git a/source/cl_parse.c b/source/cl_parse.c index 22379d6..7e7910c 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -44,6 +44,9 @@ #ifdef HAVE_STRINGS_H #include #endif +#ifdef HAVE_ERRNO_H +#include +#endif #ifdef HAVE_UNISTD_H #include #endif @@ -276,6 +279,7 @@ void Model_NextDownload (void) // all done cl.worldmodel = cl.model_precache[1]; R_NewMap (); + Team_NewMap (); Hunk_Check (); // make sure nothing is hurt // done with modellist, request first of static signon messages @@ -463,9 +467,9 @@ void CL_ParseDownload (void) snprintf (oldn, sizeof(oldn), "%s/qw/%s", fs_userpath->string, cls.downloadtempname); snprintf (newn, sizeof(newn), "%s/qw/%s", fs_userpath->string, cls.downloadname); } - r = rename (oldn, newn); + r = Qrename (oldn, newn); if (r) - Con_Printf ("failed to rename.\n"); + Con_Printf ("failed to rename, %s.\n", strerror(errno)); } cls.download = NULL; @@ -1070,12 +1074,17 @@ void CL_SetStat (int stat, int value) Sbar_Changed (); - if (stat == STAT_ITEMS) - { // set flash times - Sbar_Changed (); - for (j=0 ; j<32 ; j++) - if ( (value & (1< + #include "bothdefs.h" -#include "client.h" #include "cmd.h" -#include "cvar.h" +#include "client.h" #include "teamplay.h" +#include "locs.h" +#include "sys.h" cvar_t *cl_deadbodyfilter; cvar_t *cl_gibfilter; @@ -38,7 +41,7 @@ cvar_t *cl_parsesay; cvar_t *cl_nofake; -void CL_BestWeaponImpulse (void) +void Team_BestWeaponImpulse (void) { int best, i, imp, items; extern int in_impulse; @@ -94,43 +97,136 @@ void CL_BestWeaponImpulse (void) } -char *CL_ParseSay (char *s) +char *Team_ParseSay (char *s) { static char buf[1024]; - int i; - char c; + int i, bracket; + char c, chr, *t1, t2[128], t3[128]; + static location_t *location = NULL; if (!cl_parsesay->value) return s; i = 0; - while (*s && i < sizeof(buf)-1) - { - if (*s == '$') - { + while (*s && (i <= sizeof(buf))) { + if (*s == '$') { c = 0; - switch (s[1]) - { - case '\\': c = 13; break; // fake message - case '[': c = 0x90; break; // colored brackets - case ']': c = 0x91; break; - case 'G': c = 0x86; break; // ocrana leds - case 'R': c = 0x87; break; - case 'Y': c = 0x88; break; - case 'B': c = 0x89; break; + switch (s[1]) { + case '\\': c = 13; break; // fake message + case '[': c = 0x90; break; // colored brackets + case ']': c = 0x91; break; + case 'G': c = 0x86; break; // ocrana leds + case 'R': c = 0x87; break; + case 'Y': c = 0x88; break; + case 'B': c = 0x89; break; } - if (c) - { + if (c) { buf[i++] = c; s += 2; continue; } + } else if (*s == '%') { + t1 = NULL; + memset(t2, '\0', sizeof(t2)); + memset(t3, '\0', sizeof(t3)); + + if ((s[1] == '[') && (s[3] == ']')) { + bracket = 1; + chr = s[2]; + s += 4; + } else { + bracket = 0; + chr = s[1]; + s += 2; + } + switch (chr) { + case 'l': + bracket = 0; + location = locs_find(r_origin); + if (location) { + t1 = location->name; + } else + snprintf(t2, sizeof(t2), "Unknown!\n"); + break; + case 'a': + if (bracket) { + if (cl.stats[STAT_ARMOR] > 50) + bracket = 0; + + if (cl.stats[STAT_ITEMS] & IT_ARMOR3) + t3[0] = 'R' | 0x80; + else if (cl.stats[STAT_ITEMS] & IT_ARMOR2) + t3[0] = 'Y' | 0x80; + else if (cl.stats[STAT_ITEMS] & IT_ARMOR1) + t3[0] = 'G' | 0x80; + else { + t2[0] = 'N' | 0x80; + t2[1] = 'O' | 0x80; + t2[2] = 'N' | 0x80; + t2[3] = 'E' | 0x80; + t2[4] = '!' | 0x80; + } + + snprintf(t2, sizeof(t2), "%sa:%i", t3, cl.stats[STAT_ARMOR]); + } else + snprintf(t2, sizeof(t2), "%i", cl.stats[STAT_ARMOR]); + break; + case 'A': + bracket = 0; + if (cl.stats[STAT_ITEMS] & IT_ARMOR3) + t2[0] = 'R' | 0x80; + else if (cl.stats[STAT_ITEMS] & IT_ARMOR2) + t2[0] = 'Y' | 0x80; + else if (cl.stats[STAT_ITEMS] & IT_ARMOR1) + t2[0] = 'G' | 0x80; + else { + t2[0] = 'N' | 0x80; + t2[1] = 'O' | 0x80; + t2[2] = 'N' | 0x80; + t2[3] = 'E' | 0x80; + t2[4] = '!' | 0x80; + } + break; + case 'h': + if (bracket) { + if (cl.stats[STAT_HEALTH] > 50) + bracket = 0; + snprintf(t2, sizeof(t2), "h:%i", cl.stats[STAT_HEALTH]); + } else + snprintf(t2, sizeof(t2), "%i", cl.stats[STAT_HEALTH]); + break; + default: + bracket = 0; + } + + if (!t1) { + if (!t2[0]) { + t2[0] = '%'; + t2[1] = chr; + } + + t1 = t2; + } + + if (bracket) + buf[i++] = 0x90; // '[' + + if (t1) { + int len; + len = strlen(t1); + if (i + len >= sizeof(buf)) + continue; // No more space in buffer, icky. + strncpy(buf + i, t1, len); + i += len; + } + + if (bracket) + buf[i++] = 0x91; // ']' + + continue; } - -// TODO: parse team messages (%l, %a, %h, etc) - buf[i++] = *s++; } buf[i] = 0; @@ -138,8 +234,29 @@ char *CL_ParseSay (char *s) return buf; } +void Team_Dead () +{ +} -void CL_InitTeamplay (void) +void Team_NewMap () +{ + char *mapname, *t1, *t2; + + mapname = strdup(cl.worldmodel->name); + if (!mapname) + Sys_Error("Can't duplicate mapname!"); + t1 = strrchr(mapname, '/'); + t2 = strrchr(mapname, '.'); + if (!t1 || !t2) + Sys_Error("Can't find / or .!"); + t2[0] = '\0'; + + locs_reset(); + locs_load(t1); + free(mapname); +} + +void Team_InitTeamplay (void) { cl_deadbodyfilter = Cvar_Get("cl_deadbodyfilter", "0", CVAR_NONE, "Hide dead player models"); cl_gibfilter = Cvar_Get("cl_gibfilter", "0", CVAR_NONE, "Hide gibs");