diff options
author | Michael Levin <risujin@fastmail.fm> | 2009-10-03 11:26:51 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:15:00 +0000 |
commit | 0cf04fe37fef2e827a95bb19926a3cbf8e98c581 (patch) | |
tree | 93ac01309f47edb27be26fb31e3886f6082579b1 /src/cgame | |
parent | d9709deb95375f2462e5ca9fc98ebf92fd91ce04 (diff) |
* Added charge meter to the UI, can be disabled via GUI
* Trample and Lucifer Cannon charging reworked and moved to PMove
* Can no longer "cancel" a charging Lucifer Cannon
* STAT_MISC2 is now unused, booster and charge information can be inferred elsewhere (STAT_UNUSED)
* Trying to fire an empty weapon makes a clicking noise (also a bugfix, apparently the server would spam EV_NOAMMO which did nothing but is now used for the clicking noise -- audible to all players)
* Created an alternate, muffled Lucifer Cannon warning noise for other people's Lucifer Cannons
* Fixed bug which prevented players from switching to a different player while spectating someone in the spawn queue
* Spectators are now properly moved to the lock view position when spectating a player in the spawn queue
Diffstat (limited to 'src/cgame')
-rw-r--r-- | src/cgame/cg_draw.c | 141 | ||||
-rw-r--r-- | src/cgame/cg_event.c | 4 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 8 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 6 | ||||
-rw-r--r-- | src/cgame/cg_view.c | 2 | ||||
-rw-r--r-- | src/cgame/cg_weapons.c | 33 |
6 files changed, 158 insertions, 36 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 08433c44..5002fc9a 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -588,21 +588,15 @@ CG_DrawPlayerBoosterBolt */ static void CG_DrawPlayerBoosterBolt( rectDef_t *rect, vec4_t color, qhandle_t shader ) { - vec4_t localColor; - playerState_t *ps = &cg.snap->ps; + vec4_t localColor; Vector4Copy( color, localColor ); - if( ps->stats[ STAT_STATE ] & SS_BOOSTED ) - { - if( ps->stats[ STAT_MISC2 ] < 3000 ) - { - qboolean flash = ( ps->stats[ STAT_MISC2 ] / 500 ) % 2; - - if( flash ) - localColor[ 3 ] = 1.0f; - } - } + // Flash bolts when the boost is almost out + if( ( cg.snap->ps.stats[ STAT_STATE ] & SS_BOOSTED ) && + cg.boostedTime > 0 && cg.time - cg.boostedTime > BOOST_TIME - 5000 && + cg.time & 256 ) + localColor[ 3 ] = 1.0f; trap_R_SetColor( localColor ); CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); @@ -904,6 +898,123 @@ static void CG_DrawPlayerHealthCross3( rectDef_t *rect, vec4_t color, qhandle_t trap_R_SetColor( NULL ); } +static float CG_ChargeProgress( void ) +{ + float progress; + int min = 0, max = 0; + + if( cg.snap->ps.weapon == WP_ALEVEL3 ) + { + min = LEVEL3_POUNCE_TIME_MIN; + max = LEVEL3_POUNCE_TIME; + } + else if( cg.snap->ps.weapon == WP_ALEVEL3_UPG ) + { + min = LEVEL3_POUNCE_TIME_MIN; + max = LEVEL3_POUNCE_TIME_UPG; + } + else if( cg.snap->ps.weapon == WP_ALEVEL4 ) + { + min = LEVEL4_TRAMPLE_CHARGE_MIN; + max = LEVEL4_TRAMPLE_CHARGE_MAX; + } + else if( cg.snap->ps.weapon == WP_LUCIFER_CANNON ) + { + min = LCANNON_CHARGE_TIME_MIN; + max = LCANNON_CHARGE_TIME_MAX; + } + if( max - min < 0.0f ) + return 0.0f; + progress = ( (float)cg.predictedPlayerState.stats[ STAT_MISC ] - min ) / + ( max - min ); + if( progress > 1.0f ) + return 1.0f; + if( progress < 0.0f ) + return 0.0f; + return progress; +} + +#define CHARGE_BAR_FADE_RATE 0.002f + +static void CG_DrawPlayerChargeBarBG( rectDef_t *rect, vec4_t ref_color, + qhandle_t shader ) +{ + vec4_t color; + + if( !cg_drawChargeBar.integer || cg.chargeMeterAlpha <= 0.0f ) + return; + + color[ 0 ] = ref_color[ 0 ]; + color[ 1 ] = ref_color[ 1 ]; + color[ 2 ] = ref_color[ 2 ]; + color[ 3 ] = ref_color[ 3 ] * cg.chargeMeterAlpha; + + // Draw meter background + trap_R_SetColor( color ); + CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader ); + trap_R_SetColor( NULL ); +} + +static void CG_DrawPlayerChargeBar( rectDef_t *rect, vec4_t ref_color, + qhandle_t shader ) +{ + vec4_t color; + float x, y, width, height, cap_width, progress; + + if( !cg_drawChargeBar.integer ) + return; + + // Get progress proportion and pump fade + progress = CG_ChargeProgress(); + if( progress <= 0.0f ) + { + cg.chargeMeterAlpha -= CHARGE_BAR_FADE_RATE * cg.frametime; + if( cg.chargeMeterAlpha <= 0.0f ) + { + cg.chargeMeterAlpha = 0.0f; + return; + } + } + else + { + cg.chargeMeterValue = progress; + cg.chargeMeterAlpha += CHARGE_BAR_FADE_RATE * cg.frametime; + if( cg.chargeMeterAlpha > 1.0f ) + cg.chargeMeterAlpha = 1.0f; + } + + color[ 0 ] = ref_color[ 0 ]; + color[ 1 ] = ref_color[ 1 ]; + color[ 2 ] = ref_color[ 2 ]; + color[ 3 ] = ref_color[ 3 ] * cg.chargeMeterAlpha; + + // Flash red for Lucifer Cannon warning + if( cg.snap->ps.weapon == WP_LUCIFER_CANNON && + cg.snap->ps.stats[ STAT_MISC ] >= LCANNON_CHARGE_TIME_WARN && + ( cg.time & 128 ) ) + { + color[ 0 ] = 1.0f; + color[ 1 ] = 0.0f; + color[ 2 ] = 0.0f; + } + + // Calculate bar coords + x = rect->x; + y = rect->y; + width = ( rect->w - 6 ) * cg.chargeMeterValue; + height = rect->h; + CG_AdjustFrom640( &x, &y, &width, &height ); + cap_width = 3 * cgs.screenXScale; + + // Draw the meter + trap_R_SetColor( color ); + trap_R_DrawStretchPic( x, y, cap_width, height, 0, 0, 1, 1, shader ); + trap_R_DrawStretchPic( x + width + cap_width, y, cap_width, height, + 1, 0, 0, 1, shader ); + trap_R_DrawStretchPic( x + cap_width, y, width, height, 1, 0, 1, 1, shader ); + trap_R_SetColor( NULL ); +} + static void CG_DrawProgressLabel( rectDef_t *rect, float text_x, float text_y, vec4_t color, float scale, int textalign, int textvalign, const char *s, float fraction ) @@ -2151,6 +2262,12 @@ void CG_OwnerDraw( float x, float y, float w, float h, float text_x, case CG_PLAYER_HEALTH_CROSS3: CG_DrawPlayerHealthCross3( &rect, color, shader ); break; + case CG_PLAYER_CHARGE_BAR_BG: + CG_DrawPlayerChargeBarBG( &rect, color, shader ); + break; + case CG_PLAYER_CHARGE_BAR: + CG_DrawPlayerChargeBar( &rect, color, shader ); + break; case CG_PLAYER_CLIPS_RING: CG_DrawPlayerClipsRing( &rect, color, shader ); break; diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c index 9b6afbe6..2d622088 100644 --- a/src/cgame/cg_event.c +++ b/src/cgame/cg_event.c @@ -737,8 +737,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) // case EV_NOAMMO: DEBUGNAME( "EV_NOAMMO" ); - { - } + trap_S_StartSound( NULL, es->number, CHAN_WEAPON, + cgs.media.weaponEmptyClick ); break; case EV_CHANGE_WEAPON: diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 360dac34..8dfd09a4 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1133,6 +1133,11 @@ typedef struct playerState_t savedPmoveStates[ NUM_SAVED_STATES ]; int stateHead, stateTail; int ping; + + float chargeMeterAlpha; + float chargeMeterValue; + + int nextWeaponClickTime; } cg_t; @@ -1179,6 +1184,7 @@ typedef struct // sounds sfxHandle_t tracerSound; + sfxHandle_t weaponEmptyClick; sfxHandle_t selectSound; sfxHandle_t footsteps[ FOOTSTEP_TOTAL ][ 4 ]; sfxHandle_t talkSound; @@ -1263,6 +1269,7 @@ typedef struct qhandle_t massDriverTS; sfxHandle_t lCannonWarningSound; + sfxHandle_t lCannonWarningSound2; qhandle_t buildWeaponTimerPie[ 8 ]; qhandle_t upgradeClassIconShader; @@ -1409,6 +1416,7 @@ extern vmCvar_t cg_drawSnapshot; extern vmCvar_t cg_draw3dIcons; extern vmCvar_t cg_drawIcons; extern vmCvar_t cg_drawAmmoWarning; +extern vmCvar_t cg_drawChargeBar; extern vmCvar_t cg_drawCrosshair; extern vmCvar_t cg_drawCrosshairNames; extern vmCvar_t cg_drawRewards; diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index ac0715fe..a2027b3e 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -125,6 +125,7 @@ vmCvar_t cg_drawSnapshot; vmCvar_t cg_draw3dIcons; vmCvar_t cg_drawIcons; vmCvar_t cg_drawAmmoWarning; +vmCvar_t cg_drawChargeBar; vmCvar_t cg_drawCrosshair; vmCvar_t cg_drawCrosshairNames; vmCvar_t cg_drawRewards; @@ -268,6 +269,7 @@ static cvarTable_t cvarTable[ ] = { &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE }, { &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE }, { &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE }, + { &cg_drawChargeBar, "cg_drawChargeBar", "1", CVAR_ARCHIVE }, { &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE }, { &cg_drawCrosshair, "cg_drawCrosshair", "1", CVAR_ARCHIVE }, { &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, @@ -692,6 +694,7 @@ static void CG_RegisterSounds( void ) cgs.media.tracerSound = trap_S_RegisterSound( "sound/weapons/tracer.wav", qfalse ); cgs.media.selectSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse ); cgs.media.turretSpinupSound = trap_S_RegisterSound( "sound/buildables/mgturret/spinup.wav", qfalse ); + cgs.media.weaponEmptyClick = trap_S_RegisterSound( "sound/weapons/click.wav", qfalse ); cgs.media.talkSound = trap_S_RegisterSound( "sound/misc/talk.wav", qfalse ); cgs.media.alienTalkSound = trap_S_RegisterSound( "sound/misc/alien_talk.wav", qfalse ); @@ -760,6 +763,7 @@ static void CG_RegisterSounds( void ) cgs.media.buildableRepairedSound = trap_S_RegisterSound( "sound/buildables/human/repaired.wav", qfalse ); cgs.media.lCannonWarningSound = trap_S_RegisterSound( "models/weapons/lcannon/warning.wav", qfalse ); + cgs.media.lCannonWarningSound2 = trap_S_RegisterSound( "models/weapons/lcannon/warning2.wav", qfalse ); } @@ -835,7 +839,7 @@ static void CG_RegisterGraphics( void ) cgs.media.buildWeaponTimerPie[ i ] = trap_R_RegisterShader( buildWeaponTimerPieShaders[ i ] ); cgs.media.upgradeClassIconShader = trap_R_RegisterShader( "icons/icona_upgrade.tga" ); - + cgs.media.balloonShader = trap_R_RegisterShader( "gfx/sprites/chatballoon" ); cgs.media.disconnectPS = CG_RegisterParticleSystem( "disconnectPS" ); diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index 2c718556..9772e1f5 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -471,7 +471,7 @@ static void CG_OffsetFirstPersonView( void ) if( ps->stats[ STAT_MISC ] > 0 ) { float fraction = (float)ps->stats[ STAT_MISC ] / - (float)LEVEL4_TRAMPLE_CHARGE_MAX; + LEVEL4_TRAMPLE_CHARGE_MAX; if( fraction > 1.0f ) fraction = 1.0f; diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c index f4c8fbf8..d0968dd9 100644 --- a/src/cgame/cg_weapons.c +++ b/src/cgame/cg_weapons.c @@ -872,8 +872,9 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent // Lucifer cannon charge warning beep if( weaponNum == WP_LUCIFER_CANNON && ( cent->currentState.eFlags & EF_WARN_CHARGE ) ) - trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, - vec3_origin, cgs.media.lCannonWarningSound ); + trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, + vec3_origin, ps ? cgs.media.lCannonWarningSound : + cgs.media.lCannonWarningSound2 ); if( !noGunModel ) { @@ -987,6 +988,9 @@ CG_AddViewWeapon Add the weapon, and flash for the player's view ============== */ + +#define WEAPON_CLICK_REPEAT 500 + void CG_AddViewWeapon( playerState_t *ps ) { refEntity_t hand; @@ -1072,27 +1076,16 @@ void CG_AddViewWeapon( playerState_t *ps ) VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin ); VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin ); - if( weapon == WP_LUCIFER_CANNON ) + // Lucifer Cannon vibration effect + if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 ) { float fraction; - if( ps->stats[ STAT_MISC ] > 0 ) - { - // vibration effect - fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE; - VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], - hand.origin ); - VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], - hand.origin ); - } - else if( ps->stats[ STAT_MISC2 ] > 0 ) - { - // reloading effect - fraction = (float)ps->stats[ STAT_MISC2 ] / 250.0f; - fraction = ( fraction > 1.0f ) ? 1.0f : fraction; - VectorMA( hand.origin, fraction * -3.0f, cg.refdef.viewaxis[ 2 ], - hand.origin ); - } + fraction = (float)ps->stats[ STAT_MISC ] / LCANNON_CHARGE_TIME_MAX; + VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], + hand.origin ); + VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], + hand.origin ); } AnglesToAxis( angles, hand.axis ); |