summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2015-04-03 00:33:39 +0200
committerPaweł Redman <pawel.redman@gmail.com>2015-04-03 00:33:39 +0200
commit5678a7bb3498f20123523f008df947a39eb44ccc (patch)
tree79a9984682742613ba610155ab43705e86f4ba9c
parent216fc980dd8221198e491745a0eaa029c37f74d3 (diff)
Implement damage blobs.
-rw-r--r--assets/gfx/2d/numbers_alt/0.tgabin0 -> 1038 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/1.tgabin0 -> 772 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/2.tgabin0 -> 854 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/3.tgabin0 -> 786 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/4.tgabin0 -> 860 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/5.tgabin0 -> 834 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/6.tgabin0 -> 904 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/7.tgabin0 -> 710 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/8.tgabin0 -> 1102 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/9.tgabin0 -> 904 bytes
-rw-r--r--assets/gfx/2d/numbers_alt/minus.tgabin0 -> 282 bytes
-rw-r--r--src/cgame/cg_draw.c139
-rw-r--r--src/cgame/cg_local.h5
-rw-r--r--src/cgame/cg_main.c25
-rw-r--r--src/cgame/cg_servercmds.c20
-rw-r--r--src/game/bg_public.h4
-rw-r--r--src/game/g_active.c39
-rw-r--r--src/game/g_combat.c37
-rw-r--r--src/game/g_local.h11
19 files changed, 279 insertions, 1 deletions
diff --git a/assets/gfx/2d/numbers_alt/0.tga b/assets/gfx/2d/numbers_alt/0.tga
new file mode 100644
index 0000000..ed72ed5
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/0.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/1.tga b/assets/gfx/2d/numbers_alt/1.tga
new file mode 100644
index 0000000..8267352
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/1.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/2.tga b/assets/gfx/2d/numbers_alt/2.tga
new file mode 100644
index 0000000..92414db
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/2.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/3.tga b/assets/gfx/2d/numbers_alt/3.tga
new file mode 100644
index 0000000..862606a
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/3.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/4.tga b/assets/gfx/2d/numbers_alt/4.tga
new file mode 100644
index 0000000..bd7e6cc
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/4.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/5.tga b/assets/gfx/2d/numbers_alt/5.tga
new file mode 100644
index 0000000..0de619f
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/5.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/6.tga b/assets/gfx/2d/numbers_alt/6.tga
new file mode 100644
index 0000000..770ee54
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/6.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/7.tga b/assets/gfx/2d/numbers_alt/7.tga
new file mode 100644
index 0000000..cf173e7
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/7.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/8.tga b/assets/gfx/2d/numbers_alt/8.tga
new file mode 100644
index 0000000..21a0b54
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/8.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/9.tga b/assets/gfx/2d/numbers_alt/9.tga
new file mode 100644
index 0000000..d548695
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/9.tga
Binary files differ
diff --git a/assets/gfx/2d/numbers_alt/minus.tga b/assets/gfx/2d/numbers_alt/minus.tga
new file mode 100644
index 0000000..2129858
--- /dev/null
+++ b/assets/gfx/2d/numbers_alt/minus.tga
Binary files differ
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index e3af715..30e6001 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -3834,6 +3834,143 @@ static void CG_DrawWarmup( void )
UI_Text_Paint( 320 - w / 2, 200 + 1.5f * h, size, colorWhite, text, 0, 0, ITEM_TEXTSTYLE_SHADOWED );
}
+/*
+=================
+CG_DrawWarmup
+=================
+*/
+
+typedef struct
+{
+ qboolean inuse;
+ int spawnTime;
+ int value;
+ int flags;
+ vec3_t origin;
+ vec3_t velocity;
+} cg_damageBlob_t;
+
+#define MAX_DAMAGE_BLOBS 50
+cg_damageBlob_t cg_damageBlobs[ MAX_DAMAGE_BLOBS ];
+
+void CG_SpawnDamageBlob( vec3_t origin, int value, int flags )
+{
+ centity_t *cent;
+ cg_damageBlob_t *blob, *oldest = NULL;
+
+ for( blob = cg_damageBlobs; blob < cg_damageBlobs + MAX_DAMAGE_BLOBS; blob++ )
+ {
+ if( !oldest || blob->spawnTime < oldest->spawnTime )
+ oldest = blob;
+
+ if( blob->inuse )
+ continue;
+
+ goto found_blob;
+ }
+
+ oldest = blob;
+
+found_blob:
+
+ blob->inuse = qtrue;
+ blob->spawnTime = cg.time;
+ blob->value = value;
+ blob->flags = flags;
+ VectorCopy( origin, blob->origin );
+ VectorSet( blob->velocity, crandom( ) * 50, crandom( ) * 50, 300 );
+}
+
+static void CG_DrawNumber( float x, float y, float h, char *str )
+{
+ int index, len;
+ float w;
+ char *p;
+
+ len = strlen( str );
+ w = h * cgDC.aspectScale * 0.5f;
+
+ y -= h / 2;
+ x -= len * w / 2;
+
+ for( p = str; *p; p++ )
+ {
+ if( *p >= '0' && *p <= '9' )
+ index = *p - '0';
+ else
+ index = 10;
+
+ CG_DrawPic( x, y, w, h, cgs.media.numberShadersAlt[ index ] );
+ x += w;
+ }
+}
+
+#define DAMAGE_BLOB_TIME 700
+
+static void CG_DrawDamageBlobs( void )
+{
+ cg_damageBlob_t *blob;
+ float dt, x, y, fade, scale;
+ vec4_t color;
+ char str[ 32 ];
+
+ dt = 0.001 * cg.frametime;
+
+ for( blob = cg_damageBlobs; blob < cg_damageBlobs + MAX_DAMAGE_BLOBS; blob++ )
+ {
+ if( !blob->inuse )
+ continue;
+
+ if( blob->spawnTime + DAMAGE_BLOB_TIME < cg.time )
+ {
+ blob->inuse = qfalse;
+ continue;
+ }
+
+ if( !CG_WorldToScreen( blob->origin, &x, &y ) )
+ continue;
+
+ fade = 1.0f - (float)( cg.time - blob->spawnTime ) / DAMAGE_BLOB_TIME;
+
+ scale = cg_damageBlobSize.value /
+ pow( Distance( blob->origin, cg.refdef.vieworg ), 0.5f );
+
+ Com_sprintf( str, sizeof( str ), "%d", blob->value );
+
+
+#define Vector3Set( v, x, y, z ) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z))
+
+ if( blob->flags & DAMAGE_BLOB_FRIENDLY )
+ Vector3Set( color, 1, 0, 0 );
+ else
+ {
+ if( blob->flags & DAMAGE_BLOB_BUILDABLE )
+ {
+ if( blob->flags & DAMAGE_BLOB_SPLASH )
+ Vector3Set( color, 1, 0.5, 0 );
+ else
+ Vector3Set( color, 0.7, 0.7, 0.7 );
+ }
+ else
+ {
+ if( blob->flags & DAMAGE_BLOB_SPLASH )
+ Vector3Set( color, 1, 1, 0 );
+ else
+ Vector3Set( color, 1, 1, 1 );
+ }
+ }
+
+ color[ 3 ] = cg_damageBlobAlpha.value * fade;
+ trap_R_SetColor( color );
+ CG_DrawNumber( x, y, scale, str );
+
+ VectorMA( blob->origin, dt, blob->velocity, blob->origin );
+ blob->velocity[ 2 ] -= 800 * dt;
+ }
+
+ trap_R_SetColor( NULL );
+}
+
//==================================================================================
/*
@@ -3884,6 +4021,8 @@ static void CG_Draw2D( void )
CG_DrawBuildableStatus( );
}
+ CG_DrawDamageBlobs( );
+
if( !menu )
{
menu = Menus_FindByName( "default_hud" );
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 5816a9b..bb38c41 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -1198,6 +1198,7 @@ typedef struct
qhandle_t teamOverlayShader;
qhandle_t numberShaders[ 11 ];
+ qhandle_t numberShadersAlt[ 11 ];
qhandle_t shadowMarkShader;
qhandle_t wakeMarkShader;
@@ -1606,6 +1607,9 @@ extern vmCvar_t cg_viewQuake;
extern vmCvar_t cg_viewQuakeLambda;
extern vmCvar_t cg_viewQuakeLimit;
+extern vmCvar_t cg_damageBlobSize;
+extern vmCvar_t cg_damageBlobAlpha;
+
//
// cg_main.c
//
@@ -1703,6 +1707,7 @@ void CG_UpdateMediaFraction( float newFract );
void CG_ResetPainBlend( void );
void CG_DrawField( float x, float y, int width, float cw, float ch, int value );
+void CG_SpawnDamageBlob( vec3_t origin, int value, int flags );
//
// cg_players.c
//
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 7ed3bfc..714b0d8 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -232,6 +232,9 @@ vmCvar_t cg_viewQuake;
vmCvar_t cg_viewQuakeLambda;
vmCvar_t cg_viewQuakeLimit;
+vmCvar_t cg_damageBlobSize;
+vmCvar_t cg_damageBlobAlpha;
+
typedef struct
{
vmCvar_t *vmCvar;
@@ -379,7 +382,10 @@ static cvarTable_t cvarTable[ ] =
{ &cg_viewQuake, "cg_viewQuake", "1", CVAR_ARCHIVE },
{ &cg_viewQuakeLambda, "cg_viewQuakeLambda", "-10", CVAR_ARCHIVE },
- { &cg_viewQuakeLimit, "cg_viewQuakeLimit", "5", CVAR_ARCHIVE }
+ { &cg_viewQuakeLimit, "cg_viewQuakeLimit", "5", CVAR_ARCHIVE },
+
+ { &cg_damageBlobSize, "cg_damageBlobSize", "400", CVAR_ARCHIVE },
+ { &cg_damageBlobAlpha, "cg_damageBlobAlpha", "0.8", CVAR_ARCHIVE }
};
static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
@@ -769,6 +775,20 @@ static void CG_RegisterGraphics( void )
"gfx/2d/numbers/nine_32b",
"gfx/2d/numbers/minus_32b",
};
+ static char *sb_nums_alt[ 11 ] =
+ {
+ "gfx/2d/numbers_alt/0",
+ "gfx/2d/numbers_alt/1",
+ "gfx/2d/numbers_alt/2",
+ "gfx/2d/numbers_alt/3",
+ "gfx/2d/numbers_alt/4",
+ "gfx/2d/numbers_alt/5",
+ "gfx/2d/numbers_alt/6",
+ "gfx/2d/numbers_alt/7",
+ "gfx/2d/numbers_alt/8",
+ "gfx/2d/numbers_alt/9",
+ "gfx/2d/numbers_alt/minus",
+ };
static char *buildWeaponTimerPieShaders[ 8 ] =
{
"ui/assets/neutral/1_5pie",
@@ -791,6 +811,9 @@ static void CG_RegisterGraphics( void )
for( i = 0; i < 11; i++ )
cgs.media.numberShaders[ i ] = trap_R_RegisterShader( sb_nums[ i ] );
+ for( i = 0; i < 11; i++ )
+ cgs.media.numberShadersAlt[ i ] = trap_R_RegisterShader( sb_nums_alt[ i ] );
+
cgs.media.viewBloodShader = trap_R_RegisterShader( "gfx/damage/fullscreen_painblend" );
cgs.media.connectionShader = trap_R_RegisterShader( "gfx/2d/net" );
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c
index 084e3f1..891c3e0 100644
--- a/src/cgame/cg_servercmds.c
+++ b/src/cgame/cg_servercmds.c
@@ -1336,6 +1336,25 @@ static void CG_GameCmds_f( void )
trap_AddCommand( CG_Argv( i ) );
}
+static void CG_DamageBlob_f( void )
+{
+ int i, count = trap_Argc( ), value, flags;
+ vec3_t origin;
+
+ for( i = 1; i + 4 < count; i += 5 )
+ {
+ origin[ 0 ] = atof( CG_Argv( i ) );
+ origin[ 1 ] = atof( CG_Argv( i + 1 ) );
+ origin[ 2 ] = atof( CG_Argv( i + 2 ) );
+ value = atoi( CG_Argv( i + 3 ) );
+ flags = atoi( CG_Argv( i + 4 ) );
+
+ CG_SpawnDamageBlob( origin, value, flags );
+
+ i += 5;
+ }
+}
+
static consoleCommand_t svcommands[ ] =
{
{ "chat", CG_Chat_f },
@@ -1343,6 +1362,7 @@ static consoleCommand_t svcommands[ ] =
{ "cmds", CG_GameCmds_f },
{ "cp", CG_CenterPrint_f },
{ "cs", CG_ConfigStringModified },
+ { "dblob", CG_DamageBlob_f },
{ "map_restart", CG_MapRestart },
{ "poisoncloud", CG_PoisonCloud_f },
{ "print", CG_Print_f },
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index f96fd66..fa93839 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -1244,3 +1244,7 @@ typedef struct
} dummyCmd_t;
int cmdcmp( const void *a, const void *b );
+// damage blob flags
+#define DAMAGE_BLOB_FRIENDLY 1
+#define DAMAGE_BLOB_BUILDABLE 2
+#define DAMAGE_BLOB_SPLASH 4
diff --git a/src/game/g_active.c b/src/game/g_active.c
index 6021a65..90c47c4 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -2236,6 +2236,45 @@ void ClientThink( int clientNum )
void G_RunClient( gentity_t *ent )
{
+ if( ent->client->bufferedBlobCount )
+ {
+ int i;
+ g_damageBlob_t *blob;
+ char *p, buffer[ 1024 ];
+
+ strcpy( buffer, "dblob" );
+ p = buffer + 5;
+
+ for( i = 0; i < ent->client->bufferedBlobCount; i++ )
+ {
+ char smallbuf[ 64 ];
+ int len;
+
+ blob = ent->client->blobBuffer + i;
+
+ Com_sprintf( smallbuf, sizeof( smallbuf ), " %.0f %.0f %.0f %d %d",
+ blob->origin[ 0 ], blob->origin[ 1 ], blob->origin[ 2 ],
+ blob->value, blob->flags );
+
+ len = strlen( smallbuf );
+
+ if( p - buffer + len + 1 > sizeof( buffer ) )
+ {
+ trap_SendServerCommand( ent - g_entities, buffer );
+ strcpy( buffer, "dblob" );
+ p = buffer + 5;
+ }
+
+ strcpy( p, smallbuf );
+ p += len;
+ }
+
+ if( p > buffer + 6 )
+ trap_SendServerCommand( ent - g_entities, buffer );
+
+ ent->client->bufferedBlobCount = 0;
+ }
+
// Run a client think when there are no commands for a time
if( !g_synchronousClients.integer &&
( g_friendlyFreeze.integer < 100 ||
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index eb7f48e..9758dc0 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -1118,6 +1118,42 @@ void G_InitDamageLocations( void )
/*
============
+G_SpawnDamageBlob
+============
+*/
+
+void G_SpawnDamageBlob(
+ gentity_t *ent, gentity_t *target, int mod,
+ int damage, vec3_t point, qboolean indirect )
+{
+ g_damageBlob_t *blob;
+ int flags = 0;
+
+ if( !ent || !ent->client || !target || ent == target )
+ return;
+
+ if( ent->client->bufferedBlobCount == MAX_BUFFERED_BLOBS )
+ return;
+
+ if( OnSameTeam( ent, target ) ||
+ ( target->s.eType == ET_BUILDABLE &&
+ ent->client->pers.teamSelection == target->buildableTeam ) )
+ flags |= DAMAGE_BLOB_FRIENDLY;
+
+ if( target->s.eType == ET_BUILDABLE )
+ flags |= DAMAGE_BLOB_BUILDABLE;
+
+ if( indirect )
+ flags |= DAMAGE_BLOB_SPLASH;
+
+ blob = ent->client->blobBuffer + (ent->client->bufferedBlobCount++);
+ VectorCopy( point, blob->origin );
+ blob->value = damage;
+ blob->flags = flags;
+}
+
+/*
+============
T_Damage
targ entity that is being damaged
@@ -1446,6 +1482,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
}
G_CombatStats_HitMOD( attacker, targ, mod, take );
+ G_SpawnDamageBlob( attacker, targ, mod, take, point, ( dflags & DAMAGE_RADIUS ) );
if( targ->health <= 0 )
{
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 30a61b0..cbf98bd 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -403,6 +403,14 @@ typedef struct unlagged_s {
qboolean used;
} unlagged_t;
+#define MAX_BUFFERED_BLOBS 20
+typedef struct
+{
+ vec3_t origin;
+ int value;
+ int flags;
+} g_damageBlob_t;
+
#define MAX_TRAMPLE_BUILDABLES_TRACKED 20
// this structure is cleared on each ClientSpawn(),
// except for 'client->pers' and 'client->sess'
@@ -511,6 +519,9 @@ struct gclient_s
int notrackEndTime; // Time when the current no track period ends
int blobs;
+
+ g_damageBlob_t blobBuffer[ MAX_BUFFERED_BLOBS ];
+ int bufferedBlobCount;
};