summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2001-08-03 01:18:00 +0000
committerTim Angus <tim@ngus.net>2001-08-03 01:18:00 +0000
commitde7fdcb516d39976affbea3b69b5a32e11fc4a6a (patch)
tree4704c909e5aa256dd7c657b2e1c5c31c137c2bae
parent306ec15326090417f16513e962e2956bff1433f5 (diff)
1.29h upgrade.. oooo particles hehehehehehe
-rw-r--r--Makefile1
-rw-r--r--src/cgame/cg_consolecmds.c6
-rw-r--r--src/cgame/cg_draw.c62
-rw-r--r--src/cgame/cg_drawtools.c13
-rw-r--r--src/cgame/cg_event.c4
-rw-r--r--src/cgame/cg_local.h42
-rw-r--r--src/cgame/cg_main.c107
-rw-r--r--src/cgame/cg_players.c65
-rw-r--r--src/cgame/cg_predict.c2
-rw-r--r--src/cgame/cg_public.h8
-rw-r--r--src/cgame/cg_servercmds.c87
-rw-r--r--src/cgame/cg_snapshot.c11
-rw-r--r--src/cgame/cg_syscalls.asm9
-rw-r--r--src/cgame/cg_syscalls.c23
-rw-r--r--src/cgame/cg_view.c1
-rw-r--r--src/cgame/cg_weapons.c293
-rw-r--r--src/game/bg_lib.c29
-rw-r--r--src/game/bg_misc.c16
-rw-r--r--src/game/bg_public.h11
-rw-r--r--src/game/bg_slidemove.c6
-rw-r--r--src/game/g_active.c38
-rw-r--r--src/game/g_client.c32
-rw-r--r--src/game/g_cmds.c3
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_main.c9
-rw-r--r--src/game/g_misc.c13
-rw-r--r--src/game/g_mover.c83
-rw-r--r--src/game/g_public.h11
-rw-r--r--src/game/g_session.c16
-rw-r--r--src/game/g_spawn.c13
-rw-r--r--src/game/g_svcmds.c2
-rw-r--r--src/game/g_syscalls.asm7
-rw-r--r--src/game/g_syscalls.c23
-rw-r--r--src/game/g_team.c2
-rw-r--r--src/game/g_utils.c2
-rw-r--r--src/game/g_weapon.c2
-rw-r--r--src/game/q_shared.h2
37 files changed, 779 insertions, 278 deletions
diff --git a/Makefile b/Makefile
index a9ffefd5..34e8c546 100644
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,7 @@ CGOBJ = \
$(CGDIRNAME)/cg_creep.o \
$(CGDIRNAME)/cg_mem.o \
$(CGDIRNAME)/cg_mp3decoder.o \
+ $(CGDIRNAME)/cg_particles.o \
$(CGDIRNAME)/cg_scanner.o
UIOBJ = \
diff --git a/src/cgame/cg_consolecmds.c b/src/cgame/cg_consolecmds.c
index db613646..5f1bb0d6 100644
--- a/src/cgame/cg_consolecmds.c
+++ b/src/cgame/cg_consolecmds.c
@@ -178,6 +178,12 @@ CG_StartOrbit_f
*/
static void CG_StartOrbit_f( void ) {
+ char var[MAX_TOKEN_CHARS];
+
+ trap_Cvar_VariableStringBuffer( "developer", var, sizeof( var ) );
+ if ( !atoi(var) ) {
+ return;
+ }
if (cg_cameraOrbit.value != 0) {
trap_Cvar_Set("cg_cameraOrbit", "0");
trap_Cvar_Set("cg_thirdPerson", "0");
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 6f82deb0..c004c3d5 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -313,13 +313,13 @@ void CG_DrawTeamBackground( int x, int y, int w, int h, float alpha, int team )
hcolor[3] = alpha;
if ( team == TEAM_HUMANS ) {
- hcolor[0] = 1;
- hcolor[1] = 0;
- hcolor[2] = 0;
+ hcolor[0] = 1.0f;
+ hcolor[1] = 0.0f;
+ hcolor[2] = 0.0f;
} else if ( team == TEAM_DROIDS ) {
- hcolor[0] = 0;
- hcolor[1] = 0;
- hcolor[2] = 1;
+ hcolor[0] = 0.0f;
+ hcolor[1] = 0.0f;
+ hcolor[2] = 1.0f;
} else {
return;
}
@@ -1086,9 +1086,9 @@ static float CG_DrawScores( float y ) {
if ( cgs.gametype >= GT_TEAM ) {
x = 640;
- color[0] = 0;
- color[1] = 0;
- color[2] = 1;
+ color[0] = 0.0f;
+ color[1] = 0.0f;
+ color[2] = 1.0f;
color[3] = 0.33f;
s = va( "%2i", s2 );
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH + 8;
@@ -1111,9 +1111,9 @@ static float CG_DrawScores( float y ) {
}
}
- color[0] = 1;
- color[1] = 0;
- color[2] = 0;
+ color[0] = 1.0f;
+ color[1] = 0.0f;
+ color[2] = 0.0f;
color[3] = 0.33f;
s = va( "%2i", s1 );
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH + 8;
@@ -1166,9 +1166,9 @@ static float CG_DrawScores( float y ) {
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH + 8;
x -= w;
if ( !spectator && score == s2 && score != s1 ) {
- color[0] = 1;
- color[1] = 0;
- color[2] = 0;
+ color[0] = 1.0f;
+ color[1] = 0.0f;
+ color[2] = 0.0f;
color[3] = 0.33f;
CG_FillRect( x, y-4, w, BIGCHAR_HEIGHT+8, color );
CG_DrawPic( x, y-4, w, BIGCHAR_HEIGHT+8, cgs.media.selectShader );
@@ -1188,9 +1188,9 @@ static float CG_DrawScores( float y ) {
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH + 8;
x -= w;
if ( !spectator && score == s1 ) {
- color[0] = 0;
- color[1] = 0;
- color[2] = 1;
+ color[0] = 0.0f;
+ color[1] = 0.0f;
+ color[2] = 1.0f;
color[3] = 0.33f;
CG_FillRect( x, y-4, w, BIGCHAR_HEIGHT+8, color );
CG_DrawPic( x, y-4, w, BIGCHAR_HEIGHT+8, cgs.media.selectShader );
@@ -1234,7 +1234,9 @@ static float CG_DrawPowerups( float y ) {
float size;
float f;
static float colors[2][4] = {
- { 0.2f, 1.0f, 0.2f, 1.0f } , { 1.0f, 0.2f, 0.2f, 1.0f } };
+ { 0.2f, 1.0f, 0.2f, 1.0f },
+ { 1.0f, 0.2f, 0.2f, 1.0f }
+ };
ps = &cg.snap->ps;
@@ -1426,19 +1428,19 @@ static void CG_DrawTeamInfo( void ) {
w += TINYCHAR_WIDTH * 2;
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_HUMANS ) {
- hcolor[0] = 1;
- hcolor[1] = 0;
- hcolor[2] = 0;
+ hcolor[0] = 1.0f;
+ hcolor[1] = 0.0f;
+ hcolor[2] = 0.0f;
hcolor[3] = 0.33f;
} else if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_DROIDS ) {
- hcolor[0] = 0;
- hcolor[1] = 0;
- hcolor[2] = 1;
+ hcolor[0] = 0.0f;
+ hcolor[1] = 0.0f;
+ hcolor[2] = 1.0f;
hcolor[3] = 0.33f;
} else {
- hcolor[0] = 0;
- hcolor[1] = 1;
- hcolor[2] = 0;
+ hcolor[0] = 0.0f;
+ hcolor[1] = 1.0f;
+ hcolor[2] = 0.0f;
hcolor[3] = 0.33f;
}
@@ -1446,8 +1448,8 @@ static void CG_DrawTeamInfo( void ) {
CG_DrawPic( CHATLOC_X, CHATLOC_Y - h, 640, h, cgs.media.teamStatusBar );
trap_R_SetColor( NULL );
- hcolor[0] = hcolor[1] = hcolor[2] = 1.0;
- hcolor[3] = 1.0;
+ hcolor[0] = hcolor[1] = hcolor[2] = 1.0f;
+ hcolor[3] = 1.0f;
for (i = cgs.teamChatPos - 1; i >= cgs.teamLastChatPos; i--) {
CG_DrawStringExt( CHATLOC_X + TINYCHAR_WIDTH,
diff --git a/src/cgame/cg_drawtools.c b/src/cgame/cg_drawtools.c
index 77a8d411..6aa4a581 100644
--- a/src/cgame/cg_drawtools.c
+++ b/src/cgame/cg_drawtools.c
@@ -464,9 +464,10 @@ void CG_ColorForHealth( vec4_t hcolor ) {
cg.snap->ps.stats[STAT_ARMOR], hcolor );
}
-
-
-
+// bk001205 - code below duplicated in q3_ui/ui-atoms.c
+// bk001205 - FIXME: does this belong in ui_shared.c?
+// bk001205 - FIXME: HARD_LINKED flags not visible here
+#ifndef Q3_STATIC // bk001205 - q_shared defines not visible here
/*
=================
UI_DrawProportionalString2
@@ -626,7 +627,7 @@ UI_DrawBannerString
static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color )
{
const char* s;
- char ch;
+ unsigned char ch;
float ax;
float ay;
float aw;
@@ -736,7 +737,7 @@ int UI_ProportionalStringWidth( const char* str ) {
static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t color, float sizeScale, qhandle_t charset )
{
const char* s;
- char ch;
+ unsigned char ch;
float ax;
float ay;
float aw;
@@ -851,4 +852,4 @@ void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t
UI_DrawProportionalString2( x, y, str, color, sizeScale, cgs.media.charsetProp );
}
-
+#endif // Q3STATIC
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index 250349c6..37ac7435 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -28,8 +28,10 @@
#include "cg_local.h"
+#ifdef MISSIONPACK // bk001205
// for the voice chats
#include "../ta_ui/menudef.h"
+#endif
//==========================================================================
@@ -940,11 +942,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
DEBUGNAME("EV_RAILTRAIL");
cent->currentState.weapon = WP_RAILGUN;
// if the end was on a nomark surface, don't make an explosion
+ CG_RailTrail( es->origin2, es->pos.trBase );
if ( es->eventParm != 255 ) {
ByteToDir( es->eventParm, dir );
CG_MissileHitWall( es->weapon, es->clientNum, position, dir, IMPACTSOUND_DEFAULT );
}
- CG_RailTrail( es->origin2, es->pos.trBase );
break;
case EV_BULLET_HIT_WALL:
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 0e398258..38bc3d26 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -176,6 +176,7 @@ typedef struct centity_s {
int trailTime; // so missile trails can handle dropped initial packets
int dustTrailTime;
int miscTime;
+ int snapShotTime; // last time this entity was found in a snapshot
playerEntity_t pe;
@@ -308,7 +309,8 @@ typedef struct {
int botSkill; // 0 = not bot, 1-5 = bot
- vec3_t color;
+ vec3_t color1;
+ vec3_t color2;
int score; // updated by score servercmds
int location; // location index for team mode
@@ -343,7 +345,9 @@ typedef struct {
qboolean deferred;
qboolean newAnims; // true if using the new mission pack animations
-
+ qboolean fixedlegs; // true if legs yaw is always the same as torso yaw
+ qboolean fixedtorso; // true if torso never changes yaw
+
vec3_t headOffset; // move head in icon views
footstep_t footsteps;
gender_t gender; // from model
@@ -585,6 +589,11 @@ typedef struct {
int soundTime;
qhandle_t soundBuffer[MAX_SOUNDBUFFER];
+ // for voice chat buffer
+ int voiceChatTime;
+ int voiceChatBufferIn;
+ int voiceChatBufferOut;
+
// warmup countdown
int warmup;
int warmupCount;
@@ -661,7 +670,6 @@ typedef struct {
qhandle_t redFlagShader[3];
qhandle_t blueFlagShader[3];
qhandle_t flagShader[4];
-#ifdef NEW_ANIMS
qhandle_t flagPoleModel;
qhandle_t flagFlapModel;
@@ -673,6 +681,7 @@ typedef struct {
qhandle_t blueFlagBaseModel;
qhandle_t neutralFlagBaseModel;
+#ifdef MISSIONPACK
qhandle_t overloadBaseModel;
qhandle_t overloadTargetModel;
qhandle_t overloadLightsModel;
@@ -1166,6 +1175,11 @@ extern vmCvar_t cg_cameraMode;
extern vmCvar_t cg_smallFont;
extern vmCvar_t cg_bigFont;
extern vmCvar_t cg_noTaunt;
+extern vmCvar_t cg_noProjectileTrail;
+extern vmCvar_t cg_oldRail;
+extern vmCvar_t cg_oldRocket;
+extern vmCvar_t cg_oldPlasma;
+extern vmCvar_t cg_trueLightning;
extern vmCvar_t cg_creepRes;
extern vmCvar_t cg_drawSurfNormal;
extern vmCvar_t cg_debugAlloc;
@@ -1305,7 +1319,7 @@ void CG_InitBuildables( );
//
void CG_BuildSolidList( void );
int CG_PointContents( const vec3_t point, int passEntityNum );
-void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
+void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask );
void CG_PredictPlayerState( void );
void CG_LoadDeferredPlayers( void );
@@ -1580,6 +1594,7 @@ void trap_R_AddRefEntityToScene( const refEntity_t *re );
// polys are intended for simple wall marks, not really for doing
// significant construction
void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts );
+void trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int numPolys );
void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b );
void trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b );
int trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );
@@ -1654,3 +1669,22 @@ void trap_CIN_SetExtents (int handle, int x, int y, int w, int h);
void trap_SnapVector( float *v );
+qboolean trap_loadCamera(const char *name);
+void trap_startCamera(int time);
+qboolean trap_getCameraInfo(int time, vec3_t *origin, vec3_t *angles);
+
+qboolean trap_GetEntityToken( char *buffer, int bufferSize );
+
+void CG_ClearParticles (void);
+void CG_AddParticles (void);
+void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum);
+void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent);
+void CG_AddParticleShrapnel (localEntity_t *le);
+void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent);
+void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration);
+void CG_ParticleSparks (vec3_t org, vec3_t vel, int duration, float x, float y, float speed);
+void CG_ParticleDust (centity_t *cent, vec3_t origin, vec3_t dir);
+void CG_ParticleMisc (qhandle_t pshader, vec3_t origin, int size, int duration, float alpha);
+void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duration, int sizeStart, int sizeEnd);
+extern qboolean initparticles;
+int CG_NewParticleArea ( int num );
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index dfe76d13..e9717faf 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -178,6 +178,11 @@ vmCvar_t cg_timescale;
vmCvar_t cg_smallFont;
vmCvar_t cg_bigFont;
vmCvar_t cg_noTaunt;
+vmCvar_t cg_noProjectileTrail;
+vmCvar_t cg_oldRail;
+vmCvar_t cg_oldRocket;
+vmCvar_t cg_oldPlasma;
+vmCvar_t cg_trueLightning;
vmCvar_t cg_creepRes;
vmCvar_t cg_drawSurfNormal;
vmCvar_t cg_debugAlloc;
@@ -190,7 +195,7 @@ typedef struct {
int cvarFlags;
} cvarTable_t;
-cvarTable_t cvarTable[] = {
+static cvarTable_t cvarTable[] = {
{ &cg_ignore, "cg_ignore", "0", 0 }, // used for debugging
{ &cg_autoswitch, "cg_autoswitch", "1", CVAR_ARCHIVE },
{ &cg_drawGun, "cg_drawGun", "1", CVAR_ARCHIVE },
@@ -281,13 +286,17 @@ cvarTable_t cvarTable[] = {
{ &pmove_fixed, "pmove_fixed", "0", 0},
{ &pmove_msec, "pmove_msec", "8", 0},
{ &cg_noTaunt, "cg_noTaunt", "0", CVAR_ARCHIVE},
+ { &cg_noProjectileTrail, "cg_noProjectileTrail", "0", CVAR_ARCHIVE},
{ &cg_smallFont, "ui_smallFont", "0.25", CVAR_ARCHIVE},
{ &cg_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE},
-
+ { &cg_oldRail, "cg_oldRail", "1", CVAR_ARCHIVE},
+ { &cg_oldRocket, "cg_oldRocket", "1", CVAR_ARCHIVE},
+ { &cg_oldPlasma, "cg_oldPlasma", "1", CVAR_ARCHIVE},
+ { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE}
// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
};
-int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
+static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
/*
=================
@@ -520,49 +529,49 @@ static void CG_RegisterSounds( void ) {
// voice commands
- cgs.media.oneMinuteSound = trap_S_RegisterSound( "sound/feedback/1_minute.wav", qfalse );
- cgs.media.fiveMinuteSound = trap_S_RegisterSound( "sound/feedback/5_minute.wav", qfalse );
- cgs.media.suddenDeathSound = trap_S_RegisterSound( "sound/feedback/sudden_death.wav", qfalse );
- cgs.media.oneFragSound = trap_S_RegisterSound( "sound/feedback/1_frag.wav", qfalse );
- cgs.media.twoFragSound = trap_S_RegisterSound( "sound/feedback/2_frags.wav", qfalse );
- cgs.media.threeFragSound = trap_S_RegisterSound( "sound/feedback/3_frags.wav", qfalse );
- cgs.media.count3Sound = trap_S_RegisterSound( "sound/feedback/three.wav", qfalse );
- cgs.media.count2Sound = trap_S_RegisterSound( "sound/feedback/two.wav", qfalse );
- cgs.media.count1Sound = trap_S_RegisterSound( "sound/feedback/one.wav", qfalse );
- cgs.media.countFightSound = trap_S_RegisterSound( "sound/feedback/fight.wav", qfalse );
- cgs.media.countPrepareSound = trap_S_RegisterSound( "sound/feedback/prepare.wav", qfalse );
+ cgs.media.oneMinuteSound = trap_S_RegisterSound( "sound/feedback/1_minute.wav", qtrue );
+ cgs.media.fiveMinuteSound = trap_S_RegisterSound( "sound/feedback/5_minute.wav", qtrue );
+ cgs.media.suddenDeathSound = trap_S_RegisterSound( "sound/feedback/sudden_death.wav", qtrue );
+ cgs.media.oneFragSound = trap_S_RegisterSound( "sound/feedback/1_frag.wav", qtrue );
+ cgs.media.twoFragSound = trap_S_RegisterSound( "sound/feedback/2_frags.wav", qtrue );
+ cgs.media.threeFragSound = trap_S_RegisterSound( "sound/feedback/3_frags.wav", qtrue );
+ cgs.media.count3Sound = trap_S_RegisterSound( "sound/feedback/three.wav", qtrue );
+ cgs.media.count2Sound = trap_S_RegisterSound( "sound/feedback/two.wav", qtrue );
+ cgs.media.count1Sound = trap_S_RegisterSound( "sound/feedback/one.wav", qtrue );
+ cgs.media.countFightSound = trap_S_RegisterSound( "sound/feedback/fight.wav", qtrue );
+ cgs.media.countPrepareSound = trap_S_RegisterSound( "sound/feedback/prepare.wav", qtrue );
if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
- cgs.media.captureAwardSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav", qfalse );
- cgs.media.redLeadsSound = trap_S_RegisterSound( "sound/feedback/redleads.wav", qfalse );
- cgs.media.blueLeadsSound = trap_S_RegisterSound( "sound/feedback/blueleads.wav", qfalse );
- cgs.media.teamsTiedSound = trap_S_RegisterSound( "sound/feedback/teamstied.wav", qfalse );
- cgs.media.hitTeamSound = trap_S_RegisterSound( "sound/feedback/hit_teammate.wav", qfalse );
+ cgs.media.captureAwardSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav", qtrue );
+ cgs.media.redLeadsSound = trap_S_RegisterSound( "sound/feedback/redleads.wav", qtrue );
+ cgs.media.blueLeadsSound = trap_S_RegisterSound( "sound/feedback/blueleads.wav", qtrue );
+ cgs.media.teamsTiedSound = trap_S_RegisterSound( "sound/feedback/teamstied.wav", qtrue );
+ cgs.media.hitTeamSound = trap_S_RegisterSound( "sound/feedback/hit_teammate.wav", qtrue );
- cgs.media.redScoredSound = trap_S_RegisterSound( "sound/teamplay/voc_red_scores.wav", qfalse );
- cgs.media.blueScoredSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_scores.wav", qfalse );
+ cgs.media.redScoredSound = trap_S_RegisterSound( "sound/teamplay/voc_red_scores.wav", qtrue );
+ cgs.media.blueScoredSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_scores.wav", qtrue );
- cgs.media.captureYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav", qfalse );
- cgs.media.captureOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_opponent.wav", qfalse );
+ cgs.media.captureYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_yourteam.wav", qtrue );
+ cgs.media.captureOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagcapture_opponent.wav", qtrue );
- cgs.media.returnYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_yourteam.wav", qfalse );
- cgs.media.returnOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qfalse );
+ cgs.media.returnYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_yourteam.wav", qtrue );
+ cgs.media.returnOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qtrue );
- cgs.media.takenYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_yourteam.wav", qfalse );
- cgs.media.takenOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_opponent.wav", qfalse );
+ cgs.media.takenYourTeamSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_yourteam.wav", qtrue );
+ cgs.media.takenOpponentSound = trap_S_RegisterSound( "sound/teamplay/flagtaken_opponent.wav", qtrue );
if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
- cgs.media.redFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_red_returned.wav", qfalse );
- cgs.media.blueFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_returned.wav", qfalse );
- cgs.media.enemyTookYourFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_flag.wav", qfalse );
- cgs.media.yourTeamTookEnemyFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_flag.wav", qfalse );
+ cgs.media.redFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_red_returned.wav", qtrue );
+ cgs.media.blueFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/voc_blue_returned.wav", qtrue );
+ cgs.media.enemyTookYourFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_flag.wav", qtrue );
+ cgs.media.yourTeamTookEnemyFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_flag.wav", qtrue );
}
- cgs.media.youHaveFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_you_flag.wav", qfalse );
- cgs.media.holyShitSound = trap_S_RegisterSound("sound/feedback/voc_holyshit.wav", qfalse);
- cgs.media.neutralFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qfalse );
- cgs.media.yourTeamTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_1flag.wav", qfalse );
- cgs.media.enemyTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_1flag.wav", qfalse );
+ cgs.media.youHaveFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_you_flag.wav", qtrue );
+ cgs.media.holyShitSound = trap_S_RegisterSound("sound/feedback/voc_holyshit.wav", qtrue);
+ cgs.media.neutralFlagReturnedSound = trap_S_RegisterSound( "sound/teamplay/flagreturn_opponent.wav", qtrue );
+ cgs.media.yourTeamTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_team_1flag.wav", qtrue );
+ cgs.media.enemyTookTheFlagSound = trap_S_RegisterSound( "sound/teamplay/voc_enemy_1flag.wav", qtrue );
}
cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/machinegun/buletby1.wav", qfalse );
@@ -585,16 +594,16 @@ static void CG_RegisterSounds( void ) {
cgs.media.hitSound = trap_S_RegisterSound( "sound/feedback/hit.wav", qfalse );
- cgs.media.impressiveSound = trap_S_RegisterSound( "sound/feedback/impressive.wav", qfalse );
- cgs.media.excellentSound = trap_S_RegisterSound( "sound/feedback/excellent.wav", qfalse );
- cgs.media.deniedSound = trap_S_RegisterSound( "sound/feedback/denied.wav", qfalse );
- cgs.media.humiliationSound = trap_S_RegisterSound( "sound/feedback/humiliation.wav", qfalse );
- cgs.media.assistSound = trap_S_RegisterSound( "sound/feedback/assist.wav", qfalse );
- cgs.media.defendSound = trap_S_RegisterSound( "sound/feedback/defense.wav", qfalse );
+ cgs.media.impressiveSound = trap_S_RegisterSound( "sound/feedback/impressive.wav", qtrue );
+ cgs.media.excellentSound = trap_S_RegisterSound( "sound/feedback/excellent.wav", qtrue );
+ cgs.media.deniedSound = trap_S_RegisterSound( "sound/feedback/denied.wav", qtrue );
+ cgs.media.humiliationSound = trap_S_RegisterSound( "sound/feedback/humiliation.wav", qtrue );
+ cgs.media.assistSound = trap_S_RegisterSound( "sound/feedback/assist.wav", qtrue );
+ cgs.media.defendSound = trap_S_RegisterSound( "sound/feedback/defense.wav", qtrue );
- cgs.media.takenLeadSound = trap_S_RegisterSound( "sound/feedback/takenlead.wav", qfalse);
- cgs.media.tiedLeadSound = trap_S_RegisterSound( "sound/feedback/tiedlead.wav", qfalse);
- cgs.media.lostLeadSound = trap_S_RegisterSound( "sound/feedback/lostlead.wav", qfalse);
+ cgs.media.takenLeadSound = trap_S_RegisterSound( "sound/feedback/takenlead.wav", qtrue);
+ cgs.media.tiedLeadSound = trap_S_RegisterSound( "sound/feedback/tiedlead.wav", qtrue);
+ cgs.media.lostLeadSound = trap_S_RegisterSound( "sound/feedback/lostlead.wav", qtrue);
cgs.media.watrInSound = trap_S_RegisterSound( "sound/player/watr_in.wav", qfalse);
cgs.media.watrOutSound = trap_S_RegisterSound( "sound/player/watr_out.wav", qfalse);
@@ -661,12 +670,6 @@ static void CG_RegisterSounds( void ) {
cgs.media.n_healthSound = trap_S_RegisterSound("sound/items/n_health.wav", qfalse );
cgs.media.hgrenb1aSound = trap_S_RegisterSound("sound/weapons/grenade/hgrenb1a.wav", qfalse);
cgs.media.hgrenb2aSound = trap_S_RegisterSound("sound/weapons/grenade/hgrenb2a.wav", qfalse);
-
- //TA: it complains about these
- /*cgs.media.wstbimplSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpl.wav", qfalse);
- cgs.media.wstbimpmSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpm.wav", qfalse);
- cgs.media.wstbimpdSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbimpd.wav", qfalse);
- cgs.media.wstbactvSound = trap_S_RegisterSound("sound/weapons/proxmine/wstbactv.wav", qfalse);*/
}
@@ -901,6 +904,8 @@ static void CG_RegisterGraphics( void ) {
}
cgs.gameModels[i] = trap_R_RegisterModel( modelName );
}
+
+ CG_ClearParticles ();
}
diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c
index 77c01f81..c876ed17 100644
--- a/src/cgame/cg_players.c
+++ b/src/cgame/cg_players.c
@@ -125,6 +125,8 @@ static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci )
ci->footsteps = FOOTSTEP_NORMAL;
VectorClear( ci->headOffset );
ci->gender = GENDER_MALE;
+ ci->fixedlegs = qfalse;
+ ci->fixedtorso = qfalse;
// read optional parameters
while ( 1 ) {
@@ -174,6 +176,12 @@ static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci )
ci->gender = GENDER_MALE;
}
continue;
+ } else if ( !Q_stricmp( token, "fixedlegs" ) ) {
+ ci->fixedlegs = qtrue;
+ continue;
+ } else if ( !Q_stricmp( token, "fixedtorso" ) ) {
+ ci->fixedtorso = qtrue;
+ continue;
}
// if it is a number, start parsing animations
@@ -189,7 +197,6 @@ static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci )
token = COM_Parse( &text_p );
if ( !*token ) {
-#ifdef NEW_ANIMS
if( i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE ) {
animations[i].firstFrame = animations[TORSO_GESTURE].firstFrame;
animations[i].frameLerp = animations[TORSO_GESTURE].frameLerp;
@@ -200,7 +207,6 @@ static qboolean CG_ParseAnimationFile( const char *filename, clientInfo_t *ci )
animations[i].flipflop = qfalse;
continue;
}
-#endif
break;
}
animations[i].firstFrame = atoi( token );
@@ -325,7 +331,7 @@ CG_RegisterClientModelname
==========================
*/
static qboolean CG_RegisterClientModelname( clientInfo_t *ci, const char *modelName, const char *skinName ) {
- char filename[MAX_QPATH];
+ char filename[MAX_QPATH*2];
// load cmodels before models so filecache works
@@ -423,11 +429,16 @@ static void CG_LoadClientInfo( clientInfo_t *ci ) {
// fall back
if ( cgs.gametype >= GT_TEAM ) {
- // keep skin name
+/* // keep skin name
+ if( ci->team == TEAM_BLUE ) {
+ Q_strncpyz(teamname, DEFAULT_BLUETEAM_NAME, sizeof(teamname) );
+ } else {
+ Q_strncpyz(teamname, DEFAULT_REDTEAM_NAME, sizeof(teamname) );
+ }
if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, ci->skinName ) ) {
CG_Error( "DEFAULT_MODEL / skin (%s/%s) failed to register",
DEFAULT_MODEL, ci->skinName );
- }
+ }*/
} else {
if ( !CG_RegisterClientModelname( ci, DEFAULT_MODEL, "default" ) ) {
CG_Error( "DEFAULT_MODEL (%s) failed to register", DEFAULT_MODEL );
@@ -640,7 +651,10 @@ void CG_PrecacheClientInfo( int clientNum ) {
// colors
v = Info_ValueForKey( configstring, "c1" );
- CG_ColorFromString( v, newInfo.color );
+ CG_ColorFromString( v, newInfo.color1 );
+
+ v = Info_ValueForKey( configstring, "c2" );
+ CG_ColorFromString( v, newInfo.color2 );
// bot skill
v = Info_ValueForKey( configstring, "skill" );
@@ -743,7 +757,10 @@ void CG_NewClientInfo( int clientNum ) {
// colors
v = Info_ValueForKey( configstring, "c1" );
- CG_ColorFromString( v, newInfo.color );
+ CG_ColorFromString( v, newInfo.color1 );
+
+ v = Info_ValueForKey( configstring, "c2" );
+ CG_ColorFromString( v, newInfo.color2 );
// bot skill
v = Info_ValueForKey( configstring, "skill" );
@@ -1176,7 +1193,8 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v
static int movementOffsets[8] = { 0, 22, 45, -22, 0, 22, -45, -22 };
vec3_t velocity;
float speed;
- int dir;
+ int dir, clientNum;
+ clientInfo_t *ci;
VectorCopy( cent->lerpAngles, headAngles );
headAngles[YAW] = AngleMod( headAngles[YAW] );
@@ -1226,6 +1244,15 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v
CG_SwingAngles( dest, 15, 30, 0.1f, &cent->pe.torso.pitchAngle, &cent->pe.torso.pitching );
torsoAngles[PITCH] = cent->pe.torso.pitchAngle;
+ //
+ clientNum = cent->currentState.clientNum;
+ if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) {
+ ci = &cgs.clientinfo[ clientNum ];
+ if ( ci->fixedtorso ) {
+ torsoAngles[PITCH] = 0.0f;
+ }
+ }
+
// --------- roll -------------
@@ -1246,6 +1273,17 @@ static void CG_PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t torso[3], v
legsAngles[PITCH] += side;
}
+ //
+ clientNum = cent->currentState.clientNum;
+ if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) {
+ ci = &cgs.clientinfo[ clientNum ];
+ if ( ci->fixedlegs ) {
+ legsAngles[YAW] = torsoAngles[YAW];
+ legsAngles[PITCH] = 0.0f;
+ legsAngles[ROLL] = 0.0f;
+ }
+ }
+
// pain twitch
CG_AddPainTwitch( cent, torsoAngles );
@@ -1330,11 +1368,7 @@ static void CG_TrailItem( centity_t *cent, qhandle_t hModel ) {
CG_PlayerPowerups
===============
*/
-#ifdef NEW_ANIMS
static void CG_PlayerPowerups( centity_t *cent, refEntity_t *torso ) {
-#else
-static void CG_PlayerPowerups( centity_t *cent ) {
-#endif
int powerups;
clientInfo_t *ci;
@@ -1484,7 +1518,7 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane ) {
trap_CM_BoxTrace( &trace, cent->lerpOrigin, end, mins, maxs, 0, MASK_PLAYERSOLID );
// no shadow if too high
- if ( trace.fraction == 1.0 ) {
+ if ( trace.fraction == 1.0 || trace.startsolid || trace.allsolid ) {
return qfalse;
}
@@ -1802,11 +1836,6 @@ void CG_Player( centity_t *cent )
CG_PlayerAnimation( cent, &legs.oldframe, &legs.frame, &legs.backlerp,
&torso.oldframe, &torso.frame, &torso.backlerp );
-#ifndef NEW_ANIMS
- // add powerups floating behind the player
- //CG_PlayerPowerups( cent );
-#endif
-
// add the talk baloon or disconnect icon
CG_PlayerSprites( cent );
diff --git a/src/cgame/cg_predict.c b/src/cgame/cg_predict.c
index 602efa0b..71045d16 100644
--- a/src/cgame/cg_predict.c
+++ b/src/cgame/cg_predict.c
@@ -146,7 +146,7 @@ static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const
CG_Trace
================
*/
-void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
+void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
int skipNumber, int mask ) {
trace_t t;
diff --git a/src/cgame/cg_public.h b/src/cgame/cg_public.h
index 9935a79e..a090ae16 100644
--- a/src/cgame/cg_public.h
+++ b/src/cgame/cg_public.h
@@ -157,6 +157,14 @@ typedef enum {
CG_S_ADDREALLOOPINGSOUND,
CG_S_STOPLOOPINGSOUND,
+ CG_CM_TEMPCAPSULEMODEL,
+ CG_CM_CAPSULETRACE,
+ CG_CM_TRANSFORMEDCAPSULETRACE,
+ CG_R_ADDADDITIVELIGHTTOSCENE,
+ CG_GET_ENTITY_TOKEN,
+ CG_R_ADDPOLYSTOSCENE,
+ CG_R_INPVS,
+
CG_MEMSET = 100,
CG_MEMCPY,
CG_STRNCPY,
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 95aca2d5..ed0a7956 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -428,6 +428,7 @@ static void CG_MapRestart( void ) {
CG_InitLocalEntities();
CG_InitMarkPolys();
+ CG_ClearParticles ();
// make sure the "3 frags left" warnings play again
cg.fraglimitWarnings = 0;
@@ -451,6 +452,7 @@ static void CG_MapRestart( void ) {
trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER );
CG_CenterPrint( "FIGHT!", 120, GIANTCHAR_WIDTH*2 );
}
+ trap_Cvar_Set("cg_thirdPerson", "0");
}
#define MAX_VOICEFILESIZE 16384
@@ -506,7 +508,7 @@ int CG_ParseVoiceChats( const char *filename, voiceChatList_t *voiceChatList, in
len = trap_FS_FOpenFile( filename, &f, FS_READ );
if ( !f ) {
- trap_Print( va( S_COLOR_RED "voice chat file not found: %s\n", filename ) );
+ //trap_Print( va( S_COLOR_RED "voice chat file not found: %s\n", filename ) );
return qfalse;
}
if ( len >= MAX_VOICEFILESIZE ) {
@@ -677,37 +679,52 @@ CG_VoiceChatListForClient
voiceChatList_t *CG_VoiceChatListForClient( int clientNum ) {
clientInfo_t *ci;
int voiceChatNum, i, j, k, gender;
- char filename[128], *headModelName;
+ char filename[MAX_QPATH], headModelName[MAX_QPATH];
if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) {
clientNum = 0;
}
ci = &cgs.clientinfo[ clientNum ];
- headModelName = ci->headModelName;
- if (headModelName[0] == '*')
- headModelName++;
- // find the voice file for the head model the client uses
- for ( i = 0; i < MAX_HEADMODELS; i++ ) {
- if (!Q_stricmp(headModelVoiceChat[i].headmodel, headModelName)) {
- break;
+ for ( k = 0; k < 2; k++ ) {
+ if ( k == 0 ) {
+ if (ci->headModelName[0] == '*') {
+ Com_sprintf( headModelName, sizeof(headModelName), "%s/%s", ci->headModelName+1, ci->headSkinName );
+ }
+ else {
+ Com_sprintf( headModelName, sizeof(headModelName), "%s/%s", ci->headModelName, ci->headSkinName );
+ }
}
- }
- if (i < MAX_HEADMODELS) {
- return &voiceChatLists[headModelVoiceChat[i].voiceChatNum];
- }
- // find a <headmodelname>.vc file
- for ( i = 0; i < MAX_HEADMODELS; i++ ) {
- if (!strlen(headModelVoiceChat[i].headmodel)) {
- Com_sprintf(filename, sizeof(filename), "scripts/%s.vc", headModelName);
- voiceChatNum = CG_HeadModelVoiceChats(filename);
- if (voiceChatNum == -1)
+ else {
+ if (ci->headModelName[0] == '*') {
+ Com_sprintf( headModelName, sizeof(headModelName), "%s", ci->headModelName+1 );
+ }
+ else {
+ Com_sprintf( headModelName, sizeof(headModelName), "%s", ci->headModelName );
+ }
+ }
+ // find the voice file for the head model the client uses
+ for ( i = 0; i < MAX_HEADMODELS; i++ ) {
+ if (!Q_stricmp(headModelVoiceChat[i].headmodel, headModelName)) {
break;
- Com_sprintf(headModelVoiceChat[i].headmodel, sizeof ( headModelVoiceChat[i].headmodel ),
- "%s", headModelName);
- headModelVoiceChat[i].voiceChatNum = voiceChatNum;
+ }
+ }
+ if (i < MAX_HEADMODELS) {
return &voiceChatLists[headModelVoiceChat[i].voiceChatNum];
}
+ // find a <headmodelname>.vc file
+ for ( i = 0; i < MAX_HEADMODELS; i++ ) {
+ if (!strlen(headModelVoiceChat[i].headmodel)) {
+ Com_sprintf(filename, sizeof(filename), "scripts/%s.vc", headModelName);
+ voiceChatNum = CG_HeadModelVoiceChats(filename);
+ if (voiceChatNum == -1)
+ break;
+ Com_sprintf(headModelVoiceChat[i].headmodel, sizeof ( headModelVoiceChat[i].headmodel ),
+ "%s", headModelName);
+ headModelVoiceChat[i].voiceChatNum = voiceChatNum;
+ return &voiceChatLists[headModelVoiceChat[i].voiceChatNum];
+ }
+ }
}
gender = ci->gender;
for (k = 0; k < 2; k++) {
@@ -758,8 +775,6 @@ typedef struct bufferedVoiceChat_s
} bufferedVoiceChat_t;
bufferedVoiceChat_t voiceChatBuffer[MAX_VOICECHATBUFFER];
-int voiceChatBufferIn, voiceChatBufferOut;
-int voiceChatTime;
/*
=================
@@ -767,6 +782,7 @@ CG_PlayVoiceChat
=================
*/
void CG_PlayVoiceChat( bufferedVoiceChat_t *vchat ) {
+#ifdef MISSIONPACK
// if we are going into the intermission, don't start any voices
if ( cg.intermissionStarted ) {
return;
@@ -779,15 +795,17 @@ void CG_PlayVoiceChat( bufferedVoiceChat_t *vchat ) {
CG_AddToTeamChat( vchat->message );
CG_Printf( "%s\n", vchat->message );
}
- voiceChatBuffer[voiceChatBufferOut].snd = 0;
+ voiceChatBuffer[cg.voiceChatBufferOut].snd = 0;
+#endif
}
/*
=====================
-CG_PlayBufferedVoieChats
+CG_PlayBufferedVoiceChats
=====================
*/
void CG_PlayBufferedVoiceChats( void ) {
+#ifdef MISSIONPACK
if ( voiceChatTime < cg.time ) {
if (voiceChatBufferOut != voiceChatBufferIn && voiceChatBuffer[voiceChatBufferOut].snd) {
//
@@ -797,6 +815,7 @@ void CG_PlayBufferedVoiceChats( void ) {
voiceChatTime = cg.time + 1000;
}
}
+#endif
}
/*
@@ -805,17 +824,19 @@ CG_AddBufferedVoiceChat
=====================
*/
void CG_AddBufferedVoiceChat( bufferedVoiceChat_t *vchat ) {
+#ifdef MISSIONPACK
// if we are going into the intermission, don't start any voices
if ( cg.intermissionStarted ) {
return;
}
- memcpy(&voiceChatBuffer[voiceChatBufferIn], vchat, sizeof(bufferedVoiceChat_t));
- voiceChatBufferIn = (voiceChatBufferIn + 1) % MAX_VOICECHATBUFFER;
- if (voiceChatBufferIn == voiceChatBufferOut) {
- CG_PlayVoiceChat( &voiceChatBuffer[voiceChatBufferOut] );
- voiceChatBufferOut++;
+ memcpy(&voiceChatBuffer[cg.voiceChatBufferIn], vchat, sizeof(bufferedVoiceChat_t));
+ cg.voiceChatBufferIn = (cg.voiceChatBufferIn + 1) % MAX_VOICECHATBUFFER;
+ if (cg.voiceChatBufferIn == cg.voiceChatBufferOut) {
+ CG_PlayVoiceChat( &voiceChatBuffer[cg.voiceChatBufferOut] );
+ cg.voiceChatBufferOut++;
}
+#endif
}
/*
@@ -824,6 +845,7 @@ CG_VoiceChatLocal
=================
*/
void CG_VoiceChatLocal( int mode, qboolean voiceOnly, int clientNum, int color, const char *cmd ) {
+#ifdef MISSIONPACK
char *chat;
voiceChatList_t *voiceChatList;
clientInfo_t *ci;
@@ -863,6 +885,7 @@ void CG_VoiceChatLocal( int mode, qboolean voiceOnly, int clientNum, int color,
CG_AddBufferedVoiceChat(&vchat);
}
}
+#endif
}
/*
@@ -871,6 +894,7 @@ CG_VoiceChat
=================
*/
void CG_VoiceChat( int mode ) {
+#ifdef MISSIONPACK
const char *cmd;
int clientNum, color;
qboolean voiceOnly;
@@ -889,6 +913,7 @@ void CG_VoiceChat( int mode ) {
}
CG_VoiceChatLocal( mode, voiceOnly, clientNum, color, cmd );
+#endif
}
/*
diff --git a/src/cgame/cg_snapshot.c b/src/cgame/cg_snapshot.c
index fdee86eb..d172803f 100644
--- a/src/cgame/cg_snapshot.c
+++ b/src/cgame/cg_snapshot.c
@@ -37,9 +37,11 @@ CG_ResetEntity
==================
*/
static void CG_ResetEntity( centity_t *cent ) {
- // if an event is set, assume it is new enough to use
- // if the event had timed out, it would have been cleared
- cent->previousEvent = 0;
+ // if the previous snapshot this entity was updated in is at least
+ // an event window back in time then we can reset the previous event
+ if ( cent->snapShotTime < cg.time - EVENT_VALID_MSEC ) {
+ cent->previousEvent = 0;
+ }
cent->trailTime = cg.snap->serverTime;
@@ -162,6 +164,9 @@ static void CG_TransitionSnapshot( void ) {
for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
cent = &cg_entities[ cg.snap->entities[ i ].number ];
CG_TransitionEntity( cent );
+
+ // remember time of snapshot this entity was last updated in
+ cent->snapShotTime = cg.snap->serverTime;
}
cg.nextSnap = NULL;
diff --git a/src/cgame/cg_syscalls.asm b/src/cgame/cg_syscalls.asm
index 51cfa6ad..b13b028f 100644
--- a/src/cgame/cg_syscalls.asm
+++ b/src/cgame/cg_syscalls.asm
@@ -82,8 +82,13 @@ equ trap_CIN_SetExtents -79
equ trap_R_RemapShader -80
equ trap_S_AddRealLoopingSound -81
equ trap_S_StopLoopingSound -82
-equ trap_R_AddAdditiveLightToScene -86
-
+equ trap_CM_TempCapsuleModel -83
+equ trap_CM_CapsuleTrace -84
+equ trap_CM_TransformedCapsuleTrace -85
+equ trap_R_AddAdditiveLightToScene -86
+equ trap_GetEntityToken -87
+equ trap_R_AddPolysToScene -88
+equ trap_R_inPVS -89
equ memset -101
equ memcpy -102
diff --git a/src/cgame/cg_syscalls.c b/src/cgame/cg_syscalls.c
index 818a21d5..d1d962f4 100644
--- a/src/cgame/cg_syscalls.c
+++ b/src/cgame/cg_syscalls.c
@@ -135,6 +135,10 @@ clipHandle_t trap_CM_TempBoxModel( const vec3_t mins, const vec3_t maxs ) {
return syscall( CG_CM_TEMPBOXMODEL, mins, maxs );
}
+clipHandle_t trap_CM_TempCapsuleModel( const vec3_t mins, const vec3_t maxs ) {
+ return syscall( CG_CM_TEMPCAPSULEMODEL, mins, maxs );
+}
+
int trap_CM_PointContents( const vec3_t p, clipHandle_t model ) {
return syscall( CG_CM_POINTCONTENTS, p, model );
}
@@ -149,6 +153,12 @@ void trap_CM_BoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
syscall( CG_CM_BOXTRACE, results, start, end, mins, maxs, model, brushmask );
}
+void trap_CM_CapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
+ const vec3_t mins, const vec3_t maxs,
+ clipHandle_t model, int brushmask ) {
+ syscall( CG_CM_CAPSULETRACE, results, start, end, mins, maxs, model, brushmask );
+}
+
void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs,
clipHandle_t model, int brushmask,
@@ -156,6 +166,13 @@ void trap_CM_TransformedBoxTrace( trace_t *results, const vec3_t start, const ve
syscall( CG_CM_TRANSFORMEDBOXTRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
}
+void trap_CM_TransformedCapsuleTrace( trace_t *results, const vec3_t start, const vec3_t end,
+ const vec3_t mins, const vec3_t maxs,
+ clipHandle_t model, int brushmask,
+ const vec3_t origin, const vec3_t angles ) {
+ syscall( CG_CM_TRANSFORMEDCAPSULETRACE, results, start, end, mins, maxs, model, brushmask, origin, angles );
+}
+
int trap_CM_MarkFragments( int numPoints, const vec3_t *points,
const vec3_t projection,
int maxPoints, vec3_t pointBuffer,
@@ -239,6 +256,10 @@ void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *
syscall( CG_R_ADDPOLYTOSCENE, hShader, numVerts, verts );
}
+void trap_R_AddPolysToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num ) {
+ syscall( CG_R_ADDPOLYSTOSCENE, hShader, numVerts, verts, num );
+}
+
int trap_R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ) {
return syscall( CG_R_LIGHTFORPOINT, point, ambientLight, directedLight, lightDir );
}
@@ -248,7 +269,7 @@ void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g
}
void trap_R_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
- syscall( CG_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
+ syscall( CG_R_ADDADDITIVELIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
}
void trap_R_RenderScene( const refdef_t *fd ) {
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index aad94541..90a2a5e9 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -957,6 +957,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
if ( !cg.hyperspace ) {
CG_AddPacketEntities(); // adter calcViewValues, so predicted player state is correct
CG_AddMarks();
+ CG_AddParticles ();
CG_AddLocalEntities();
}
CG_AddViewWeapon( &cg.predictedPlayerState );
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index 7640fb0c..3654aeba 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -185,41 +185,26 @@ CG_RailTrail
*/
void CG_RailTrail( vec3_t start, vec3_t end )
{
+ vec3_t axis[36], move, move2, next_move, vec, temp;
+ float len;
+ int i, j, skip;
+
localEntity_t *le;
refEntity_t *re;
- //
- // rings
- //
- le = CG_AllocLocalEntity();
- re = &le->refEntity;
-
- le->leType = LE_FADE_RGB;
- le->startTime = cg.time;
- le->endTime = cg.time + cg_railTrailTime.value;
- le->lifeRate = 1.0 / ( le->endTime - le->startTime );
-
- re->shaderTime = cg.time / 1000.0f;
- re->reType = RT_RAIL_RINGS;
- re->customShader = cgs.media.railRingsShader;
-
- VectorCopy( start, re->origin );
- VectorCopy( end, re->oldorigin );
-
- // nudge down a bit so it isn't exactly in center
- re->origin[2] -= 8;
- re->oldorigin[2] -= 8;
-
- le->color[0] = 0.75f;
- le->color[1] = 0.75f;
- le->color[2] = 0.75f;
- le->color[3] = 1.0f;
-
- AxisClear( re->axis );
-
- //
- // core
- //
+#define RADIUS 4
+#define ROTATION 1
+#define SPACING 5
+
+ start[2] -= 4;
+ VectorCopy (start, move);
+ VectorSubtract (end, start, vec);
+ len = VectorNormalize (vec);
+ PerpendicularVector(temp, vec);
+ for (i = 0 ; i < 36; i++) {
+ RotatePointAroundVector(axis[i], vec, temp, i * 10);//banshee 2.4 was 10
+ }
+
le = CG_AllocLocalEntity();
re = &le->refEntity;
@@ -235,16 +220,73 @@ void CG_RailTrail( vec3_t start, vec3_t end )
VectorCopy( start, re->origin );
VectorCopy( end, re->oldorigin );
- // nudge down a bit so it isn't exactly in center
- re->origin[2] -= 8;
- re->oldorigin[2] -= 8;
+ re->shaderRGBA[0] = 255;
+ re->shaderRGBA[1] = 255;
+ re->shaderRGBA[2] = 255;
+ re->shaderRGBA[3] = 255;
- le->color[0] = 0.75f;
- le->color[1] = 0.75f;
- le->color[2] = 0.75f;
+ le->color[0] = 0.75f;
+ le->color[1] = 0.75f;
+ le->color[2] = 0.75f;
le->color[3] = 1.0f;
AxisClear( re->axis );
+
+ VectorMA(move, 20, vec, move);
+ VectorCopy(move, next_move);
+ VectorScale (vec, SPACING, vec);
+
+ if (cg_oldRail.integer != 0) {
+ // nudge down a bit so it isn't exactly in center
+ re->origin[2] -= 8;
+ re->oldorigin[2] -= 8;
+ return;
+ }
+ skip = -1;
+
+ j = 18;
+ for (i = 0; i < len; i += SPACING) {
+ if (i != skip) {
+ skip = i + SPACING;
+ le = CG_AllocLocalEntity();
+ re = &le->refEntity;
+ le->leFlags = LEF_PUFF_DONT_SCALE;
+ le->leType = LE_MOVE_SCALE_FADE;
+ le->startTime = cg.time;
+ le->endTime = cg.time + (i>>1) + 600;
+ le->lifeRate = 1.0 / (le->endTime - le->startTime);
+
+ re->shaderTime = cg.time / 1000.0f;
+ re->reType = RT_SPRITE;
+ re->radius = 1.1f;
+ re->customShader = cgs.media.railRingsShader;
+
+ re->shaderRGBA[0] = 255;
+ re->shaderRGBA[1] = 255;
+ re->shaderRGBA[2] = 255;
+ re->shaderRGBA[3] = 255;
+
+ le->color[0] = 0.75f;
+ le->color[1] = 0.75f;
+ le->color[2] = 0.75f;
+ le->color[3] = 1.0f;
+
+ le->pos.trType = TR_LINEAR;
+ le->pos.trTime = cg.time;
+
+ VectorCopy( move, move2);
+ VectorMA(move2, RADIUS , axis[j], move2);
+ VectorCopy(move2, le->pos.trBase);
+
+ le->pos.trDelta[0] = axis[j][0]*6;
+ le->pos.trDelta[1] = axis[j][1]*6;
+ le->pos.trDelta[2] = axis[j][2]*6;
+ }
+
+ VectorAdd (move, vec, move);
+
+ j = j + ROTATION < 36 ? j + ROTATION : (j + ROTATION) % 36;
+ }
}
/*
@@ -262,6 +304,10 @@ static void CG_RocketTrail( centity_t *ent, const weaponInfo_t *wi ) {
vec3_t up;
localEntity_t *smoke;
+ if ( cg_noProjectileTrail.integer ) {
+ return;
+ }
+
up[0] = 0;
up[1] = 0;
up[2] = 0;
@@ -312,6 +358,102 @@ static void CG_RocketTrail( centity_t *ent, const weaponInfo_t *wi ) {
/*
==========================
+CG_PlasmaTrail
+==========================
+*/
+static void CG_PlasmaTrail( centity_t *cent, const weaponInfo_t *wi ) {
+ localEntity_t *le;
+ refEntity_t *re;
+ entityState_t *es;
+ vec3_t velocity, xvelocity, origin;
+ vec3_t offset, xoffset;
+ vec3_t v[3];
+ int t, startTime, step;
+
+ float waterScale = 1.0f;
+
+ if ( cg_noProjectileTrail.integer || cg_oldPlasma.integer ) {
+ return;
+ }
+
+ step = 50;
+
+ es = &cent->currentState;
+ startTime = cent->trailTime;
+ t = step * ( (startTime + step) / step );
+
+ BG_EvaluateTrajectory( &es->pos, cg.time, origin );
+
+ le = CG_AllocLocalEntity();
+ re = &le->refEntity;
+
+ velocity[0] = 60 - 120 * crandom();
+ velocity[1] = 40 - 80 * crandom();
+ velocity[2] = 100 - 200 * crandom();
+
+ le->leType = LE_MOVE_SCALE_FADE;
+ le->leFlags = LEF_TUMBLE;
+ le->leBounceSoundType = LEBS_NONE;
+ le->leMarkType = LEMT_NONE;
+
+ le->startTime = cg.time;
+ le->endTime = le->startTime + 600;
+
+ le->pos.trType = TR_GRAVITY;
+ le->pos.trTime = cg.time;
+
+ AnglesToAxis( cent->lerpAngles, v );
+
+ offset[0] = 2;
+ offset[1] = 2;
+ offset[2] = 2;
+
+ xoffset[0] = offset[0] * v[0][0] + offset[1] * v[1][0] + offset[2] * v[2][0];
+ xoffset[1] = offset[0] * v[0][1] + offset[1] * v[1][1] + offset[2] * v[2][1];
+ xoffset[2] = offset[0] * v[0][2] + offset[1] * v[1][2] + offset[2] * v[2][2];
+
+ VectorAdd( origin, xoffset, re->origin );
+ VectorCopy( re->origin, le->pos.trBase );
+
+ if ( CG_PointContents( re->origin, -1 ) & CONTENTS_WATER ) {
+ waterScale = 0.10f;
+ }
+
+ xvelocity[0] = velocity[0] * v[0][0] + velocity[1] * v[1][0] + velocity[2] * v[2][0];
+ xvelocity[1] = velocity[0] * v[0][1] + velocity[1] * v[1][1] + velocity[2] * v[2][1];
+ xvelocity[2] = velocity[0] * v[0][2] + velocity[1] * v[1][2] + velocity[2] * v[2][2];
+ VectorScale( xvelocity, waterScale, le->pos.trDelta );
+
+ AxisCopy( axisDefault, re->axis );
+ re->shaderTime = cg.time / 1000.0f;
+ re->reType = RT_SPRITE;
+ re->radius = 0.25f;
+ re->customShader = cgs.media.railRingsShader;
+ le->bounceFactor = 0.3f;
+
+ re->shaderRGBA[0] = wi->flashDlightColor[0] * 63;
+ re->shaderRGBA[1] = wi->flashDlightColor[1] * 63;
+ re->shaderRGBA[2] = wi->flashDlightColor[2] * 63;
+ re->shaderRGBA[3] = 63;
+
+ le->color[0] = wi->flashDlightColor[0] * 0.2;
+ le->color[1] = wi->flashDlightColor[1] * 0.2;
+ le->color[2] = wi->flashDlightColor[2] * 0.2;
+ le->color[3] = 0.25f;
+
+ le->angles.trType = TR_LINEAR;
+ le->angles.trTime = cg.time;
+ le->angles.trBase[0] = rand()&31;
+ le->angles.trBase[1] = rand()&31;
+ le->angles.trBase[2] = rand()&31;
+ le->angles.trDelta[0] = 1;
+ le->angles.trDelta[1] = 0.5;
+ le->angles.trDelta[2] = 0;
+
+}
+
+/*
+==========================
CG_GrappleTrail
==========================
*/
@@ -490,7 +632,7 @@ void CG_RegisterWeapon( int weaponNum ) {
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/lightning/lg_hum.wav", qfalse );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/lightning/lg_fire.wav", qfalse );
- cgs.media.lightningShader = trap_R_RegisterShader( "lightningBolt");
+ cgs.media.lightningShader = trap_R_RegisterShader( "lightningBoltNew");
cgs.media.lightningExplosionModel = trap_R_RegisterModel( "models/weaphits/crackle.md3" );
cgs.media.sfx_lghit1 = trap_S_RegisterSound( "sound/weapons/lightning/lg_hit.wav", qfalse );
cgs.media.sfx_lghit2 = trap_S_RegisterSound( "sound/weapons/lightning/lg_hit2.wav", qfalse );
@@ -580,10 +722,12 @@ void CG_RegisterWeapon( int weaponNum ) {
break;
case WP_PLASMAGUN:
+ weaponInfo->missileTrailFunc = CG_PlasmaTrail;
weaponInfo->missileSound = trap_S_RegisterSound( "sound/weapons/plasma/lasfly.wav", qfalse );
MAKERGB( weaponInfo->flashDlightColor, 0.6f, 0.6f, 1.0f );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/plasma/hyprbf1a.wav", qfalse );
cgs.media.plasmaExplosionShader = trap_R_RegisterShader( "plasmaExplosion" );
+ cgs.media.railRingsShader = trap_R_RegisterShader( "railDisc" );
break;
case WP_RAILGUN:
@@ -644,6 +788,10 @@ void CG_RegisterItemVisuals( int itemNum ) {
gitem_t *item;
int i;
+ if ( itemNum < 0 || itemNum >= bg_numItems ) {
+ CG_Error( "CG_RegisterItemVisuals: itemNum %d out of range [0-%d]", itemNum, bg_numItems-1 );
+ }
+
itemInfo = &cg_items[ itemNum ];
if ( itemInfo->registered ) {
return;
@@ -796,9 +944,37 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
memset( &beam, 0, sizeof( beam ) );
- // find muzzle point for this frame
- VectorCopy( cent->lerpOrigin, muzzlePoint );
- AngleVectors( cent->lerpAngles, forward, NULL, NULL );
+ // CPMA "true" lightning
+ if ((cent->currentState.number == cg.predictedPlayerState.clientNum) && (cg_trueLightning.value != 0)) {
+ vec3_t angle;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ float a = cent->lerpAngles[i] - cg.refdefViewAngles[i];
+ if (a > 180) {
+ a -= 360;
+ }
+ if (a < -180) {
+ a += 360;
+ }
+
+ angle[i] = cg.refdefViewAngles[i] + a * (1.0 - cg_trueLightning.value);
+ if (angle[i] < 0) {
+ angle[i] += 360;
+ }
+ if (angle[i] > 360) {
+ angle[i] -= 360;
+ }
+ }
+
+ AngleVectors(angle, forward, NULL, NULL );
+ VectorCopy(cent->lerpOrigin, muzzlePoint );
+// VectorCopy(cg.refdef.vieworg, muzzlePoint );
+ } else {
+ // !CPMA
+ AngleVectors( cent->lerpAngles, forward, NULL, NULL );
+ VectorCopy(cent->lerpOrigin, muzzlePoint );
+ }
// FIXME: crouch
muzzlePoint[2] += DEFAULT_VIEWHEIGHT;
@@ -1070,9 +1246,9 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
clientInfo_t *ci;
ci = &cgs.clientinfo[ cent->currentState.clientNum ];
- flash.shaderRGBA[0] = 255 * ci->color[0];
- flash.shaderRGBA[1] = 255 * ci->color[1];
- flash.shaderRGBA[2] = 255 * ci->color[2];
+ flash.shaderRGBA[0] = 255 * ci->color1[0];
+ flash.shaderRGBA[1] = 255 * ci->color1[1];
+ flash.shaderRGBA[2] = 255 * ci->color1[2];
}
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
@@ -1586,6 +1762,8 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
qboolean alphaFade;
qboolean isSprite;
int duration;
+ vec3_t sprOrg;
+ vec3_t sprVel;
mark = 0;
radius = 32;
@@ -1637,6 +1815,13 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
lightColor[0] = 1;
lightColor[1] = 0.75;
lightColor[2] = 0.0;
+ if (cg_oldRocket.integer == 0) {
+ // explosion sprite animation
+ VectorMA( origin, 24, dir, sprOrg );
+ VectorScale( dir, 64, sprVel );
+
+ CG_ParticleExplosion( "explode1", sprOrg, sprVel, 1400, 20, 30 );
+ }
break;
case WP_SAWBLADE_LAUNCHER:
mod = cgs.media.dishFlashModel;
@@ -1693,9 +1878,9 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
mark = cgs.media.bulletMarkShader;
r = rand() & 3;
- if ( r < 2 ) {
+ if ( r == 0 ) {
sfx = cgs.media.sfx_ric1;
- } else if ( r == 2 ) {
+ } else if ( r == 1 ) {
sfx = cgs.media.sfx_ric2;
} else {
sfx = cgs.media.sfx_ric3;
@@ -1720,7 +1905,7 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
VectorCopy( lightColor, le->lightColor );
if ( weapon == WP_RAILGUN ) {
// colorize with client color
- VectorCopy( cgs.clientinfo[clientNum].color, le->color );
+ VectorCopy( cgs.clientinfo[clientNum].color1, le->color );
}
}
@@ -1732,7 +1917,7 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
float *color;
// colorize with client color
- color = cgs.clientinfo[clientNum].color;
+ color = cgs.clientinfo[clientNum].color2;
CG_ImpactMark( mark, origin, dir, random()*360, color[0],color[1], color[2],1, alphaFade, radius, qfalse );
} else {
CG_ImpactMark( mark, origin, dir, random()*360, 1,1,1,1, alphaFade, radius, qfalse );
@@ -1825,10 +2010,10 @@ static void CG_ShotgunPellet( vec3_t start, vec3_t end, int skipNum ) {
CG_ShotgunPattern
Perform the same traces the server did to locate the
-hit splashes (FIXME: ranom seed isn't synce anymore)
+hit splashes
================
*/
-static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum ) {
+static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, int otherEntNum ) {
int i;
float r, u;
vec3_t end;
@@ -1842,8 +2027,8 @@ static void CG_ShotgunPattern( vec3_t origin, vec3_t origin2, int otherEntNum )
// generate the "random" spread pattern
for ( i = 0 ; i < DEFAULT_SHOTGUN_COUNT ; i++ ) {
- r = crandom() * DEFAULT_SHOTGUN_SPREAD * 16;
- u = crandom() * DEFAULT_SHOTGUN_SPREAD * 16;
+ r = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
+ u = Q_crandom( &seed ) * DEFAULT_SHOTGUN_SPREAD * 16;
VectorMA( origin, 8192 * 16, forward, end);
VectorMA (end, r, right, end);
VectorMA (end, u, up, end);
@@ -1875,7 +2060,7 @@ void CG_ShotgunFire( entityState_t *es ) {
CG_SmokePuff( v, up, 32, 1, 1, 1, 0.33f, 900, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.shotgunSmokePuffShader );
}
}
- CG_ShotgunPattern( es->pos.trBase, es->origin2, es->otherEntityNum );
+ CG_ShotgunPattern( es->pos.trBase, es->origin2, es->eventParm, es->otherEntityNum );
}
/*
diff --git a/src/game/bg_lib.c b/src/game/bg_lib.c
index 45bb3618..53f08ee5 100644
--- a/src/game/bg_lib.c
+++ b/src/game/bg_lib.c
@@ -72,7 +72,11 @@ static const char rcsid[] =
"$Id$";
#endif /* LIBC_SCCS and not lint */
-//typedef int cmp_t(const void *, const void *);
+// bk001127 - needed for DLL's
+#if !defined( Q3_VM )
+typedef int cmp_t(const void *, const void *);
+#endif
+
static char* med3(char *, char *, char *, cmp_t *);
static void swapfunc(char *, char *, int, int);
@@ -215,6 +219,9 @@ loop: SWAPINIT(a, es);
// this file is excluded from release builds because of intrinsics
+// bk001211 - gcc errors on compiling strcpy: parse error before `__extension__'
+#if defined ( Q3_VM )
+
size_t strlen( const char *string ) {
const char *s;
@@ -288,7 +295,12 @@ char *strstr( const char *string, const char *strCharSet ) {
return (char *)0;
}
-#if !defined ( _MSC_VER ) && !defined ( __linux__ )
+#endif // bk001211
+
+// bk001120 - presumably needed for Mac
+//#if !defined(_MSC_VER) && !defined(__linux__)
+// bk001127 - undid undo
+#if defined ( Q3_VM )
int tolower( int c ) {
if ( c >= 'A' && c <= 'Z' ) {
@@ -777,9 +789,14 @@ double atan2( double y, double x ) {
#endif
+#ifdef Q3_VM
+// bk001127 - guarded this tan replacement
+// ld: undefined versioned symbol name tan@@GLIBC_2.0
double tan( double x ) {
return sin(x) / cos(x);
}
+#endif
+
static int randSeed = 0;
@@ -864,7 +881,7 @@ double _atof( const char **stringPtr ) {
const char *string;
float sign;
float value;
- int c;
+ int c = '0'; // bk001211 - uninitialized use possible
string = *stringPtr;
@@ -929,7 +946,11 @@ double _atof( const char **stringPtr ) {
}
-#if !defined( _MSC_VER ) && !defined( __linux__ )
+// bk001120 - presumably needed for Mac
+//#if !defined ( _MSC_VER ) && ! defined ( __linux__ )
+
+// bk001127 - undid undo
+#if defined ( Q3_VM )
int atoi( const char *string ) {
int sign;
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index ba21ca43..89a8d6ba 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -3282,8 +3282,16 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const pla
}
return qtrue;*/
- case IT_BAD:
- Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: IT_BAD" );
+ case IT_BAD:
+ Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: IT_BAD" );
+
+ default:
+#ifndef Q3_VM
+#ifndef NDEBUG // bk0001204
+ Com_Printf("BG_CanItemBeGrabbed: unknown enum %d\n", item->giType );
+#endif
+#endif
+ break;
}
return qfalse;
@@ -3612,7 +3620,7 @@ void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean
if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) {
ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
}
- seq = (ps->entityEventSequence-1) & (MAX_PS_EVENTS-1);
+ seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
s->eventParm = ps->eventParms[ seq ];
ps->entityEventSequence++;
@@ -3709,7 +3717,7 @@ void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s
if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) {
ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
}
- seq = (ps->entityEventSequence-1) & (MAX_PS_EVENTS-1);
+ seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
s->eventParm = ps->eventParms[ seq ];
ps->entityEventSequence++;
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 0860b5e2..a67d516f 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -101,8 +101,9 @@
#define CS_PLAYERS (CS_SOUNDS+MAX_SOUNDS)
#define CS_PRECACHES (CS_PLAYERS+MAX_CLIENTS)
#define CS_LOCATIONS (CS_PRECACHES+MAX_CLIENTS)
+#define CS_PARTICLES (CS_LOCATIONS+MAX_LOCATIONS)
-#define CS_MAX (CS_LOCATIONS+MAX_LOCATIONS)
+#define CS_MAX (CS_PARTICLES+MAX_LOCATIONS)
#if (CS_MAX) > MAX_CONFIGSTRINGS
#error overflow: (CS_MAX) > MAX_CONFIGSTRINGS
@@ -206,7 +207,10 @@ typedef struct {
// callbacks to test the world
// these will be different functions during game and cgame
+ /*void (*trace)( trace_t *results, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask );*/
void (*trace)( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask );
+
+
int (*pointcontents)( const vec3_t point, int passEntityNum );
} pmove_t;
@@ -283,6 +287,7 @@ typedef enum {
#define EF_DEAD 0x00000001 // don't draw a foe marker over players with EF_DEAD
#define EF_TELEPORT_BIT 0x00000004 // toggled every time the origin abruptly changes
#define EF_AWARD_EXCELLENT 0x00000008 // draw an excellent sprite
+#define EF_PLAYER_EVENT 0x00000010
#define EF_BOUNCE 0x00000010 // for missiles
#define EF_BOUNCE_HALF 0x00000020 // for missiles
#define EF_AWARD_GAUNTLET 0x00000040 // draw a gauntlet sprite
@@ -427,6 +432,8 @@ typedef enum
#define EV_EVENT_BIT2 0x00000200
#define EV_EVENT_BITS (EV_EVENT_BIT1|EV_EVENT_BIT2)
+#define EVENT_VALID_MSEC 300
+
typedef enum {
EV_NONE,
@@ -595,14 +602,12 @@ typedef enum {
LEGS_TURN,
-#ifdef NEW_ANIMS
TORSO_GETFLAG,
TORSO_GUARDBASE,
TORSO_PATROL,
TORSO_FOLLOWME,
TORSO_AFFIRMATIVE,
TORSO_NEGATIVE,
-#endif
MAX_PLAYER_ANIMATIONS,
diff --git a/src/game/bg_slidemove.c b/src/game/bg_slidemove.c
index f0791ed3..c53d0fe0 100644
--- a/src/game/bg_slidemove.c
+++ b/src/game/bg_slidemove.c
@@ -241,6 +241,7 @@ void PM_StepSlideMove( qboolean gravity ) {
// float down_dist, up_dist;
// vec3_t delta, delta2;
vec3_t up, down;
+ float stepSize;
VectorCopy (pm->ps->origin, start_o);
VectorCopy (pm->ps->velocity, start_v);
@@ -266,7 +267,7 @@ void PM_StepSlideMove( qboolean gravity ) {
up[2] += STEPSIZE;
// test the player position if they were a stepheight higher
- pm->trace (&trace, up, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
+ pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
if ( trace.allsolid ) {
if ( pm->debugLevel ) {
Com_Printf("%i:bend can't step\n", c_pmove);
@@ -274,8 +275,9 @@ void PM_StepSlideMove( qboolean gravity ) {
return; // can't step up
}
+ stepSize = trace.endpos[2] - start_o[2];
// try slidemove from this position
- VectorCopy (up, pm->ps->origin);
+ VectorCopy (trace.endpos, pm->ps->origin);
VectorCopy (start_v, pm->ps->velocity);
PM_SlideMove( gravity );
diff --git a/src/game/g_active.c b/src/game/g_active.c
index ca7552a3..2a9e27fb 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -677,6 +677,41 @@ static int StuckInOtherClient(gentity_t *ent) {
/*
==============
+SendPendingPredictableEvents
+==============
+*/
+void SendPendingPredictableEvents( playerState_t *ps ) {
+ gentity_t *t;
+ int event, seq;
+ int extEvent, number;
+
+ // if there are still events pending
+ if ( ps->entityEventSequence < ps->eventSequence ) {
+ // create a temporary entity for this event which is sent to everyone
+ // except the client who generated the event
+ seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
+ event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
+ // set external event to zero before calling BG_PlayerStateToEntityState
+ extEvent = ps->externalEvent;
+ ps->externalEvent = 0;
+ // create temporary entity for event
+ t = G_TempEntity( ps->origin, event );
+ number = t->s.number;
+ BG_PlayerStateToEntityState( ps, &t->s, qtrue );
+ t->s.number = number;
+ t->s.eType = ET_EVENTS + event;
+ t->s.eFlags |= EF_PLAYER_EVENT;
+ t->s.otherEntityNum = ps->clientNum;
+ // send to everyone except the client who generated the event
+ t->r.svFlags |= SVF_NOTSINGLECLIENT;
+ t->r.singleClient = ps->clientNum;
+ // set back external event
+ ps->externalEvent = extEvent;
+ }
+}
+
+/*
+==============
ClientThink
This will be called once for each client frame, which will
@@ -927,6 +962,8 @@ void ClientThink_real( gentity_t *ent ) {
else {
BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue );
}
+ SendPendingPredictableEvents( &ent->client->ps );
+
if( !( ent->client->ps.eFlags & EF_FIRING ) )
client->fireHeld = qfalse; // for grapple
if( !( ent->client->ps.eFlags & EF_FIRING2 ) )
@@ -1163,6 +1200,7 @@ void ClientEndFrame( gentity_t *ent ) {
else {
BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue );
}
+ SendPendingPredictableEvents( &ent->client->ps );
// set the bit for the reachability area the client is currently in
// i = trap_AAS_PointReachabilityAreaIndex( ent->client->ps.origin );
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 38afac43..17928cc3 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -840,6 +840,7 @@ ForceClientSkin
Forces a client's skin (for teamplay)
===========
*/
+/*
static void ForceClientSkin( gclient_t *client, char *model, const char *skin ) {
char *p;
@@ -850,7 +851,7 @@ static void ForceClientSkin( gclient_t *client, char *model, const char *skin )
Q_strcat(model, MAX_QPATH, "/");
Q_strcat(model, MAX_QPATH, skin);
}
-
+*/
/*
===========
@@ -954,6 +955,7 @@ void ClientUserinfoChanged( int clientNum ) {
char oldname[MAX_STRING_CHARS];
gclient_t *client;
char c1[MAX_INFO_STRING];
+ char c2[MAX_INFO_STRING];
char redTeam[MAX_INFO_STRING];
char blueTeam[MAX_INFO_STRING];
char userinfo[MAX_INFO_STRING];
@@ -1015,20 +1017,21 @@ void ClientUserinfoChanged( int clientNum ) {
s = BG_FindModelNameForClass( client->pers.pclass );
Q_strncpyz( model, s, sizeof( model ) );
+/*
// team
switch( client->sess.sessionTeam ) {
case TEAM_HUMANS:
- ForceClientSkin(client, model, "red");
+ //ForceClientSkin(client, model, "red");
break;
case TEAM_DROIDS:
- ForceClientSkin(client, model, "blue");
+ //ForceClientSkin(client, model, "blue");
break;
}
if ( g_gametype.integer >= GT_TEAM && client->sess.sessionTeam == TEAM_SPECTATOR ) {
// don't ever use a default skin in teamplay, it would just waste memory
- ForceClientSkin(client, model, "red");
+ //ForceClientSkin(client, model, "red");
}
-
+*/
// teamInfo
@@ -1045,20 +1048,21 @@ void ClientUserinfoChanged( int clientNum ) {
teamLeader = client->sess.teamLeader;
// colors
- strcpy(c1, Info_ValueForKey( userinfo, "color" ));
+ strcpy(c1, Info_ValueForKey( userinfo, "color1" ));
+ strcpy(c2, Info_ValueForKey( userinfo, "color2" ));
strcpy(redTeam, "humans");
strcpy(blueTeam, "droids");
// send over a subset of the userinfo keys so other clients can
// print scoreboards, display models, and play custom sounds
if ( ent->r.svFlags & SVF_BOT ) {
- s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
- client->pers.netname, client->sess.sessionTeam, model, model, c1,
+ s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
+ client->pers.netname, client->sess.sessionTeam, model, model, c1, c2,
client->pers.maxHealth, client->sess.wins, client->sess.losses,
Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader );
} else {
- s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
- client->pers.netname, client->sess.sessionTeam, model, model, redTeam, blueTeam, c1,
+ s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
+ client->pers.netname, client->sess.sessionTeam, model, model, redTeam, blueTeam, c1, c2,
client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader);
}
@@ -1243,7 +1247,6 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn ) {
int ammoIndex, ammoSubIndex;
int teamLocal;
int accuracy_hits, accuracy_shots;
- int savedEvents[MAX_PS_EVENTS];
int eventSequence;
char userinfo[MAX_INFO_STRING];
vec3_t bodyMaxs, classMins, up = { 0, 0, 1 };
@@ -1322,10 +1325,6 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn ) {
for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
persistant[i] = client->ps.persistant[i];
}
- // also save the predictable events otherwise we might get double or dropped events
- for (i = 0; i < MAX_PS_EVENTS; i++) {
- savedEvents[i] = client->ps.events[i];
- }
eventSequence = client->ps.eventSequence;
memset (client, 0, sizeof(*client));
@@ -1338,9 +1337,6 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn ) {
for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
client->ps.persistant[i] = persistant[i];
}
- for (i = 0; i < MAX_PS_EVENTS; i++) {
- client->ps.events[i] = savedEvents[i];
- }
client->ps.eventSequence = eventSequence;
if( client->sess.sessionTeam == TEAM_SPECTATOR )
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index bba155fc..ca4cc109 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -756,6 +756,9 @@ static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, cons
if (!other->client) {
return;
}
+ if ( other->client->pers.connected != CON_CONNECTED ) {
+ return;
+ }
if ( mode == SAY_TEAM && !OnSameTeam(ent, other) ) {
return;
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 6404e6b6..1a5c96e6 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -38,7 +38,6 @@
#define INFINITE 1000000
#define FRAMETIME 100 // msec
-#define EVENT_VALID_MSEC 300
#define CARNAGE_REWARD_TIME 3000
#define REWARD_SPRITE_TIME 2000
@@ -380,7 +379,7 @@ typedef struct armourRegion_s
// this structure is cleared as each map is entered
//
#define MAX_SPAWN_VARS 64
-#define MAX_SPAWN_VARS_CHARS 2048
+#define MAX_SPAWN_VARS_CHARS 4096
typedef struct {
struct gclient_s *clients; // [maxclients]
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 3d5fb1e8..06505ce5 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -87,7 +87,7 @@ vmCvar_t g_rankings;
vmCvar_t g_listEntity;
-cvarTable_t gameCvarTable[] = {
+static cvarTable_t gameCvarTable[] = {
// don't override the cheat state set by the system
{ &g_cheats, "sv_cheats", "", 0, 0, qfalse },
@@ -98,7 +98,8 @@ cvarTable_t gameCvarTable[] = {
{ NULL, "sv_mapname", "", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
// latched vars
- { &g_gametype, "g_gametype", "0", CVAR_SERVERINFO | CVAR_LATCH, 0, qfalse },
+ { &g_gametype, "g_gametype", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse },
+
{ &g_maxclients, "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse },
{ &g_maxGameClients, "g_maxGameClients", "0", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE, 0, qfalse },
@@ -157,7 +158,7 @@ cvarTable_t gameCvarTable[] = {
{ &g_rankings, "g_rankings", "0", 0, 0, qfalse}
};
-int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] );
+static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] );
void G_InitGame( int levelTime, int randomSeed, int restart );
@@ -1212,7 +1213,9 @@ Append information about this game to the log file
void LogExit( const char *string ) {
int i, numSorted;
gclient_t *cl;
+#ifdef MISSIONPACK // bk001205
qboolean won = qtrue;
+#endif
G_LogPrintf( "Exit: %s\n", string );
diff --git a/src/game/g_misc.c b/src/game/g_misc.c
index 6508d357..a874d5b0 100644
--- a/src/game/g_misc.c
+++ b/src/game/g_misc.c
@@ -197,8 +197,14 @@ void locateCamera( gentity_t *ent ) {
ent->s.frame = 75;
}
- // set to 0 for no rotation at all
- ent->s.powerups = 1;
+ // swing camera ?
+ if ( owner->spawnflags & 4 ) {
+ // set to 0 for no rotation at all
+ ent->s.powerups = 0;
+ }
+ else {
+ ent->s.powerups = 1;
+ }
// clientNum holds the rotate offset
ent->s.clientNum = owner->s.clientNum;
@@ -237,7 +243,8 @@ void SP_misc_portal_surface(gentity_t *ent) {
}
}
-/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate
+/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate noswing
+
The target for a misc_portal_director. You can set either angles or target another entity to determine the direction of view.
"roll" an angle modifier to orient the camera around the target vector;
*/
diff --git a/src/game/g_mover.c b/src/game/g_mover.c
index b4cd4b45..bbc03db6 100644
--- a/src/game/g_mover.c
+++ b/src/game/g_mover.c
@@ -75,6 +75,43 @@ gentity_t *G_TestEntityPosition( gentity_t *ent ) {
return NULL;
}
+/*
+================
+G_CreateRotationMatrix
+================
+*/
+void G_CreateRotationMatrix(vec3_t angles, vec3_t matrix[3]) {
+ AngleVectors(angles, matrix[0], matrix[1], matrix[2]);
+ VectorInverse(matrix[1]);
+}
+
+/*
+================
+G_TransposeMatrix
+================
+*/
+void G_TransposeMatrix(vec3_t matrix[3], vec3_t transpose[3]) {
+ int i, j;
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ transpose[i][j] = matrix[j][i];
+ }
+ }
+}
+
+/*
+================
+G_RotatePoint
+================
+*/
+void G_RotatePoint(vec3_t point, vec3_t matrix[3]) {
+ vec3_t tvec;
+
+ VectorCopy(point, tvec);
+ point[0] = DotProduct(matrix[0], tvec);
+ point[1] = DotProduct(matrix[1], tvec);
+ point[2] = DotProduct(matrix[2], tvec);
+}
/*
==================
@@ -84,7 +121,7 @@ Returns qfalse if the move is blocked
==================
*/
qboolean G_TryPushingEntity( gentity_t *check, gentity_t *pusher, vec3_t move, vec3_t amove ) {
- vec3_t forward, right, up;
+ vec3_t matrix[3], transpose[3];
vec3_t org, org2, move2;
gentity_t *block;
@@ -108,28 +145,28 @@ qboolean G_TryPushingEntity( gentity_t *check, gentity_t *pusher, vec3_t move,
}
pushed_p++;
- // we need this for pushing things later
- VectorSubtract (vec3_origin, amove, org);
- AngleVectors (org, forward, right, up);
-
- // try moving the contacted entity
- VectorAdd (check->s.pos.trBase, move, check->s.pos.trBase);
- if (check->client) {
- // make sure the client's view rotates when on a rotating mover
- check->client->ps.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]);
- }
-
- // figure movement due to the pusher's amove
- VectorSubtract (check->s.pos.trBase, pusher->r.currentOrigin, org);
- org2[0] = DotProduct (org, forward);
- org2[1] = -DotProduct (org, right);
- org2[2] = DotProduct (org, up);
- VectorSubtract (org2, org, move2);
- VectorAdd (check->s.pos.trBase, move2, check->s.pos.trBase);
- if ( check->client ) {
- VectorAdd (check->client->ps.origin, move, check->client->ps.origin);
- VectorAdd (check->client->ps.origin, move2, check->client->ps.origin);
- }
+ // try moving the contacted entity
+ // figure movement due to the pusher's amove
+ G_CreateRotationMatrix( amove, transpose );
+ G_TransposeMatrix( transpose, matrix );
+ if ( check->client ) {
+ VectorSubtract (check->client->ps.origin, pusher->r.currentOrigin, org);
+ }
+ else {
+ VectorSubtract (check->s.pos.trBase, pusher->r.currentOrigin, org);
+ }
+ VectorCopy( org, org2 );
+ G_RotatePoint( org2, matrix );
+ VectorSubtract (org2, org, move2);
+ // add movement
+ VectorAdd (check->s.pos.trBase, move, check->s.pos.trBase);
+ VectorAdd (check->s.pos.trBase, move2, check->s.pos.trBase);
+ if ( check->client ) {
+ VectorAdd (check->client->ps.origin, move, check->client->ps.origin);
+ VectorAdd (check->client->ps.origin, move2, check->client->ps.origin);
+ // make sure the client's view rotates when on a rotating mover
+ check->client->ps.delta_angles[YAW] += ANGLE2SHORT(amove[YAW]);
+ }
// may have pushed them off an edge
if ( check->s.groundEntityNum != pusher->s.number ) {
diff --git a/src/game/g_public.h b/src/game/g_public.h
index 87b3800b..28456f3b 100644
--- a/src/game/g_public.h
+++ b/src/game/g_public.h
@@ -39,7 +39,13 @@
#define SVF_PORTAL 0x00000040 // merge a second pvs at origin2 into snapshots
#define SVF_USE_CURRENT_ORIGIN 0x00000080 // entity->r.currentOrigin instead of entity->s.origin
// for link position (missiles and movers)
-#define SVF_SINGLECLIENT 0x00000100 // only send to a single client
+#define SVF_SINGLECLIENT 0x00000100 // only send to a single client (entityShared_t->singleClient)
+#define SVF_NOSERVERINFO 0x00000200 // don't send CS_SERVERINFO updates to this client
+ // so that it can be updated for ping tools without
+ // lagging clients
+#define SVF_CAPSULE 0x00000400 // use capsule for collision detection instead of bbox
+#define SVF_NOTSINGLECLIENT 0x00000800 // send entity to everyone but one client
+ // (entityShared_t->singleClient)
//===============================================================
@@ -211,6 +217,9 @@ typedef enum {
G_REAL_TIME,
G_SNAPVECTOR,
+ G_TRACECAPSULE, // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask );
+ G_ENTITY_CONTACTCAPSULE, // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent );
+
BOTLIB_SETUP = 200, // ( void );
BOTLIB_SHUTDOWN, // ( void );
BOTLIB_LIBVAR_SET,
diff --git a/src/game/g_session.c b/src/game/g_session.c
index ce93b4d5..7695c96e 100644
--- a/src/game/g_session.c
+++ b/src/game/g_session.c
@@ -75,18 +75,28 @@ void G_ReadSessionData( gclient_t *client ) {
char s[MAX_STRING_CHARS];
const char *var;
+ // bk001205 - format
+ int teamLeader;
+ int spectatorState;
+ int sessionTeam;
+
var = va( "session%i", client - level.clients );
trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );
sscanf( s, "%i %i %i %i %i %i %i",
- &client->sess.sessionTeam,
+ &sessionTeam,
&client->sess.spectatorTime,
- &client->sess.spectatorState,
+ &spectatorState,
&client->sess.spectatorClient,
&client->sess.wins,
&client->sess.losses,
- &client->sess.teamLeader
+ &teamLeader
);
+
+ // bk001205 - format issues
+ client->sess.sessionTeam = (team_t)sessionTeam;
+ client->sess.spectatorState = (spectatorState_t)spectatorState;
+ client->sess.teamLeader = (qboolean)teamLeader;
}
diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c
index 8bb3f39f..8f74a4ee 100644
--- a/src/game/g_spawn.c
+++ b/src/game/g_spawn.c
@@ -195,8 +195,6 @@ void SP_team_CTF_blueplayer( gentity_t *ent );
void SP_team_CTF_redspawn( gentity_t *ent );
void SP_team_CTF_bluespawn( gentity_t *ent );
-void SP_item_botroam( gentity_t *ent ) {};
-
spawn_t spawns[] = {
// info entities don't do anything at all, but provide positional
// information for things controlled by other processes
@@ -268,8 +266,6 @@ spawn_t spawns[] = {
{"team_CTF_redspawn", SP_team_CTF_redspawn},
{"team_CTF_bluespawn", SP_team_CTF_bluespawn},
- {"item_botroam", SP_item_botroam},
-
{0, 0}
};
@@ -449,6 +445,12 @@ void G_SpawnGEntityFromSpawnVars( void ) {
}
}
+ G_SpawnInt( "notq3a", "0", &i );
+ if ( i ) {
+ G_FreeEntity( ent );
+ return;
+ }
+
if( G_SpawnString( "gametype", NULL, &value ) ) {
if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) {
gametypeName = gametypeNames[g_gametype.integer];
@@ -484,7 +486,8 @@ char *G_AddSpawnVarToken( const char *string ) {
l = strlen( string );
if ( level.numSpawnVarChars + l + 1 > MAX_SPAWN_VARS_CHARS ) {
- G_Error( "G_AddSpawnVarToken: MAX_SPAWN_VARS" );
+ G_Error( "G_AddSpawnVarToken: MAX_SPAWN_CHARS" );
+
}
dest = level.spawnVarChars + level.numSpawnVarChars;
diff --git a/src/game/g_svcmds.c b/src/game/g_svcmds.c
index f74c2e56..21eafeed 100644
--- a/src/game/g_svcmds.c
+++ b/src/game/g_svcmds.c
@@ -469,7 +469,7 @@ qboolean ConsoleCommand( void ) {
}
if (Q_stricmp (cmd, "listip") == 0) {
- trap_SendConsoleCommand( EXEC_INSERT, "g_banIPs\n" );
+ trap_SendConsoleCommand( EXEC_NOW, "g_banIPs\n" );
return qtrue;
}
diff --git a/src/game/g_syscalls.asm b/src/game/g_syscalls.asm
index 2d9c4f89..e997e293 100644
--- a/src/game/g_syscalls.asm
+++ b/src/game/g_syscalls.asm
@@ -43,6 +43,8 @@ equ trap_DebugPolygonCreate -40
equ trap_DebugPolygonDelete -41
equ trap_RealTime -42
equ trap_SnapVector -43
+equ trap_TraceCapsule -44
+equ trap_EntityContactCapsule -45
equ memset -101
@@ -215,3 +217,8 @@ equ trap_AAS_AlternativeRouteGoals -576
equ trap_AAS_PredictRoute -577
equ trap_AAS_PointReachabilityAreaIndex -578
+equ trap_BotLibLoadSource -579
+equ trap_BotLibFreeSource -580
+equ trap_BotLibReadToken -581
+equ trap_BotLibSourceFileAndLine -582
+
diff --git a/src/game/g_syscalls.c b/src/game/g_syscalls.c
index c08295d8..00b9477d 100644
--- a/src/game/g_syscalls.c
+++ b/src/game/g_syscalls.c
@@ -148,6 +148,10 @@ void trap_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const
syscall( G_TRACE, results, start, mins, maxs, end, passEntityNum, contentmask );
}
+void trap_TraceCapsule( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ) {
+ syscall( G_TRACECAPSULE, results, start, mins, maxs, end, passEntityNum, contentmask );
+}
+
int trap_PointContents( const vec3_t point, int passEntityNum ) {
return syscall( G_POINT_CONTENTS, point, passEntityNum );
}
@@ -186,6 +190,9 @@ qboolean trap_EntityContact( const vec3_t mins, const vec3_t maxs, const gentity
return syscall( G_ENTITY_CONTACT, mins, maxs, ent );
}
+qboolean trap_EntityContactCapsule( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ) {
+ return syscall( G_ENTITY_CONTACTCAPSULE, mins, maxs, ent );
+}
int trap_BotAllocateClient( void ) {
return syscall( G_BOT_ALLOCATE_CLIENT );
}
@@ -763,3 +770,19 @@ void trap_BotResetWeaponState(int weaponstate) {
int trap_GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child) {
return syscall( BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION, numranks, ranks, parent1, parent2, child );
}
+
+int trap_PC_LoadSource( const char *filename ) {
+ return syscall( BOTLIB_PC_LOAD_SOURCE, filename );
+}
+
+int trap_PC_FreeSource( int handle ) {
+ return syscall( BOTLIB_PC_FREE_SOURCE, handle );
+}
+
+int trap_PC_ReadToken( int handle, pc_token_t *pc_token ) {
+ return syscall( BOTLIB_PC_READ_TOKEN, handle, pc_token );
+}
+
+int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ) {
+ return syscall( BOTLIB_PC_SOURCE_FILE_AND_LINE, handle, filename, line );
+}
diff --git a/src/game/g_team.c b/src/game/g_team.c
index ce9263d1..528e82a4 100644
--- a/src/game/g_team.c
+++ b/src/game/g_team.c
@@ -703,7 +703,7 @@ int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
AddScore (player, CTF_RETURN_FLAG_ASSIST_BONUS);
other->client->pers.teamState.assists++;
}
- if (player->client->pers.teamState.lastfraggedcarrier +
+ else if (player->client->pers.teamState.lastfraggedcarrier +
CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time) {
AddScore(player, CTF_FRAG_CARRIER_ASSIST_BONUS);
other->client->pers.teamState.assists++;
diff --git a/src/game/g_utils.c b/src/game/g_utils.c
index a72f57ad..07d0adf4 100644
--- a/src/game/g_utils.c
+++ b/src/game/g_utils.c
@@ -59,7 +59,7 @@ void AddRemap(const char *oldShader, const char *newShader, float timeOffset) {
}
const char *BuildShaderStateConfig() {
- static char buff[MAX_STRING_CHARS];
+ static char buff[MAX_STRING_CHARS*4];
char out[(MAX_QPATH * 2) + 5];
int i;
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 7a9c7779..3532e3d0 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -32,7 +32,7 @@
static vec3_t forward, right, up;
static vec3_t muzzle;
-#define NUM_NAILSHOTS 10
+#define NUM_NAILSHOTS 15
/*
================
diff --git a/src/game/q_shared.h b/src/game/q_shared.h
index 6faaced2..26678db0 100644
--- a/src/game/q_shared.h
+++ b/src/game/q_shared.h
@@ -1198,7 +1198,7 @@ typedef enum _flag_status {
#define MAX_GLOBAL_SERVERS 2048
#define MAX_OTHER_SERVERS 128
-#define MAX_PINGREQUESTS 16
+#define MAX_PINGREQUESTS 32
#define MAX_SERVERSTATUSREQUESTS 16
#define SAY_ALL 0