summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2015-04-03 03:50:41 +0200
committerPaweł Redman <pawel.redman@gmail.com>2015-04-03 03:50:41 +0200
commit0d5460522ba3651da1ed5630f7f8a784c5eb6514 (patch)
tree143e3cae332ef6a31957d222fb9b9ed8e27e9f06 /src
parente6735d21e17ecbbe03607046ded443516b65c3a7 (diff)
Initial implementation of health bars.
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_draw.c120
-rw-r--r--src/game/g_active.c4
2 files changed, 123 insertions, 1 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index d8b411c..340a207 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -3836,7 +3836,7 @@ static void CG_DrawWarmup( void )
/*
=================
-CG_DrawWarmup
+Damage blobs
=================
*/
@@ -3968,6 +3968,123 @@ static void CG_DrawDamageBlobs( void )
trap_R_SetColor( NULL );
}
+/*
+=================
+Health bars
+=================
+*/
+typedef struct
+{
+ vec3_t origin;
+ float dist;
+
+ int value;
+ int max;
+} healthBar_t;
+
+static int CompareHealthBars( const healthBar_t *a, const healthBar_t *b )
+{
+ return a->dist < b->dist;
+}
+
+static void CG_DrawHealthBars( void )
+{
+ int i;
+ healthBar_t *bar, *bare, bars[ MAX_ENTITIES_IN_SNAPSHOT ];
+
+ for( bar = bars, i = 0; i < cg.snap->numEntities; i++ )
+ {
+ int j;
+ centity_t *cent;
+ entityState_t *es;
+ trace_t tr;
+ vec3_t mins, maxs;
+
+ cent = cg_entities + cg.snap->entities[ i ].number;
+ es = &cent->currentState;
+
+ if( es->eFlags & EF_DEAD )
+ continue;
+
+ switch( es->eType )
+ {
+ case ET_BUILDABLE:
+ bar->value = es->generic1;
+ bar->max = BG_Buildable( es->modelindex )->health;
+ BG_BuildableBoundingBox( es->modelindex, mins, maxs );
+ break;
+
+ case ET_PLAYER:
+ bar->value = es->otherEntityNum2;
+ bar->max = BG_Class( ( es->misc >> 8 ) & 0xFF )->health;
+ BG_ClassBoundingBox( ( es->misc >> 8 ) & 0xFF, mins, maxs, NULL, NULL, NULL );
+ break;
+
+ default:
+ continue;
+ }
+
+ for( j = 0; j < 3; j++ )
+ bar->origin[ j ] = cent->lerpOrigin[ j ] + ( maxs[ j ] + mins[ j ] ) / 2.0f;
+
+ CG_Trace( &tr, cg.refdef.vieworg, NULL, NULL, bar->origin, ENTITYNUM_NONE, MASK_SOLID );
+
+ if( tr.fraction < 1.0f )
+ continue;
+
+ bar->dist = Distance( bar->origin, cg.refdef.vieworg );
+
+ bar++;
+ }
+
+ bare = bar;
+ qsort( bars, bare - bars, sizeof( healthBar_t ),
+ (int(*)(const void*,const void*))CompareHealthBars );
+
+/*
+ TODO: figure out why qsort fails for more than 5 bars
+
+ for( i = 0; i < bare - bars - 1; i++ )
+ if( CompareHealthBars( bars + i, bars + i + 1 ) )
+ {
+ Com_Printf( "qsort is retarded\n" );
+ break;
+ }
+*/
+
+ for( bar = bars; bar < bare; bar++ )
+ {
+ float x, y, w, h, hf;
+ char buffer[ 64 ];
+ vec4_t color;
+
+ if( !CG_WorldToScreen( bar->origin, &x, &y ) )
+ continue;
+
+ hf = (float)bar->value / bar->max;
+
+ h = 20 * 100 / bar->dist;
+ w = 4 * h * cgDC.aspectScale;
+
+ Com_sprintf( buffer, sizeof( buffer ), "%d", bar->value );
+
+ color[ 3 ] = 1.0f;
+
+ VectorSet( color, 0.1, 0.7, 0.1 );
+ trap_R_SetColor( color );
+ CG_DrawPic( x - w/2, y - h/2, w * hf, h, cgs.media.whiteShader );
+
+ VectorSet( color, 0.7, 0.1, 0.1 );
+ trap_R_SetColor( color );
+ CG_DrawPic( x - w/2 + w * hf, y - h/2, w * ( 1 - hf ), h, cgs.media.whiteShader );
+
+ VectorSet( color, 0, 0, 0 );
+ trap_R_SetColor( color );
+ CG_DrawNumber( x, y, h, buffer );
+ }
+}
+
+
//==================================================================================
/*
@@ -4019,6 +4136,7 @@ static void CG_Draw2D( void )
}
CG_DrawDamageBlobs( );
+ CG_DrawHealthBars( );
if( !menu )
{
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 90c47c4..2eede6b 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -2236,6 +2236,7 @@ void ClientThink( int clientNum )
void G_RunClient( gentity_t *ent )
{
+ // send all buffered damage blobs
if( ent->client->bufferedBlobCount )
{
int i;
@@ -2275,6 +2276,9 @@ void G_RunClient( gentity_t *ent )
ent->client->bufferedBlobCount = 0;
}
+ // update the public health field
+ ent->s.otherEntityNum2 = MAX( 0, ent->client->ps.stats[ STAT_HEALTH ] );
+
// Run a client think when there are no commands for a time
if( !g_synchronousClients.integer &&
( g_friendlyFreeze.integer < 100 ||