I just implemented the ESF (Earth Special Forces) style if someone wanna play it:
Code: Select all
#define ESF_STYLE 1 // BFP - That isn't BFP, it's Earth Special Forces (ESF) style :P
static void CG_DrawCrosshair(void) {
float w, h;
qhandle_t hShader;
float f;
float x, y;
int ca;
trace_t trace;
playerState_t *ps;
vec3_t muzzle, forward, up, start, end;
#if ESF_STYLE
static float lastPositionX = 640.0f; // BFP - Last X position for traceable crosshair to move smoothly like ESF does
#endif
static float lastPositionY = 480.0f; // BFP - Last Y position for traceable crosshair to move smoothly like BFP vanilla does
// BFP - TODO: BFP doesn't use the crosshair as player view,
// e.g. if the camera angle is 90º, the crosshair should look what's in this view,
// not what the player sees
ps = &cg.predictedPlayerState;
if ( !cg_drawCrosshair.integer ) {
return;
}
if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR) {
return;
}
// Read: https://www.quake3world.com/forum/viewtopic.php?f=16&t=55019
CG_SetCrosshairColor(); // BFP - Crosshair color
w = h = cg_crosshairSize.value;
// BFP - pulse the size of the crosshair when hitting someone (before: when picking up items)
f = cg.time - cg.opponentHitBlendTime;
if ( f > 0 && f < HIT_BLOB_TIME ) {
f /= HIT_BLOB_TIME;
// BFP - Make crosshair size starting from biggest to current
w = LERP( w*2, w, f ); // before: w *= ( 1 + f );
h = LERP( h*2, h, f ); // before: h *= ( 1 + f );
if ( cg_crosshairHealth.integer && f <= 0.35f ) { // BFP - BFP crosshair health feature
trap_R_SetColor( colorRed );
}
}
x = cg_crosshairX.integer;
y = cg_crosshairY.integer;
ca = cg_drawCrosshair.integer;
if (ca < 0) {
ca = 0;
}
hShader = cgs.media.crosshairShader[ ca % NUM_CROSSHAIRS ];
if ( cg_thirdPerson.integer >= 1 && cg_stableCrosshair.integer <= 0 ) { // BFP - Third person traceable crosshair
#if ESF_STYLE
AngleVectors( cg.snap->ps.viewangles, forward, NULL, up );
VectorCopy( cg.snap->ps.origin, muzzle );
VectorMA( muzzle, cg.snap->ps.viewheight, up, muzzle );
#else
AngleVectors( ps->viewangles, forward, NULL, up );
VectorCopy( ps->origin, muzzle );
VectorMA( muzzle, ps->viewheight, up, muzzle );
#endif
VectorMA( muzzle, 14, forward, muzzle );
VectorCopy( muzzle, start );
VectorMA( start, 131072, forward, end );
CG_Trace( &trace, start, NULL, NULL, end, cg.snap->ps.clientNum, CONTENTS_SOLID | CONTENTS_BODY );
if ( !CG_WorldCoordToScreenCoordFloat( trace.endpos, &x, &y ) ) {
return;
}
CG_AdjustFrom640( &x, &y, &w, &h );
// BFP - Make the traceable crosshair move smoothly like BFP vanilla does
// LERP( <last (or initial) position>, <destination>, (float)(cg.frametime / 1000.00f) * <speed factor> );
#if ESF_STYLE
x = LERP( lastPositionX, x, (float)(cg.frametime / 1000.00f) * 18.0f );
y = LERP( lastPositionY, y, (float)(cg.frametime / 1000.00f) * 18.0f );
#else
y = LERP( lastPositionY, y, (float)(cg.frametime / 1000.00f) * 12.0f );
#endif
trap_R_DrawStretchPic( x - 0.5f * w, // 492.799987
y - 0.5f * h,
w, h, 0, 0, 1, 1, hShader );
#if ESF_STYLE
lastPositionX = x; // last X position where it was "lerped"
#endif
lastPositionY = y; // last Y position where it was "lerped"
} else { // Q3 default crosshair position
// x: 492.799987
// y: 364.799987
CG_AdjustFrom640( &x, &y, &w, &h );
trap_R_DrawStretchPic( x + cg.refdef.x + 0.5 * (cg.refdef.width - w),
y + cg.refdef.y + 0.5 * (cg.refdef.height - h),
w, h, 0, 0, 1, 1, hShader );
}
}