From de7fdcb516d39976affbea3b69b5a32e11fc4a6a Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Fri, 3 Aug 2001 01:18:00 +0000 Subject: 1.29h upgrade.. oooo particles hehehehehehe --- Makefile | 1 + src/cgame/cg_consolecmds.c | 6 + src/cgame/cg_draw.c | 62 +++++----- src/cgame/cg_drawtools.c | 13 +- src/cgame/cg_event.c | 4 +- src/cgame/cg_local.h | 42 ++++++- src/cgame/cg_main.c | 107 +++++++++-------- src/cgame/cg_players.c | 65 +++++++--- src/cgame/cg_predict.c | 2 +- src/cgame/cg_public.h | 8 ++ src/cgame/cg_servercmds.c | 87 +++++++++----- src/cgame/cg_snapshot.c | 11 +- src/cgame/cg_syscalls.asm | 9 +- src/cgame/cg_syscalls.c | 23 +++- src/cgame/cg_view.c | 1 + src/cgame/cg_weapons.c | 293 ++++++++++++++++++++++++++++++++++++--------- src/game/bg_lib.c | 29 ++++- src/game/bg_misc.c | 16 ++- src/game/bg_public.h | 11 +- src/game/bg_slidemove.c | 6 +- src/game/g_active.c | 38 ++++++ src/game/g_client.c | 32 +++-- src/game/g_cmds.c | 3 + src/game/g_local.h | 3 +- src/game/g_main.c | 9 +- src/game/g_misc.c | 13 +- src/game/g_mover.c | 83 +++++++++---- src/game/g_public.h | 11 +- src/game/g_session.c | 16 ++- src/game/g_spawn.c | 13 +- src/game/g_svcmds.c | 2 +- src/game/g_syscalls.asm | 7 ++ src/game/g_syscalls.c | 23 ++++ src/game/g_team.c | 2 +- src/game/g_utils.c | 2 +- src/game/g_weapon.c | 2 +- src/game/q_shared.h | 2 +- 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, ¢->pe.torso.pitchAngle, ¢->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 .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 .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; @@ -310,6 +356,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 = ¢->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 @@ -675,6 +675,41 @@ static int StuckInOtherClient(gentity_t *ent) { //TA: rip bots //void BotTestSolid(vec3_t origin); +/* +============== +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 @@ -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 -- cgit