diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_consolecmds.c | 25 | ||||
-rw-r--r-- | src/cgame/cg_draw.c | 116 | ||||
-rw-r--r-- | src/cgame/cg_drawtools.c | 53 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 17 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 4 | ||||
-rw-r--r-- | src/ui/ui_shared.c | 3 |
6 files changed, 208 insertions, 10 deletions
diff --git a/src/cgame/cg_consolecmds.c b/src/cgame/cg_consolecmds.c index 697b0e98..d28c4211 100644 --- a/src/cgame/cg_consolecmds.c +++ b/src/cgame/cg_consolecmds.c @@ -188,6 +188,30 @@ static void CG_TellAttacker_f( void ) trap_SendClientCommand( command ); } +static void CG_SquadMark_f( void ) +{ + centity_t *cent; + vec3_t start, end; + trace_t trace; + + // Find the player we are looking at + VectorCopy( cg.refdef.vieworg, start ); + VectorMA( start, 131072, cg.refdef.viewaxis[ 0 ], end ); + CG_Trace( &trace, start, vec3_origin, vec3_origin, end, + cg.snap->ps.clientNum, CONTENTS_SOLID|CONTENTS_BODY ); + if( trace.entityNum >= MAX_CLIENTS ) + return; + + // Only mark teammates + cent = cg_entities + trace.entityNum; + if( cent->currentState.eType != ET_PLAYER || + cgs.clientinfo[ trace.entityNum ].team != + cg.snap->ps.stats[ STAT_PTEAM ] ) + return; + + cent->pe.squadMarked = !cent->pe.squadMarked; +} + typedef struct { char *cmd; @@ -219,6 +243,7 @@ static consoleCommand_t commands[ ] = { "destroyTestPS", CG_DestroyTestPS_f }, { "testTS", CG_TestTS_f }, { "destroyTestTS", CG_DestroyTestTS_f }, + { "squadmark", CG_SquadMark_f }, }; diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 5ae1093a..31e619c7 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -2249,7 +2249,7 @@ static void CG_DrawCrosshairNames( rectDef_t *rect, float scale, int textStyle ) CG_ScanForCrosshairEntity( ); // draw the name of the player being looked at - color = CG_FadeColor( cg.crosshairClientTime, 1000 ); + color = CG_FadeColor( cg.crosshairClientTime, CROSSHAIR_CLIENT_TIMEOUT ); if( !color ) { trap_R_SetColor( NULL ); @@ -2263,6 +2263,116 @@ static void CG_DrawCrosshairNames( rectDef_t *rect, float scale, int textStyle ) trap_R_SetColor( NULL ); } +/* +=============== +CG_DrawSquadMarkers +=============== +*/ +#define SQUAD_MARKER_W 16.0f +#define SQUAD_MARKER_H 8.0f +#define SQUAD_MARKER_BORDER 8.0f +static void CG_DrawSquadMarkers( vec4_t color ) +{ + centity_t *cent; + vec3_t origin, maxs; + qhandle_t shader; + float x, y, w, h, distance, scale, u1 = 0.0f, v1 = 0.0f, u2 = 1.0f, v2 = 1.0f; + int i, class; + qboolean vertical = qfalse, flip = qfalse; + + if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) + return; + + trap_R_SetColor( color ); + for( i = 0; i < cg.snap->numEntities; i++ ) + { + cent = cg_entities + cg.snap->entities[ i ].number; + if( cent->currentState.eType != ET_PLAYER || + cgs.clientinfo[ i ].team != cg.snap->ps.stats[ STAT_PTEAM ] || + !cent->pe.squadMarked ) + continue; + + // Find where on screen the player is + VectorCopy( cent->lerpOrigin, origin ); + origin[ 2 ] += ( ( cent->currentState.solid >> 16 ) & 255 ) - 30; + if( !CG_WorldToScreenWrap( origin, &x, &y ) ) + continue; + + // Scale the size of the marker with distance + distance = Distance( cent->lerpOrigin, cg.refdef.vieworg ); + if( !distance ) + continue; + + scale = 200.0f / distance; + + if( scale > 1.0f ) + scale = 1.0f; + + if( scale < 0.25f ) + scale = 0.25f; + + // Don't let the marker go off-screen + if( x < SQUAD_MARKER_BORDER ) + { + x = SQUAD_MARKER_BORDER; + vertical = qtrue; + flip = qfalse; + } + else if( x > 640.0f - SQUAD_MARKER_BORDER ) + { + x = 640.0f - SQUAD_MARKER_BORDER; + vertical = qtrue; + flip = qtrue; + } + + if( y < SQUAD_MARKER_BORDER ) + { + y = SQUAD_MARKER_BORDER; + vertical = qfalse; + flip = qtrue; + } + else if( y > 480.0f - SQUAD_MARKER_BORDER ) + { + y = 480.0f - SQUAD_MARKER_BORDER; + vertical = qfalse; + flip = qfalse; + } + + // Draw the marker + if( vertical ) + { + shader = cgs.media.squadMarkerV; + + if( flip ) + { + u1 = 1.0f; + u2 = 0.0f; + } + + w = SQUAD_MARKER_H * scale; + h = SQUAD_MARKER_W * scale; + } + else + { + shader = cgs.media.squadMarkerH; + + if( flip ) + { + v1 = 1.0f; + v2 = 0.0f; + } + + w = SQUAD_MARKER_W * scale; + h = SQUAD_MARKER_H * scale; + } + + CG_AdjustFrom640( &x, &y, &w, &h ); + trap_R_DrawStretchPic( x - w / 2, y - h / 2, w, h, u1, v1, u2, v2, + shader ); + } + + trap_R_SetColor( NULL ); +} /* =============== @@ -2391,6 +2501,9 @@ void CG_OwnerDraw( float x, float y, float w, float h, float text_x, case CG_HUMANS_SCORE_LABEL: CG_DrawTeamLabel( &rect, PTE_HUMANS, text_x, text_y, color, scale, textalign, textvalign, textStyle ); break; + case CG_SQUAD_MARKERS: + CG_DrawSquadMarkers( color ); + break; //loading screen case CG_LOAD_LEVELSHOT: @@ -2977,7 +3090,6 @@ static void CG_Draw2D( void ) CG_DrawLighting( ); - defaultMenu = Menus_FindByName( "default_hud" ); if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) diff --git a/src/cgame/cg_drawtools.c b/src/cgame/cg_drawtools.c index 06ae0713..fb34f991 100644 --- a/src/cgame/cg_drawtools.c +++ b/src/cgame/cg_drawtools.c @@ -349,6 +349,59 @@ qboolean CG_WorldToScreen( vec3_t point, float *x, float *y ) /* ================ +CG_WorldToScreenWrap +================ +*/ +qboolean CG_WorldToScreenWrap( vec3_t point, float *x, float *y ) +{ + vec3_t trans; + float px, py, dotForward, dotRight, dotUp, distance, propX, propY; + + px = tan( cg.refdef.fov_x * M_PI / 360.0f ); + py = tan( cg.refdef.fov_y * M_PI / 360.0f ); + + VectorSubtract( point, cg.refdef.vieworg, trans ); + + dotForward = DotProduct( trans, cg.refdef.viewaxis[ 0 ] ); + dotRight = DotProduct( trans, cg.refdef.viewaxis[ 1 ] ); + dotUp = DotProduct( trans, cg.refdef.viewaxis[ 2 ] ); + + distance = abs( dotForward ); + propX = dotRight / ( distance * px ); + propY = dotUp / ( distance * py ); + + // The distance along the forward axis does not make sense once the point + // moves off-screen so we need to use either the side or the up axis instead + if( propX < -1.0f || propX > 1.0f ) + { + distance = abs( dotRight ) / px; + propY = dotUp / ( distance * py ); + } + if( propY < -1.0f || propY > 1.0f ) + { + distance = abs( dotUp ) / py; + propX = dotRight / ( distance * px ); + } + + if( x ) + *x = 320 - propX * 320; + if( y ) + *y = 240 - propY * 240; + + // Snap to the edge of the screen when the point is behind us + if( dotForward < 0.f && *x > 0 && *x < 640 && *y > 0 && *y < 480 ) + { + if( abs( *x - 320 ) > abs( *y - 240 ) ) + *x = *x <= 320 ? 0.0f : 640; + else + *y = *y <= 240 ? 0.0f : 480; + } + + return qtrue; +} + +/* +================ CG_KeyBinding ================ */ diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 74e43bea..891edbd4 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -572,6 +572,8 @@ typedef struct lerpFrame_t legs, torso, flag, nonseg; int painTime; int painDirection; // flip from 0 to 1 + + qboolean squadMarked; // player has been marked as a squadmember // machinegun spinning float barrelAngle; @@ -713,7 +715,7 @@ typedef struct char name[ MAX_QPATH ]; pTeam_t team; - + vec3_t color1; vec3_t color2; @@ -725,12 +727,6 @@ typedef struct int handicap; - int medkitUsageTime; - int invulnerabilityStartTime; - int invulnerabilityStopTime; - - int breathPuffTime; - // when clientinfo is changed, the loading of models/skins/sounds // can be deferred until you are dead, to prevent hitches in // gameplay @@ -901,6 +897,9 @@ typedef struct #define NUM_SAVED_STATES ( CMD_BACKUP + 2 ) +// After this many msec the crosshair name fades out completely +#define CROSSHAIR_CLIENT_TIMEOUT 1000 + typedef struct { int clientFrame; // incremented each frame @@ -1284,6 +1283,9 @@ typedef struct qhandle_t healthCross3X; qhandle_t healthCrossMedkit; qhandle_t healthCrossPoisoned; + + qhandle_t squadMarkerH; + qhandle_t squadMarkerV; } cgMedia_t; typedef struct @@ -1606,6 +1608,7 @@ void CG_DrawRect( float x, float y, float width, float height, float size void CG_DrawSides(float x, float y, float w, float h, float size); void CG_DrawTopBottom(float x, float y, float w, float h, float size); qboolean CG_WorldToScreen( vec3_t point, float *x, float *y ); +qboolean CG_WorldToScreenWrap( vec3_t point, float *x, float *y ); char *CG_KeyBinding( const char *bind ); diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index 67db0a61..c094ffee 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -852,6 +852,10 @@ static void CG_RegisterGraphics( void ) cgs.media.healthCross3X = trap_R_RegisterShader( "ui/assets/neutral/cross3.tga" ); cgs.media.healthCrossMedkit = trap_R_RegisterShader( "ui/assets/neutral/cross_medkit.tga" ); cgs.media.healthCrossPoisoned = trap_R_RegisterShader( "ui/assets/neutral/cross_poison.tga" ); + + // squad markers + cgs.media.squadMarkerH = trap_R_RegisterShader( "ui/assets/neutral/squad_h" ); + cgs.media.squadMarkerV = trap_R_RegisterShader( "ui/assets/neutral/squad_v" ); cgs.media.upgradeClassIconShader = trap_R_RegisterShader( "icons/icona_upgrade.tga" ); diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c index 8351f6fd..4513eb85 100644 --- a/src/ui/ui_shared.c +++ b/src/ui/ui_shared.c @@ -5110,7 +5110,8 @@ static bind_t g_bindings[] = { "messagemode", -1, -1, -1, -1 }, { "messagemode2", -1, -1, -1, -1 }, { "messagemode3", -1, -1, -1, -1 }, - { "messagemode4", -1, -1, -1, -1 } + { "messagemode4", -1, -1, -1, -1 }, + { "squadmark", 'k', -1, -1, -1 }, }; |