rendered paste body//spycams.c
void drawGrenadeCam() {
vec3_t angles, forward, viewpos;
trajectory_t grenadeTrajectory;
grenadeTrajectory.trType = TR_GRAVITY;
grenadeTrajectory.trTime = eth.cg_time;
VectorCopy(eth.muzzle, grenadeTrajectory.trBase);
VectorCopy(grenadeTrajectory.trBase, viewpos);
VectorCopy(eth.cg_snap->ps.viewangles, angles);
AngleVectors(angles, forward, NULL,NULL);
viewpos[2] += eth.cg_snap->ps.viewheight;
VectorMA(viewpos, 32, forward, viewpos);
VectorScale(forward, 2000, forward);
VectorCopy(forward, grenadeTrajectory.trDelta);
SnapVector(grenadeTrajectory.trDelta);
// Calculate Gre impact
int timeOffset = 0;
trace_t grenadeTrace;
vec3_t grenadeImpact;
VectorCopy(grenadeTrajectory.trBase, grenadeImpact);
#define TIME_STEPP 50
int maxTime = 2000;
int totalFly = 0;
while (timeOffset < maxTime) {
vec3_t nextPos;
timeOffset += TIME_STEPP;
totalFly += TIME_STEPP;
eth.BG_EvaluateTrajectory(&grenadeTrajectory, eth.cg_time + timeOffset, nextPos, qfalse, 0);
eth.CG_Trace(&grenadeTrace, grenadeImpact, 0, 0, nextPos, eth.cg_snap->ps.clientNum, MASK_MISSILESHOT);
// check for hit
if (grenadeTrace.startsolid || grenadeTrace.fraction != 1) {
// When a nade flies for over 750ms and hits something, it'll explode
if (totalFly > 350)
break;
// calculate reflect angle (forward axis)
int hitTime = eth.cg_time + totalFly - TIME_STEPP + TIME_STEPP * grenadeTrace.fraction;
eth_BG_EvaluateTrajectoryDelta(&grenadeTrajectory, hitTime, grenadeTrajectory.trDelta, qfalse, 0);
float dot = DotProduct(grenadeTrajectory.trDelta, grenadeTrace.plane.normal);
VectorMA(grenadeTrajectory.trDelta, -2*dot, grenadeTrace.plane.normal, grenadeTrajectory.trDelta);
VectorScale(grenadeTrajectory.trDelta, 0.15, grenadeTrajectory.trDelta);
if (grenadeTrace.surfaceFlags == 0)
VectorScale(grenadeTrajectory.trDelta, 0.5, grenadeTrajectory.trDelta);
// calc new max time and reset trTime
maxTime -= timeOffset;
timeOffset = 0;
grenadeTrajectory.trTime = eth.cg_time;
// new base origins
VectorCopy(grenadeTrace.endpos, grenadeTrajectory.trBase);
SnapVector(grenadeTrajectory.trDelta);
SnapVector(grenadeTrajectory.trBase);
} else {
VectorCopy(nextPos, grenadeImpact);
#define POINT_SIZE 2
int x, y;
if (worldToScreen(nextPos, &x, &y)) {
if (isVisible(nextPos))
drawFillRect(x - (POINT_SIZE / 2), y - (POINT_SIZE / 2), POINT_SIZE, POINT_SIZE, colorGreen);
else
drawFillRect(x - (POINT_SIZE / 2), y - (POINT_SIZE / 2), POINT_SIZE, POINT_SIZE, colorBlue);
}
}
}
// Set the view
refdef_t camRefDef;
// fov
camRefDef.fov_x = 80;
camRefDef.fov_y = 80;
// origin
VectorCopy(grenadeImpact, camRefDef.vieworg);
camRefDef.vieworg[ROLL] += seth.value[VAR_GRENADECAM_H]; // Up the cam
// angle
vec3_t camAngle;
VectorCopy(eth.cg_refdefViewAngles, camAngle);
camAngle[PITCH] = 80; // Look down
AnglesToAxis(camAngle, camRefDef.viewaxis);
// Draw the grenadecam
drawSpyCam(10, 10, 180, 200, &camRefDef, eth.enemyMortarShader, eth.friendMortarShader, qtrue);
// Draw impact time
char str[128];
sprintf(str, "^2%.1f ^3s", (float)totalFly / 1000.0f);
drawText(10 + (250 - sizeTextWidth(0.19f, str, ð.fontVariable)) / 2, 10 + 250 - 15, 0.19f, str, colorWhite, qfalse, qtrue, ð.fontVariable);
}
//engine.c
case WP_GRENADE_PINEAPPLE:
case WP_GRENADE_LAUNCHER:
if (seth.value[VAR_GRENADECAM])
drawGrenadeCam();
break;
//menu.h
VAR_GRENADECAM,
VAR_GRENADECAM_H,
//menu.c
seth.vars[VAR_GRENADECAM] = (ethVars_t) { "Show grenade cam", qfalse, "grenadecam", CAT_SPYCAM, qfalse,
{ { "Off", qfalse }, { "On", qtrue } } };
seth.vars[VAR_GRENADECAM_H] = (ethVars_t) { "Grenade cam height", 500.0f, "grenadecam_h", CAT_SPYCAM, qfalse,
{ { "300", 300.0f }, { "400", 400.0f }, { "500", 500.0f }, { "600", 600.0f }, { "800", 800.0f }, { "900", 900.0f }, { "1000", 1000.0f } } };