rendered paste bodyvoid drawRiffleCam() {
vec3_t muzzlePoint;
// CalcMuzzlePoint
{
vec3_t forward, right, up;
AngleVectors(eth.cg_snap->ps.viewangles, forward, right, up);
VectorCopy(eth.cg_snap->ps.origin, muzzlePoint);
muzzlePoint[2] += eth.cg_snap->ps.viewheight;
// Default weapon muzzle offset
VectorMA(muzzlePoint, 6, right, muzzlePoint);
VectorMA(muzzlePoint, -4, up, muzzlePoint);
SnapVector(muzzlePoint);
}
vec3_t forward;
AngleVectors(eth.cg_snap->ps.viewangles, forward, NULL, NULL);
VectorScale(forward, 2000, forward);
trajectory_t riffleTrajectory;
riffleTrajectory.trType = TR_GRAVITY;
riffleTrajectory.trTime = eth.cg_time;
VectorCopy(muzzlePoint, riffleTrajectory.trBase);
VectorCopy(forward, riffleTrajectory.trDelta);
SnapVector(riffleTrajectory.trDelta);
// Calculate riffle impact
int timeOffset = 0;
trace_t riffleTrace;
vec3_t riffleImpact;
VectorCopy(riffleTrajectory.trBase, riffleImpact);
#define TIME_STEPP 50
int maxTime = 3250;
int totalFly = 0;
while (timeOffset < maxTime) {
vec3_t nextPos;
timeOffset += TIME_STEPP;
totalFly += TIME_STEPP;
eth.BG_EvaluateTrajectory(&riffleTrajectory, eth.cg_time + timeOffset, nextPos, qfalse, 0);
eth.CG_Trace(&riffleTrace, riffleImpact, 0, 0, nextPos, eth.cg_snap->ps.clientNum, MASK_MISSILESHOT);
// Check for hit
if (riffleTrace.startsolid || riffleTrace.fraction != 1) {
// When a nade flies for over 750ms and hits something, it'll explode
if (totalFly > 750)
break;
// Calculate reflect angle (forward axis)
int hitTime = eth.cg_time + totalFly - TIME_STEPP + TIME_STEPP * riffleTrace.fraction;
eth_BG_EvaluateTrajectoryDelta(&riffleTrajectory, hitTime, riffleTrajectory.trDelta, qfalse, 0);
float dot = DotProduct(riffleTrajectory.trDelta, riffleTrace.plane.normal);
VectorMA(riffleTrajectory.trDelta, -2*dot, riffleTrace.plane.normal, riffleTrajectory.trDelta);
// Scale down velocity
VectorScale(riffleTrajectory.trDelta, 0.35, riffleTrajectory.trDelta);
// More scale down velocity on movers
if ((riffleTrace.plane.normal[2] < 0.2) || (riffleTrace.entityNum != ENTITYNUM_WORLD))
VectorScale(riffleTrajectory.trDelta, 0.5, riffleTrajectory.trDelta);
// Calc new max time and reset trTime
maxTime -= timeOffset;
timeOffset = 0;
riffleTrajectory.trTime = eth.cg_time;
// New base origins
VectorCopy(riffleTrace.endpos, riffleTrajectory.trBase);
SnapVector(riffleTrajectory.trDelta);
SnapVector(riffleTrajectory.trBase);
} else {
VectorCopy(nextPos, riffleImpact);
#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, colorYellow);
else
drawFillRect(x - (POINT_SIZE / 2), y - (POINT_SIZE / 2), POINT_SIZE, POINT_SIZE, colorRed);
}
}
}