diff --git a/reaction/cgame/cg_consolecmds.c b/reaction/cgame/cg_consolecmds.c index 51a9da0d..5f502f13 100644 --- a/reaction/cgame/cg_consolecmds.c +++ b/reaction/cgame/cg_consolecmds.c @@ -147,91 +147,6 @@ static void CG_Bandage_f (void) { } -/* -================= -CG_ReloadReset_f - -Elder: reset reload depressed flag -================= -*/ -static void CG_ReloadReset_f (void) { - //CG_Printf("Releasing Reload\n"); - cg.rq3_reloadDown = qfalse; -} - - -/* -================= -CG_Reload_f - -Elder: reset local zoom, then proceed with server action -Note: most of this doesn't work if it's a +button style -================= -*/ -static void CG_Reload_f (void) { - centity_t *cent; - cent = &cg_entities[cg.snap->ps.clientNum]; - - if ( !cg.snap ) { - //CG_Printf("No snapshot: normally exiting\n"); - return; - } - - // if we are going into the intermission, don't do anything - if ( cg.intermissionStarted ) { - return; - } - - ///Elder: spectator? - if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) { - return; - } - - //Elder: don't allow reloading when in the middle of bursts - if (cg.snap->ps.stats[STAT_BURST] > 0) - return; - - if (cg.rq3_reloadDown == qtrue) - { - //CG_Printf("Reload down... exiting\n"); - return; - } - - cg.rq3_reloadDown = qtrue; - - //Elder: prevent "reloading" when dead hehe - if ( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) { - CG_Printf("Nothing to reload - you are dead.\n"); - return; - } - - //Elder: don't allow reloading until the weapon is free - //Don't cut-off here because we want to check for fast-reloads - //if (cg.snap->ps.weaponTime > 0) - //return; - - //Elder: added to prevent bandaging while reloading - if ( (cg.snap->ps.stats[STAT_RQ3] & RQ3_BANDAGE_WORK) == RQ3_BANDAGE_WORK) { - CG_Printf("You'll get to your weapon when you are finished bandaging!\n"); - return; - } - - //Elder: no clips, or full chamber means no reload - //CG_Printf("currentState.weapon: %d, clipamount: %d\n", cent->currentState.weapon, ClipAmountForAmmo(cent->currentState.weapon)); - if (cg.snap->ps.stats[STAT_CLIPS] && - cg.snap->ps.ammo[cent->currentState.weapon] < ClipAmountForAmmo(cent->currentState.weapon) ) { - //cg.zoomed = 0; - //cg.zoomLevel = 0; - } - - //Elder: reset "no ammo" switch in view - if (cg.snap->ps.weapon == WP_SSG3000 && cg.zoomFirstReturn == -1) - cg.zoomFirstReturn = 0; - - //CG_Printf("Sending reload command to server\n"); - trap_SendClientCommand("reload"); -} - /* ================= CG_SizeUp_f @@ -758,14 +673,7 @@ static consoleCommand_t commands[] = { { "dropitem", CG_DropItem_f }, { "dropweapon", CG_DropWeapon_f }, // Elder: added to reset zoom then goto server { "bandage", CG_Bandage_f }, // Elder: added to reset zoom then goto server - { "+reload", CG_Reload_f }, // Elder: added to reset zoom then goto server - { "-reload", CG_ReloadReset_f}, // Elder: added to stop auto-throttle { "specialweapon", CG_SpecialWeapon_f }, // Elder: select special weapon - //Elder: added for manual sv_floodProtect check - //{ "messagemode", CG_Say_f }, - //{ "messagemode2", CG_SayTeam_f }, - //{ "say", CG_Say_f }, - //{ "say_team", CG_SayTeam_f }, { "tell_target", CG_TellTarget_f }, { "tell_attacker", CG_TellAttacker_f }, { "vtell_target", CG_VoiceTellTarget_f }, @@ -875,7 +783,6 @@ void CG_InitConsoleCommands( void ) { trap_AddCommand ("stats"); trap_AddCommand ("teamtask"); trap_AddCommand ("loaddefered"); // spelled wrong, but not changing for demo - trap_AddCommand ("reload"); trap_AddCommand ("opendoor"); trap_AddCommand ("bandage"); //trap_AddCommand ("drop"); // XRAY FMJ weap drop cmd - Elder: not used diff --git a/reaction/cgame/cg_ents.c b/reaction/cgame/cg_ents.c index 51449f14..3cf25add 100644 --- a/reaction/cgame/cg_ents.c +++ b/reaction/cgame/cg_ents.c @@ -5,6 +5,7 @@ #include "cg_local.h" static void CG_LaserSight( centity_t *cent ); +static void CG_Dlight( centity_t *cent ); /* ====================== @@ -147,7 +148,7 @@ static void CG_EntityEffects( centity_t *cent ) { // constant light glow - if ( cent->currentState.constantLight ) { + if ( cent->currentState.constantLight && cent->currentState.eType != ET_DLIGHT) { int cl; int i, r, g, b; @@ -156,6 +157,7 @@ static void CG_EntityEffects( centity_t *cent ) { g = ( cl >> 8 ) & 255; b = ( cl >> 16 ) & 255; i = ( ( cl >> 24 ) & 255 ) * 4; + trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b ); } @@ -255,7 +257,21 @@ static void CG_Item( centity_t *cent ) { memset( &ent, 0, sizeof( ent ) ); ent.reType = RT_SPRITE; VectorCopy( cent->lerpOrigin, ent.origin ); - ent.radius = 14; + // Elder: lower them slightly + ent.origin[2] -= 6; + // Elder: make auto-sprites smaller, especially grenades and knifes + if (item->giType == IT_WEAPON) + { + if (item->giTag == WP_GRENADE || item->giTag == WP_KNIFE) + ent.radius = 4; + else + ent.radius = 14; + } + else if (item->giType == IT_HOLDABLE) + ent.radius = 10; + else + ent.radius = 6; + //ent.radius = 14; ent.customShader = cg_items[es->modelindex].icon; ent.shaderRGBA[0] = 255; ent.shaderRGBA[1] = 255; @@ -382,10 +398,13 @@ static void CG_Item( centity_t *cent ) { frac = 1.0; } + // Elder: special items and ammo should have minimum light too // items without glow textures need to keep a minimum light value // so they are always visible if ( ( item->giType == IT_WEAPON ) || - ( item->giType == IT_ARMOR ) ) { + ( item->giType == IT_ARMOR ) || + ( item->giType == IT_AMMO) || + ( item->giType == IT_HOLDABLE) ) { ent.renderfx |= RF_MINLIGHT; } @@ -1008,6 +1027,7 @@ static void CG_TeamBase( centity_t *cent ) { #endif } + /* =============== CG_AddCEntity @@ -1072,7 +1092,9 @@ static void CG_AddCEntity( centity_t *cent ) { //if (!cg_RQ3_laserAssist.integer || cent->currentState.clientNum != cg.snap->ps.clientNum) CG_LaserSight( cent ); break; - + case ET_DLIGHT: + CG_Dlight( cent ); + break; } } @@ -1161,3 +1183,37 @@ static void CG_LaserSight( centity_t *cent ) { trap_R_AddLightToScene(ent.origin, 200, 1, 1, 1); } } + + +/* +================= +CG_Dlight +Added by Elder. + +Use sparingly. +================= +*/ +static void CG_Dlight( centity_t *cent ) { + int cl; + float i, r, g, b; + + cl = cent->currentState.constantLight; + r = ( cl & 255 ) / 255.0f; + g = ( ( cl >> 8 ) & 255 ) / 255.0f; + b = ( ( cl >> 16 ) & 255 ) / 255.0f; + i = ( cl >> 24 ) & 255 * 4; + + if ( cent->currentState.eventParm & DLIGHT_FLICKER ) + i += rand() % 100 - 50; + + if ( cent->currentState.eventParm & DLIGHT_PULSE ) + i *= 1.0f + sin( 2 * M_PI * cg.time / 1000.0f ); + + if ( cent->currentState.eventParm & DLIGHT_ADDITIVE) + trap_R_AddAdditiveLightToScene(cent->lerpOrigin, i, r, g, b); + else + trap_R_AddLightToScene(cent->lerpOrigin, i, r, g, b); + + //CG_Printf("cgame: (%f %f %f) %f\n", r, g, b, i ); +} + diff --git a/reaction/cgame/cg_event.c b/reaction/cgame/cg_event.c index 97da0633..94a3f16f 100644 --- a/reaction/cgame/cg_event.c +++ b/reaction/cgame/cg_event.c @@ -1778,9 +1778,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); //Elder: TODO: change to appropriate weapon "in" sound - trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); - //Elder: removed - //CG_RQ3_Zoom(0); + //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); @@ -1994,6 +1992,13 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) { CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_METAL); break; + case EV_BULLET_HIT_GLASS: + DEBUGNAME("EV_BULLET_HIT_GLASS"); + ByteToDir( es->eventParm, dir ); + CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_GLASS); + break; + + case EV_BULLET_HIT_KEVLAR: DEBUGNAME("EV_BULLET_HIT_KEVLAR"); ByteToDir( es->eventParm, dir ); diff --git a/reaction/cgame/cg_local.h b/reaction/cgame/cg_local.h index f49fc1f8..1628752a 100644 --- a/reaction/cgame/cg_local.h +++ b/reaction/cgame/cg_local.h @@ -117,7 +117,9 @@ typedef enum { typedef enum { IMPACTSOUND_DEFAULT, IMPACTSOUND_METAL, - IMPACTSOUND_FLESH + IMPACTSOUND_FLESH, + // rq3 onwards + IMPACTSOUND_GLASS } impactSound_t; @@ -399,15 +401,24 @@ typedef struct { // Elder: maximum sizes #define MAX_RELOAD_SOUNDS 5 #define MAX_OTHER_SOUNDS 5 -// Circular, singly-linked list + +#define MAX_ANIM_SOUNDS 16 +// Singly-linked list + struct sfxSyncInfo_s { int frame; sfxHandle_t sound; - struct sfxSyncInfo_s *next; + qboolean played; + //struct sfxSyncInfo_s *next; }; typedef struct sfxSyncInfo_s sfxSyncInfo_t; +typedef struct sfxWeapTiming_s { + int numFrames; + sfxSyncInfo_t sfxInfo[MAX_ANIM_SOUNDS]; +} sfxWeapTiming_t; + // each WP_* weapon enum has an associated weaponInfo_t // that contains media references necessary to present the @@ -447,16 +458,19 @@ typedef struct weaponInfo_s { float trailRadius; float wiTrailTime; + sfxHandle_t readySound; sfxHandle_t firingSound; + sfxWeapTiming_t animationSounds[MAX_ANIM_SOUNDS]; // Elder: sounds to queue + /* sfxSyncInfo_t activateSound[2]; // last one is an endpoint node sfxSyncInfo_t disarmSound[2]; // last one is an endpoint node sfxSyncInfo_t reloadSounds[MAX_RELOAD_SOUNDS]; sfxSyncInfo_t otherSounds[MAX_OTHER_SOUNDS]; - + */ // Deprecated sfxHandle_t reloadSound1; // Elder: for various reload stages such as sfxHandle_t reloadSound2; // Clip in, clip out, sliding, sliding bolt, @@ -528,6 +542,8 @@ typedef struct { // is rendering at. int oldTime; // time at last frame, used for missile trails and prediction checking + int cvarCheckTime; // Elder: used for cvar cheat interval cycling + int physicsTime; // either cg.snap->time or cg.nextSnap->time int timelimitWarnings; // 5 min, 1 min, overtime @@ -668,7 +684,6 @@ typedef struct { //Elder: added for alpha pain blend int rq3_trueDamage; //Q3 doesn't hold the actual damage amount in cg.damageValue float rq3_blendTime; //How long we take to fade out - qboolean rq3_reloadDown; //Flag to check if reload is pressed // status bar head float headYaw; @@ -714,8 +729,9 @@ typedef struct { qboolean rq3_irvision; // Elder: enabled IR vision int akimboFlash; // Alternate between two tags for flash (0 or 1) - sfxSyncInfo_t *curSyncSound; // Shifts after a sound is played + sfxSyncInfo_t curSyncSound; // Shifts after a sound is played + } cg_t; @@ -871,6 +887,7 @@ typedef struct { // Elder: rq3 marks qhandle_t slashMarkShader; + qhandle_t glassMarkShader; // powerup shaders qhandle_t quadShader; @@ -975,6 +992,10 @@ typedef struct { sfxHandle_t sfx_metalric1; sfxHandle_t sfx_metalric2; sfxHandle_t sfx_metalric3; + // Elder: Glass ricochet sounds + sfxHandle_t sfx_glassric1; + sfxHandle_t sfx_glassric2; + sfxHandle_t sfx_glassric3; sfxHandle_t sfx_railg; sfxHandle_t sfx_rockexp; @@ -1306,6 +1327,11 @@ extern vmCvar_t cg_RQ3_ssgColorR; extern vmCvar_t cg_RQ3_ssgColorG; extern vmCvar_t cg_RQ3_ssgColorB; extern vmCvar_t cg_RQ3_ssgColorA; +//Elder: SSG unique sensitivities +extern vmCvar_t cg_RQ3_ssgSensitivityAuto; +extern vmCvar_t cg_RQ3_ssgSensitivity2x; +extern vmCvar_t cg_RQ3_ssgSensitivity4x; +extern vmCvar_t cg_RQ3_ssgSensitivity6x; //Elder: smoke puffs, sparks, etc. extern vmCvar_t cg_RQ3_impactEffects; //Elder: toggle client-side laser drawing diff --git a/reaction/cgame/cg_main.c b/reaction/cgame/cg_main.c index 567221bb..31f5dca5 100644 --- a/reaction/cgame/cg_main.c +++ b/reaction/cgame/cg_main.c @@ -151,6 +151,11 @@ vmCvar_t cg_RQ3_ssgColorR; vmCvar_t cg_RQ3_ssgColorG; vmCvar_t cg_RQ3_ssgColorB; vmCvar_t cg_RQ3_ssgColorA; +//Elder: SSG unique sensitivities +vmCvar_t cg_RQ3_ssgSensitivityAuto; +vmCvar_t cg_RQ3_ssgSensitivity2x; +vmCvar_t cg_RQ3_ssgSensitivity4x; +vmCvar_t cg_RQ3_ssgSensitivity6x; //Elder: smoke puffs, sparks, etc. vmCvar_t cg_RQ3_impactEffects; //Elder: toggle client-side laser drawing @@ -324,6 +329,10 @@ static cvarTable_t cvarTable[] = { // bk001129 { &cg_RQ3_flash, "cg_RQ3_flash", "1", CVAR_ARCHIVE }, { &cg_RQ3_painblend, "cg_RQ3_painblend", "1", CVAR_ARCHIVE }, { &cg_RQ3_ssgZoomAssist, "cg_RQ3_ssgZoomAssist", "1", CVAR_ARCHIVE }, + { &cg_RQ3_ssgSensitivityAuto, "cg_RQ3_ssgSensitivityAuto", "1", CVAR_ARCHIVE }, + { &cg_RQ3_ssgSensitivity2x, "cg_RQ3_ssgSensitivity2x", "0.4", CVAR_ARCHIVE }, + { &cg_RQ3_ssgSensitivity4x, "cg_RQ3_ssgSensitivity4x", "0.2", CVAR_ARCHIVE }, + { &cg_RQ3_ssgSensitivity6x, "cg_RQ3_ssgSensitivity6x", "0.1", CVAR_ARCHIVE }, { &cg_RQ3_ssgColorR, "cg_RQ3_ssgColorR", "0.0", CVAR_ARCHIVE }, { &cg_RQ3_ssgColorG, "cg_RQ3_ssgColorG", "1.0", CVAR_ARCHIVE }, { &cg_RQ3_ssgColorB, "cg_RQ3_ssgColorB", "0.0", CVAR_ARCHIVE }, @@ -791,6 +800,9 @@ static void CG_RegisterSounds( void ) { cgs.media.sfx_metalric1 = trap_S_RegisterSound ("sound/world/impactmetal01.wav", qfalse); cgs.media.sfx_metalric2 = trap_S_RegisterSound ("sound/world/impactmetal02.wav", qfalse); cgs.media.sfx_metalric3 = trap_S_RegisterSound ("sound/world/impactmetal03.wav", qfalse); + cgs.media.sfx_glassric1 = trap_S_RegisterSound ("sound/world/impactglass01.wav", qfalse); + cgs.media.sfx_glassric2 = trap_S_RegisterSound ("sound/world/impactglass02.wav", qfalse); + cgs.media.sfx_glassric3 = trap_S_RegisterSound ("sound/world/impactglass03.wav", qfalse); cgs.media.sfx_railg = trap_S_RegisterSound ("sound/weapons/railgun/railgf1a.wav", qfalse); cgs.media.sfx_rockexp = trap_S_RegisterSound ("sound/weapons/rocket/rocklx1a.wav", qfalse); @@ -1157,6 +1169,7 @@ static void CG_RegisterGraphics( void ) { cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" ); // Elder: added cgs.media.slashMarkShader = trap_R_RegisterShader( "gfx/damage/slash_mrk" ); + cgs.media.glassMarkShader = trap_R_RegisterShader( "gfx/damage/glass_mrk" ); // register the inline models cgs.numInlineModels = trap_CM_NumInlineModels(); diff --git a/reaction/cgame/cg_players.c b/reaction/cgame/cg_players.c index fcf59d6b..9e630167 100644 --- a/reaction/cgame/cg_players.c +++ b/reaction/cgame/cg_players.c @@ -1329,7 +1329,7 @@ void CG_WeaponAnimation( centity_t *cent, int *weaponOld, int *weapon, float *we CG_RunLerpFrame( ci, ¢->pe.weapon, cent->currentState.generic1, 1, qtrue ); // QUARANTINE - Debug - Animations - #if 1 + #if 0 if (cg_debugAnim.integer) if(cent->pe.weapon.oldFrame || cent->pe.weapon.frame || cent->pe.weapon.backlerp) { CG_Printf("weaponOld: %i weaponFrame: %i weaponBack: %i\n", diff --git a/reaction/cgame/cg_playerstate.c b/reaction/cgame/cg_playerstate.c index 2e6c61e3..2b3cc259 100644 --- a/reaction/cgame/cg_playerstate.c +++ b/reaction/cgame/cg_playerstate.c @@ -232,8 +232,8 @@ A respawn happened this snapshot ================ */ void CG_Respawn( void ) { - int i=0; - float cvar_val; + //int i=0; + //float cvar_val; // no error decay on player movement cg.thisFrameTeleport = qtrue; @@ -246,9 +246,6 @@ void CG_Respawn( void ) { //Elder: added to reset zoom stuff LOCALLY CG_RQ3_Zoom1x(); - cg.curSyncSound = 0; - - } extern char *eventnames[]; @@ -578,10 +575,12 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) { } // Elder: reset sync sounds + /* if ( ps->weaponstate != ops->weaponstate ) { cg.curSyncSound = 0; } + */ //Elder: grenade message if (ps->weapon == WP_GRENADE && diff --git a/reaction/cgame/cg_view.c b/reaction/cgame/cg_view.c index be6fb986..89cdcf89 100644 --- a/reaction/cgame/cg_view.c +++ b/reaction/cgame/cg_view.c @@ -573,6 +573,8 @@ static int CG_CalcFov( void ) { CG_RQ3_SyncZoom(); //SSG3000 zoom handling +/* + // old code if ( cg.snap->ps.weapon == WP_SSG3000) { //switching zoom @@ -700,6 +702,140 @@ static int CG_CalcFov( void ) { fov_x = fov_x + f * ( zoomFov - fov_x ); } } +*/ + if ( cg.snap->ps.weapon == WP_SSG3000) + { + //switching zoom + if (cg.zoomLevel != cg.lastZoomLevel) + { + fov_x = CG_RQ3_GetLastFov(); + //Get desired zoom FOV based on current FOV + if (cg.zoomLevel == 0) + { + zoomFov = 90; + cg.zoomed = qfalse; + } + else + { + switch ((int)fov_x) + { + case 20: + zoomFov = 10; + cg.zoomed = qtrue; + break; + case 45: + zoomFov = 20; + cg.zoomed = qtrue; + break; + case 90: + zoomFov = 45; + cg.zoomed = qtrue; + break; + case 10: + default: + zoomFov = 90; + cg.zoomed = qfalse; + break; + } + } + + f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; + if ( f > 1.0 || cg.zoomFirstReturn == ZOOM_OUT) + { + //finished zoom switch + cg.lastZoomLevel = cg.zoomLevel; + fov_x = zoomFov; + } + else + fov_x = fov_x + f * ( zoomFov - fov_x ); + } + //Idle state + else if (cg.snap->ps.weaponTime == 0 && cg.snap->ps.weaponstate == WEAPON_READY) + { + fov_x = CG_RQ3_GetFov(); + if (fov_x == 90) + cg.zoomed = qfalse; + else + cg.zoomed = qtrue; + + if (cg.lowAmmoWarning) + cg.zoomFirstReturn = ZOOM_OUTOFAMMO; + else + cg.zoomFirstReturn = ZOOM_IDLE; + } + //Zoom back in after a reload or fire + else if (cg.snap->ps.weaponTime < ZOOM_TIME && + !(cg.snap->ps.weaponstate == WEAPON_DROPPING || + cg.snap->ps.weaponstate == WEAPON_RAISING ) && + cg.snap->ps.stats[STAT_RELOADTIME] < ZOOM_TIME && + !(cg.snap->ps.stats[STAT_RQ3] & RQ3_FASTRELOADS)) + { + if (cg.zoomFirstReturn == ZOOM_OUT) + { + cg.zoomTime = cg.time; + if (cg.lowAmmoWarning) + cg.zoomFirstReturn = ZOOM_OUTOFAMMO; + else + cg.zoomFirstReturn = ZOOM_IDLE; + } + + fov_x = 90; + zoomFov = CG_RQ3_GetFov(); + + if (zoomFov == 90) + cg.zoomed = qfalse; + else + cg.zoomed = qtrue; + + f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; + if ( f > 1.0 ) //|| cg.zoomFirstReturn == ZOOM_OUTOFAMMO) + fov_x = zoomFov; + else + fov_x = fov_x + f * ( zoomFov - fov_x ); + //fov_x = zoomFov + f * ( fov_x - zoomFov ); + } + //first time after a shot, reload, or weapon switch - zoom out + else + { + fov_x = CG_RQ3_GetFov(); + + if (cg.snap->ps.weaponstate == WEAPON_RELOADING && + cg.zoomFirstReturn != ZOOM_OUT) + { + cg.zoomTime = cg.time; + cg.zoomFirstReturn = ZOOM_OUT; + } + else if (cg.zoomFirstReturn == ZOOM_IDLE && + !(cg.snap->ps.weaponstate == WEAPON_DROPPING || cg.snap->ps.weaponstate == WEAPON_RAISING)) + { + cg.zoomTime = cg.time; + cg.zoomFirstReturn = ZOOM_OUT; + } + + + if (cg.zoomFirstReturn == ZOOM_OUTOFAMMO) + { + zoomFov = fov_x; + f = 1.0f; // don't bother zooming out + } + else + { + zoomFov = 90; + f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; + } + + if ( f > 1.0 ) + { + fov_x = zoomFov; + if (fov_x == 90) + cg.zoomed = qfalse; + else + cg.zoomed = qtrue; + } + else + fov_x = fov_x + f * ( zoomFov - fov_x ); + } + } //Using anything but the SSG3000 else { @@ -731,11 +867,27 @@ static int CG_CalcFov( void ) { cg.refdef.fov_y = fov_y; - // user-defined sensitivities! if ( !cg.zoomed ) { cg.zoomSensitivity = 1; } else { - cg.zoomSensitivity = cg.refdef.fov_y / 75.0; + if ( cg_RQ3_ssgSensitivityAuto.integer ) + cg.zoomSensitivity = cg.refdef.fov_y / 75.0; + else + { + // Use user-defined sensitivites + switch ( (int)fov_x ) + { + case 45: + cg.zoomSensitivity = cg_RQ3_ssgSensitivity2x.value; + break; + case 20: + cg.zoomSensitivity = cg_RQ3_ssgSensitivity4x.value; + break; + case 10: + cg.zoomSensitivity = cg_RQ3_ssgSensitivity6x.value; + break; + } + } } return inwater; @@ -1068,8 +1220,12 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo CG_Printf( "cg.clientFrame:%i\n", cg.clientFrame ); } - if ((cg.time - cgs.levelStartTime) / 10000 == 1) + //if ((cg.time - cgs.levelStartTime) / 10000 == 1) + // Elder: working timer implementation + if (cg.time > cg.cvarCheckTime) { + //cg.cvarCheckTime = cg.time + 5000 + rand() % 6000; + cg.cvarCheckTime = cg.time + 10000; //Blaze: Check for invalid video settings. for(i=0;i<30;i++) { @@ -1079,7 +1235,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo //CG_Printf("%s is set to %f\n",cheats[i].cvar, cvar_val); if ( cvar_val < cheats[i].low || cvar_val > cheats[i].high) { - CG_Printf("This server restricts %s to be between %f and %f\n",cheats[i].cvar,cheats[i].low, cheats[i].high); + CG_Printf("This server restricts %s to be between %1.11f and %1.11f\n",cheats[i].cvar,cheats[i].low, cheats[i].high); trap_SendConsoleCommand(va("disconnect\n")); } diff --git a/reaction/cgame/cg_weapons.c b/reaction/cgame/cg_weapons.c index ee6fdcd4..4503bef5 100644 --- a/reaction/cgame/cg_weapons.c +++ b/reaction/cgame/cg_weapons.c @@ -16,16 +16,17 @@ static qboolean CG_ParseWeaponSoundFile( const char *filename, weaponInfo_t *wea int len; int i; char *token; - float fps; +// float fps; int skip; // Elder: What's this for? char text[20000]; fileHandle_t f; - animation_t *animations; - sfxSyncInfo_t *reloadSounds; - + //animation_t *animations; + //sfxSyncInfo_t *reloadSounds; + sfxWeapTiming_t *weapTiming; - animations = weapon->animations; - reloadSounds = weapon->reloadSounds; + //animations = weapon->animations; + //reloadSounds = weapon->reloadSounds; + weapTiming = weapon->animationSounds; // load the file len = trap_FS_FOpenFile( filename, &f, FS_READ ); @@ -44,7 +45,39 @@ static qboolean CG_ParseWeaponSoundFile( const char *filename, weaponInfo_t *wea text_p = text; // Elder: uhh, what was this for? skip = 0; // quite the compiler warning + + for ( i = 0; i < MAX_ANIM_SOUNDS; i++ ) + { + // Grab frame number + token = COM_Parse( &text_p ); + if ( !token ) break; + // Add it to the array + if ( atoi( token ) ) + { + Com_Printf("(%i): %s\n", i, token); + weapTiming->sfxInfo[i].frame = atoi(token); + } + else + break; + //return qfalse; + + // Grab sound file path + token = COM_Parse( &text_p ); + if ( !token ) break; + //return qfalse; + + Com_Printf("(%i): %s\n", i, token); + weapTiming->sfxInfo[i].sound = trap_S_RegisterSound( token, qfalse ); + } + // Store total number + weapTiming->numFrames = i; + Com_Printf("Total Frames: %i\n", weapTiming->numFrames); + + return qtrue; + + // Old crap code + /* // read information for each phase of a reload for ( i = 0 ; i < MAX_RELOAD_SOUNDS ; i++ ) { @@ -130,6 +163,7 @@ static qboolean CG_ParseWeaponSoundFile( const char *filename, weaponInfo_t *wea } return qtrue; + */ } /* [QUARANTINE] - Weapon Animations - CG_ParseWeaponAnimFile @@ -890,9 +924,6 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/mk23/mk23fire.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass; - //weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/mk23/mk23out.wav", qfalse ); - //weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/mk23/mk23in.wav", qfalse ); - //weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/mk23/mk23slide.wav", qfalse ); cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" ); // Load the animation information @@ -909,17 +940,6 @@ void CG_RegisterWeapon( int weaponNum ) { if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) { Com_Printf("Failed to load weapon sound file %s\n", filename); } - else { - // Temporarily print the info - int k; - Com_Printf("Sync Sound Status:\n"); - for (k = 0; k < MAX_RELOAD_SOUNDS; k++) - { - Com_Printf("%i: Frame %i Has sfxHandle: %s\n", - k, weaponInfo->reloadSounds[k].frame, - weaponInfo->reloadSounds[k].sound? "yes":"no"); - } - } } else { @@ -951,8 +971,6 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/m4/m4fire.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass; - //weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/m4/m4out.wav", qfalse ); - //weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/m4/m4in.wav", qfalse ); cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" ); Com_sprintf( filename, sizeof(filename), "models/weapons2/m4/animation.cfg" ); @@ -969,6 +987,7 @@ void CG_RegisterWeapon( int weaponNum ) { } else { Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n"); } + break; case WP_SSG3000: @@ -976,14 +995,21 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 0.5f, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgfire.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass; - weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgbolt.wav", qfalse ); - weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgin.wav", qfalse ); - weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/ssg3000/ssgbolt.wav", qfalse ); cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" ); Com_sprintf( filename, sizeof(filename), "models/weapons2/ssg3000/animation.cfg" ); if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) { Com_Printf("Failed to load weapon animation file %s\n", filename); } + + // Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION + if (weapAnimLoad) { + Com_sprintf( filename, sizeof(filename), "models/weapons2/ssg3000/sound.cfg" ); + if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) { + Com_Printf("Failed to load weapon sound file %s\n", filename); + } + } else { + Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n"); + } break; case WP_MP5: @@ -991,9 +1017,9 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 0.75f, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/mp5/mp5fire.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass; - weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/mp5/mp5out.wav", qfalse ); - weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/mp5/mp5in.wav", qfalse ); - weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/mp5/mp5slide.wav", qfalse ); + //weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/mp5/mp5out.wav", qfalse ); + //weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/mp5/mp5in.wav", qfalse ); + //weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/mp5/mp5slide.wav", qfalse ); cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" ); break; @@ -1004,25 +1030,44 @@ void CG_RegisterWeapon( int weaponNum ) { weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/handcannon/hcfire.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_ShotgunEjectBrass; cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" ); - weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/handcannon/hcopen.wav", qfalse ); - weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/handcannon/hcout.wav", qfalse ); - weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/handcannon/hcclose.wav", qfalse ); Com_sprintf( filename, sizeof(filename), "models/weapons2/handcannon/animation.cfg" ); if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) { Com_Printf("Failed to load weapon animation file %s\n", filename); + weapAnimLoad = qfalse; } + + if (weapAnimLoad) { + Com_sprintf( filename, sizeof(filename), "models/weapons2/handcannon/sound.cfg" ); + if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) { + Com_Printf("Failed to load weapon sound file %s\n", filename); + } + } else { + Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n"); + } + break; case WP_M3: MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 ); weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/m3/m3fire.wav", qfalse ); - weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/m3/m3in.wav", qfalse ); weaponInfo->ejectBrassFunc = CG_ShotgunEjectBrass; + Com_sprintf( filename, sizeof(filename), "models/weapons2/m3/animation.cfg" ); if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) { Com_Printf("Failed to load weapon animation file %s\n", filename); + weapAnimLoad = qfalse; } + + if (weapAnimLoad) { + Com_sprintf( filename, sizeof(filename), "models/weapons2/m3/sound.cfg" ); + if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) { + Com_Printf("Failed to load weapon sound file %s\n", filename); + } + } else { + Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n"); + } + break; case WP_AKIMBO: @@ -1030,10 +1075,6 @@ void CG_RegisterWeapon( int weaponNum ) { MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0.5f ); // Elder: no more pseudo-dual sound needed :) weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/mk23/mk23fire.wav", qfalse ); - //Elder: changed to use pseudo-dual sound - //weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/akimbo/akimbofire.wav", qfalse ); - //weaponInfo->flashSound[1] = trap_S_RegisterSound( "sound/weapons/akimbo/akimbofire.wav", qfalse ); - weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass; cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" ); Com_sprintf( filename, sizeof(filename), "models/weapons2/akimbo/animation.cfg" ); @@ -1051,6 +1092,7 @@ void CG_RegisterWeapon( int weaponNum ) { } else { Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n"); } + break; case WP_GRENADE: @@ -1061,7 +1103,7 @@ void CG_RegisterWeapon( int weaponNum ) { weaponInfo->wiTrailTime = 700; weaponInfo->trailRadius = 32; MAKERGB( weaponInfo->flashDlightColor, 1, 0.70f, 0 ); - weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/grenade/gren_throw.wav", qfalse ); + //weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/grenade/gren_throw.wav", qfalse ); cgs.media.grenadeExplosionShader = trap_R_RegisterShader( "grenadeExplosion" ); // Load the animation information @@ -1070,6 +1112,15 @@ void CG_RegisterWeapon( int weaponNum ) { Com_Printf("Failed to load weapon animation file %s\n", filename); weapAnimLoad = qfalse; } + // Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION + if (weapAnimLoad) { + Com_sprintf( filename, sizeof(filename), "models/weapons2/grenade/sound.cfg" ); + if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) { + Com_Printf("Failed to load weapon sound file %s\n", filename); + } + } else { + Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n"); + } break; default: @@ -1489,33 +1540,47 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent // Temp hack because it isn't fully implemented if ( weapon->item->giTag == WP_PISTOL || weapon->item->giTag == WP_AKIMBO || - weapon->item->giTag == WP_M4) + weapon->item->giTag == WP_M4 || + weapon->item->giTag == WP_M3 || + weapon->item->giTag == WP_HANDCANNON || + weapon->item->giTag == WP_SSG3000 || + weapon->item->giTag == WP_GRENADE) { - if ( ps->weaponstate == WEAPON_RELOADING ) { - if ( !cg.curSyncSound || cg.curSyncSound->frame == 0) - cg.curSyncSound = &weapon->reloadSounds[0]; - } - else if ( ps->weaponstate == WEAPON_RAISING ) { - if ( !cg.curSyncSound || cg.curSyncSound->frame == 0) - cg.curSyncSound = &weapon->activateSound[0]; - } - else if ( ps->weaponstate == WEAPON_DROPPING ) { - if ( !cg.curSyncSound || cg.curSyncSound->frame == 0) - cg.curSyncSound = &weapon->disarmSound[0]; + int i = 0; + qboolean noSound = qfalse; + + while ( gun.frame != weapon->animationSounds->sfxInfo[i].frame ) + { + if ( ++i == weapon->animationSounds->numFrames ) + { + noSound = qtrue; + break; + } } - if (cg.curSyncSound && cg.curSyncSound->frame == gun.frame) { - if ( cg.curSyncSound->sound ) { + // reset the current sound + if (cg.curSyncSound.played && cg.curSyncSound.frame != gun.frame) + cg.curSyncSound.played = qfalse; + + if (!noSound) + { + // copy the struct to reset it + if (cg.curSyncSound.frame != gun.frame ) + cg.curSyncSound = weapon->animationSounds->sfxInfo[i]; + + if (cg.curSyncSound.played == qfalse) + { + cg.curSyncSound.played = qtrue; CG_Printf("Playing a timed sound (%i %i %1.1f)\n", gun.frame, gun.oldframe, gun.backlerp); - trap_S_StartLocalSound ( cg.curSyncSound->sound, CHAN_WEAPON ); - cg.curSyncSound = cg.curSyncSound->next; + trap_S_StartLocalSound ( cg.curSyncSound.sound, CHAN_WEAPON ); } } } } // Elder: break off here so we still have weapon animations on bolt out - if (cg.zoomed) + // Elder: added ps so we see SSG in third-person zoomed + if (cg.zoomed && ps) return; CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups ); @@ -2018,9 +2083,11 @@ void CG_PrevWeapon_f( void ) { //Elder: in the middle of firing, reloading or weapon-switching //cg.snap->ps.weaponstate == WEAPON_RELOADING when it's in + /* if (cg.snap->ps.weaponstate == WEAPON_RELOADING && cg.snap->ps.weaponTime > 0) { return; } + */ //Elder: added //cg.zoomed = qfalse; @@ -2089,9 +2156,11 @@ void CG_SpecialWeapon_f( void ) { //Elder: in the middle of firing, reloading or weapon-switching //cg.snap->ps.weaponstate == WEAPON_RELOADING when it's in + /* if (cg.snap->ps.weaponstate == WEAPON_RELOADING && cg.snap->ps.weaponTime > 0) { return; } + */ cg.weaponSelectTime = cg.time; original = cg.weaponSelect; @@ -2299,10 +2368,12 @@ void CG_Weapon_f( void ) { if (cg.snap->ps.stats[STAT_BURST] > 0) return; + /* //Elder: in the middle of firing, reloading or weapon-switching if (cg.snap->ps.weaponTime > 0 || cg.snap->ps.stats[STAT_RELOADTIME] > 0) { return; } + */ ///Elder: spectator? @@ -2312,6 +2383,11 @@ void CG_Weapon_f( void ) { // Hawkins (give 'weapon' dual meaning) if ( trap_Argc() == 1 ) { + //Elder: in the middle of firing, reloading or weapon-switching + if (cg.snap->ps.weaponTime > 0 || cg.snap->ps.stats[STAT_RELOADTIME] > 0) { + return; + } + if (cg.snap->ps.weapon == WP_SSG3000) { //trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_ITEM, cgs.media.lensSound); trap_S_StartLocalSound( cgs.media.lensSound, CHAN_ITEM); @@ -2777,7 +2853,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, case WP_M4: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; r = rand() & 3; if (soundType == IMPACTSOUND_METAL) @@ -2790,6 +2869,16 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, sfx = cgs.media.sfx_metalric3; } } + else if (soundType == IMPACTSOUND_GLASS) + { + if ( r < 2 ) { + sfx = cgs.media.sfx_glassric1; + } else if ( r == 2 ) { + sfx = cgs.media.sfx_glassric2; + } else { + sfx = cgs.media.sfx_glassric3; + } + } else { if ( r < 2 ) { @@ -2807,7 +2896,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, case WP_PISTOL: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; r = rand() & 3; if (soundType == IMPACTSOUND_METAL) @@ -2820,6 +2912,16 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, sfx = cgs.media.sfx_metalric3; } } + else if (soundType == IMPACTSOUND_GLASS) + { + if ( r < 2 ) { + sfx = cgs.media.sfx_glassric1; + } else if ( r == 2 ) { + sfx = cgs.media.sfx_glassric2; + } else { + sfx = cgs.media.sfx_glassric3; + } + } else { if ( r < 2 ) { @@ -2835,7 +2937,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, case WP_SSG3000: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; r = rand() & 3; if (soundType == IMPACTSOUND_METAL) @@ -2848,6 +2953,16 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, sfx = cgs.media.sfx_metalric3; } } + else if (soundType == IMPACTSOUND_GLASS) + { + if ( r < 2 ) { + sfx = cgs.media.sfx_glassric1; + } else if ( r == 2 ) { + sfx = cgs.media.sfx_glassric2; + } else { + sfx = cgs.media.sfx_glassric3; + } + } else { if ( r < 2 ) { @@ -2863,7 +2978,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, case WP_AKIMBO: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; r = rand() & 3; if (soundType == IMPACTSOUND_METAL) @@ -2876,6 +2994,16 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, sfx = cgs.media.sfx_metalric3; } } + else if (soundType == IMPACTSOUND_GLASS) + { + if ( r < 2 ) { + sfx = cgs.media.sfx_glassric1; + } else if ( r == 2 ) { + sfx = cgs.media.sfx_glassric2; + } else { + sfx = cgs.media.sfx_glassric3; + } + } else { if ( r < 2 ) { @@ -2893,7 +3021,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, case WP_MP5: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; r = rand() & 3; if (soundType == IMPACTSOUND_METAL) @@ -2906,6 +3037,16 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, sfx = cgs.media.sfx_metalric3; } } + else if (soundType == IMPACTSOUND_GLASS) + { + if ( r < 2 ) { + sfx = cgs.media.sfx_glassric1; + } else if ( r == 2 ) { + sfx = cgs.media.sfx_glassric2; + } else { + sfx = cgs.media.sfx_glassric3; + } + } else { if ( r == 0 ) { @@ -2922,14 +3063,20 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, case WP_M3: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; sfx = 0; radius = 4; break; case WP_HANDCANNON: mod = cgs.media.bulletFlashModel; shader = cgs.media.bulletExplosionShader; - mark = cgs.media.bulletMarkShader; + if (soundType == IMPACTSOUND_GLASS) + mark = cgs.media.glassMarkShader; + else + mark = cgs.media.bulletMarkShader; sfx = 0; radius = 4; break; @@ -3234,6 +3381,17 @@ static void CG_ShotgunPellet( vec3_t start, vec3_t end, int skipNum, int shellWe CG_MissileHitWall( WP_HANDCANNON, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_METAL, 0 ); } } + else if ( tr.surfaceFlags & SURF_GLASS ) + { + //Blaze: Changed WP_SHOTGUN to WP_M3 + if (shellWeapon == WP_M3) + CG_MissileHitWall( WP_M3, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_GLASS, 0 ); + else if (shellWeapon == WP_HANDCANNON && crandom() > 0.5) + { + //Elder: show only approximately every other impact mark + CG_MissileHitWall( WP_HANDCANNON, 0, tr.endpos, tr.plane.normal, IMPACTSOUND_GLASS, 0 ); + } + } else { //Blaze: Changed WP_SHOTGUN to WP_M3 @@ -3671,7 +3829,7 @@ void CG_ReloadWeapon (centity_t *cent, int reloadStage) } weap = &cg_weapons[ ent->weapon ]; - +/* switch (reloadStage) { case 0: @@ -3709,4 +3867,5 @@ void CG_ReloadWeapon (centity_t *cent, int reloadStage) CG_Error("CG_ReloadWeapon: Reload stage > 2\n"); break; } +*/ }