diff options
Diffstat (limited to 'src/cgame')
-rw-r--r-- | src/cgame/cg_buildable.c | 186 | ||||
-rw-r--r-- | src/cgame/cg_draw.c | 1 | ||||
-rw-r--r-- | src/cgame/cg_drawtools.c | 35 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 3 | ||||
-rw-r--r-- | src/cgame/cg_servercmds.c | 1 | ||||
-rw-r--r-- | src/cgame/cg_tutorial.c | 33 |
6 files changed, 166 insertions, 93 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c index 2f1eb239..c1cac345 100644 --- a/src/cgame/cg_buildable.c +++ b/src/cgame/cg_buildable.c @@ -697,8 +697,8 @@ static void CG_BuildableParticleEffects( centity_t *cent ) { entityState_t *es = ¢->currentState; buildableTeam_t team = BG_FindTeamForBuildable( es->modelindex ); - int health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - float healthFrac = (float)health / B_HEALTH_SCALE; + int health = es->generic1 & B_HEALTH_MASK; + float healthFrac = (float)health / B_HEALTH_MASK; if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) return; @@ -736,85 +736,122 @@ static void CG_BuildableParticleEffects( centity_t *cent ) } } - -#define HEALTH_BAR_WIDTH 50.0f -#define HEALTH_BAR_HEIGHT 5.0f +#define STATUS_FADE_TIME 200 +#define STATUS_MAX_VIEW_DIST 600.0f /* ================== -CG_BuildableHealthBar +CG_BuildableStatusDisplay ================== */ -static void CG_BuildableHealthBar( centity_t *cent ) +static void CG_BuildableStatusDisplay( centity_t *cent ) { - vec3_t origin, origin2, down, right, back, downLength, rightLength; - float rimWidth = HEALTH_BAR_HEIGHT / 15.0f; - float doneWidth, leftWidth, progress; + entityState_t *es = ¢->currentState; + vec3_t origin; + float healthScale; int health; - qhandle_t shader; - entityState_t *es; - vec3_t mins, maxs; + float x, y; + char s[ MAX_STRING_CHARS ] = { 0 }; + int w; + vec4_t color = { 1.0f, 1.0f, 1.0f, 1.0f }; + qboolean powered, marked; + trace_t tr; + float d; - es = ¢->currentState; + CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, cg.refdef.vieworg, + cent->currentState.number, MASK_SOLID ); + d = Distance( cent->lerpOrigin, cg.refdef.vieworg ); - health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - progress = (float)health / B_HEALTH_SCALE; + if( ( tr.fraction < 1.0f || d > STATUS_MAX_VIEW_DIST ) && + cent->buildableStatus.visible ) + { + cent->buildableStatus.visible = qfalse; + cent->buildableStatus.lastTime = cg.time; + } + else if( ( tr.fraction == 1.0f && d <= STATUS_MAX_VIEW_DIST ) && + !cent->buildableStatus.visible ) + { + cent->buildableStatus.visible = qtrue; + cent->buildableStatus.lastTime = cg.time; + } - if( progress < 0.0f ) - progress = 0.0f; - else if( progress > 1.0f ) - progress = 1.0f; + // Fade up + if( cent->buildableStatus.visible ) + { + if( cent->buildableStatus.lastTime + STATUS_FADE_TIME > cg.time ) + color[ 3 ] = (float)( cg.time - cent->buildableStatus.lastTime ) / STATUS_FADE_TIME; + } - if( progress < 0.33f ) - shader = cgs.media.redBuildShader; - else - shader = cgs.media.greenBuildShader; + // Fade down + if( !cent->buildableStatus.visible ) + { + if( cent->buildableStatus.lastTime + STATUS_FADE_TIME > cg.time ) + color[ 3 ] = 1.0f - (float)( cg.time - cent->buildableStatus.lastTime ) / STATUS_FADE_TIME; + else + return; + } + + health = es->generic1 & B_HEALTH_MASK; + healthScale = (float)health / B_HEALTH_MASK; - doneWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) * progress; - leftWidth = ( HEALTH_BAR_WIDTH - 2 * rimWidth ) - doneWidth; + if( healthScale < 0.0f ) + healthScale = 0.0f; + else if( healthScale > 1.0f ) + healthScale = 1.0f; - VectorCopy( cg.refdef.viewaxis[ 2 ], down ); - VectorInverse( down ); - VectorCopy( cg.refdef.viewaxis[ 1 ], right ); - VectorInverse( right ); - VectorSubtract( cg.refdef.vieworg, cent->lerpOrigin, back ); - VectorNormalize( back ); VectorCopy( cent->lerpOrigin, origin ); - BG_FindBBoxForBuildable( es->modelindex, mins, maxs ); - VectorMA( origin, 48.0f, es->origin2, origin ); - VectorMA( origin, -HEALTH_BAR_WIDTH / 2.0f, right, origin ); - VectorMA( origin, maxs[ 0 ] + 8.0f, back, origin ); - - VectorCopy( origin, origin2 ); - VectorScale( right, rimWidth + doneWidth, rightLength ); - VectorScale( down, HEALTH_BAR_HEIGHT, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - VectorMA( origin, rimWidth + doneWidth, right, origin2 ); - VectorScale( right, leftWidth, rightLength ); - VectorScale( down, rimWidth, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - VectorMA( origin, rimWidth + doneWidth, right, origin2 ); - VectorMA( origin2, HEALTH_BAR_HEIGHT - rimWidth, down, origin2 ); - VectorScale( right, leftWidth, rightLength ); - VectorScale( down, rimWidth, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - VectorMA( origin, HEALTH_BAR_WIDTH - rimWidth, right, origin2 ); - VectorScale( right, rimWidth, rightLength ); - VectorScale( down, HEALTH_BAR_HEIGHT, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, shader ); - - if( !( es->generic1 & B_POWERED_TOGGLEBIT ) && - BG_FindTeamForBuildable( es->modelindex ) == BIT_HUMANS ) + if( CG_WorldToScreen( origin, &x, &y ) ) + { + powered = es->generic1 & B_POWERED_TOGGLEBIT; + marked = es->generic1 & B_MARKED_TOGGLEBIT; + + //FIXME: crappy mock-up for the time being... + Com_sprintf( s, MAX_STRING_CHARS, "%d%%", (int)(healthScale * 100) ); + + if( BG_FindTeamForBuildable( es->modelindex ) == BIT_HUMANS && !powered ) + Q_strcat( s, MAX_STRING_CHARS, " P" ); + + if( marked ) + Q_strcat( s, MAX_STRING_CHARS, " X" ); + + w = CG_Text_Width( s, 0.5f, 0 ); + + CG_Text_Paint( x - w / 2, y, 0.5f, color, s, 0, 0, ITEM_TEXTSTYLE_NORMAL ); + } +} + +/* +================== +CG_DrawBuildableStatus +================== +*/ +void CG_DrawBuildableStatus( void ) +{ + int i; + centity_t *cent; + entityState_t *es; + + switch( cg.predictedPlayerState.weapon ) { - VectorMA( origin, 15.0f, right, origin2 ); - VectorMA( origin2, HEALTH_BAR_HEIGHT + 5.0f, down, origin2 ); - VectorScale( right, HEALTH_BAR_WIDTH / 2.0f - 5.0f, rightLength ); - VectorScale( down, HEALTH_BAR_WIDTH / 2.0f - 5.0f, downLength ); - CG_DrawPlane( origin2, downLength, rightLength, cgs.media.noPowerShader ); + case WP_ABUILD: + case WP_ABUILD2: + case WP_HBUILD: + case WP_HBUILD2: + for( i = 0; i < cg.snap->numEntities; i++ ) + { + cent = &cg_entities[ cg.snap->entities[ i ].number ]; + es = ¢->currentState; + + if( es->eType == ET_BUILDABLE && + BG_FindTeamForBuildable( es->modelindex ) == + BG_FindTeamForWeapon( cg.predictedPlayerState.weapon ) ) + CG_BuildableStatusDisplay( cent ); + } + break; + + default: + break; } } @@ -993,21 +1030,6 @@ void CG_Buildable( centity_t *cent ) trap_R_AddRefEntityToScene( &turretTop ); } - switch( cg.predictedPlayerState.weapon ) - { - case WP_ABUILD: - case WP_ABUILD2: - case WP_HBUILD: - case WP_HBUILD2: - if( BG_FindTeamForBuildable( es->modelindex ) == - BG_FindTeamForWeapon( cg.predictedPlayerState.weapon ) ) - CG_BuildableHealthBar( cent ); - break; - - default: - break; - } - //weapon effects for turrets if( es->eFlags & EF_FIRING ) { @@ -1036,8 +1058,8 @@ void CG_Buildable( centity_t *cent ) trap_S_AddLoopingSound( es->number, cent->lerpOrigin, vec3_origin, weapon->readySound ); } - health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - healthScale = (float)health / B_HEALTH_SCALE; + health = es->generic1 & B_HEALTH_MASK; + healthScale = (float)health / B_HEALTH_MASK; if( healthScale < cent->lastBuildableHealthScale && ( es->generic1 & B_SPAWNED_TOGGLEBIT ) ) { diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 4bcec5b3..43f5e0fc 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -3345,6 +3345,7 @@ static void CG_Draw2D( void ) Menu_Paint( menu, qtrue ); CG_DrawCrosshair( ); + CG_DrawBuildableStatus( ); } else if( cg_drawStatus.integer ) Menu_Paint( defaultMenu, qtrue ); diff --git a/src/cgame/cg_drawtools.c b/src/cgame/cg_drawtools.c index a1b99a5f..3151f66f 100644 --- a/src/cgame/cg_drawtools.c +++ b/src/cgame/cg_drawtools.c @@ -285,8 +285,6 @@ void CG_TileClear( void ) CG_TileClearBox( right, top, w - right, bottom - top + 1, cgs.media.backTileShader ); } - - /* ================ CG_FadeColor @@ -315,3 +313,36 @@ float *CG_FadeColor( int startMsec, int totalMsec ) return color; } + +/* +================ +CG_WorldToScreen +================ +*/ +qboolean CG_WorldToScreen( vec3_t point, float *x, float *y ) +{ + vec3_t trans; + float xc, yc; + float px, py; + float z; + + px = tan( cg.refdef.fov_x * M_PI / 360.0 ); + py = tan( cg.refdef.fov_y * M_PI / 360.0 ); + + VectorSubtract( point, cg.refdef.vieworg, trans ); + + xc = 640.0f / 2.0f; + yc = 480.0f / 2.0f; + + z = DotProduct( trans, cg.refdef.viewaxis[ 0 ] ); + if( z <= 0.001f ) + return qfalse; + + if( x ) + *x = xc - DotProduct( trans, cg.refdef.viewaxis[ 1 ] ) * xc / ( z * px ); + + if( y ) + *y = yc - DotProduct( trans, cg.refdef.viewaxis[ 2 ] ) * yc / ( z * py ); + + return qtrue; +} diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 2f61e4a4..613dc98a 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1291,11 +1291,10 @@ typedef struct qboolean localServer; // detected on startup by checking sv_running // parsed from serverinfo - int dmflags; - int teamflags; int timelimit; int maxclients; char mapname[ MAX_QPATH ]; + qboolean markDeconstruct; // Whether or not buildables are marked int voteTime; int voteYes; diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index bb0daabb..ed677779 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -115,6 +115,7 @@ void CG_ParseServerinfo( void ) info = CG_ConfigString( CS_SERVERINFO ); cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) ); cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); + cgs.markDeconstruct = atoi( Info_ValueForKey( info, "g_markDeconstruct" ) ); mapname = Info_ValueForKey( info, "mapname" ); Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname ); } diff --git a/src/cgame/cg_tutorial.c b/src/cgame/cg_tutorial.c index 350d3156..ddc4cbcb 100644 --- a/src/cgame/cg_tutorial.c +++ b/src/cgame/cg_tutorial.c @@ -157,8 +157,8 @@ static entityState_t *CG_BuildableInRange( playerState_t *ps, float *healthFract if( healthFraction ) { - health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT ); - *healthFraction = (float)health / B_HEALTH_SCALE; + health = es->generic1 & B_HEALTH_MASK; + *healthFraction = (float)health / B_HEALTH_MASK; } if( es->eType == ET_BUILDABLE && @@ -175,7 +175,8 @@ CG_AlienBuilderText */ static void CG_AlienBuilderText( char *text, playerState_t *ps ) { - buildable_t buildable = ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT; + buildable_t buildable = ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT; + entityState_t *es; if( buildable > BA_NONE ) { @@ -195,11 +196,29 @@ static void CG_AlienBuilderText( char *text, playerState_t *ps ) va( "Press %s to build a structure\n", CG_KeyNameForCommand( "+attack" ) ) ); - if( CG_BuildableInRange( ps, NULL ) ) + if( ( es = CG_BuildableInRange( ps, NULL ) ) ) { - Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Press %s to destroy this structure\n", - CG_KeyNameForCommand( "deconstruct" ) ) ); + if( cgs.markDeconstruct ) + { + if( es->generic1 & B_MARKED_TOGGLEBIT ) + { + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to unmark this structure\n", + CG_KeyNameForCommand( "deconstruct" ) ) ); + } + else + { + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to mark this structure\n", + CG_KeyNameForCommand( "deconstruct" ) ) ); + } + } + else + { + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to destroy this structure\n", + CG_KeyNameForCommand( "deconstruct" ) ) ); + } } } |