float CGVM_TracePhysics(const float *start, const float *end, const float *worldmins, const float *worldmaxs, const float *entitymins, const float *entitymaxs, const cgphysentity_t *physentities, const int numphysentities, float *impactpos, float *impactnormal, int *impactentnum)
{
- float frac;
- vec3_t start2, end2, middle;
+ trace_t trace;
// FIXME: do tracing agains network entities and physentities here
- // placeholder world only code assuming 0 size
- middle[0] = (worldmins[0] + worldmaxs[0]) * 0.5f;
- middle[1] = (worldmins[1] + worldmaxs[1]) * 0.5f;
- middle[2] = (worldmins[2] + worldmaxs[2]) * 0.5f;
- VectorAdd(start, middle, start2);
- VectorAdd(end, middle, end2);
- frac = CL_TraceLine((float *)start2, (float *)end2, impactpos, impactnormal, true, NULL, SUPERCONTENTS_SOLID);
- VectorSubtract(impactpos, middle, impactpos);
+ trace = CL_TraceBox(start, vec3_origin, vec3_origin, end, true, NULL, SUPERCONTENTS_SOLID, false);
+ VectorCopy(trace.endpos, impactpos);
+ VectorCopy(trace.plane.normal, impactnormal);
*impactentnum = -1;
- return frac;
+ return trace.fraction;
}
char *CGVM_GetCvarString(const char *name)
physentity_t;
*/
-int cl_traceline_startsupercontents;
-
-float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int hitbmodels, int *hitent, int hitsupercontentsmask)
+trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers)
{
- float maxfrac, maxrealfrac;
int n;
entity_render_t *ent;
- float tracemins[3], tracemaxs[3];
- trace_t trace;
- float tempnormal[3], starttransformed[3], endtransformed[3];
+ vec3_t tracemins, tracemaxs;
+ trace_t cliptrace, trace;
+ vec3_t starttransformed, endtransformed, starttransformedmins, endtransformedmins, starttransformedmaxs, endtransformedmaxs;
+ vec3_t startmins, startmaxs, endmins, endmaxs, entmins, entmaxs;
+ vec_t *playermins, *playermaxs;
- memset (&trace, 0 , sizeof(trace_t));
- trace.fraction = 1;
- trace.realfraction = 1;
- VectorCopy (end, trace.endpos);
+ VectorAdd(start, mins, startmins);
+ VectorAdd(start, maxs, startmaxs);
+ VectorAdd(end, mins, endmins);
+ VectorAdd(end, maxs, endmaxs);
+
+ memset (&cliptrace, 0 , sizeof(trace_t));
+ cliptrace.fraction = 1;
+ cliptrace.realfraction = 1;
- if (hitent)
- *hitent = 0;
Mod_CheckLoaded(cl.worldmodel);
if (cl.worldmodel && cl.worldmodel->TraceBox)
- cl.worldmodel->TraceBox(cl.worldmodel, 0, &trace, start, start, end, end, hitsupercontentsmask);
+ cl.worldmodel->TraceBox(cl.worldmodel, 0, &cliptrace, startmins, startmaxs, endmins, endmaxs, hitsupercontentsmask);
- if (normal)
- VectorCopy(trace.plane.normal, normal);
- cl_traceline_startsupercontents = trace.startsupercontents;
- maxfrac = trace.fraction;
- maxrealfrac = trace.realfraction;
+ if (hitent)
+ *hitent = 0;
if (hitbmodels && cl_num_brushmodel_entities)
{
- tracemins[0] = min(start[0], end[0]);
- tracemaxs[0] = max(start[0], end[0]);
- tracemins[1] = min(start[1], end[1]);
- tracemaxs[1] = max(start[1], end[1]);
- tracemins[2] = min(start[2], end[2]);
- tracemaxs[2] = max(start[2], end[2]);
+ tracemins[0] = min(start[0], end[0]) + mins[0];
+ tracemaxs[0] = max(start[0], end[0]) + maxs[0];
+ tracemins[1] = min(start[1], end[1]) + mins[1];
+ tracemaxs[1] = max(start[1], end[1]) + maxs[1];
+ tracemins[2] = min(start[2], end[2]) + mins[2];
+ tracemaxs[2] = max(start[2], end[2]) + maxs[2];
// look for embedded bmodels
for (n = 0;n < cl_num_brushmodel_entities;n++)
Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
+ VectorAdd(starttransformed, mins, starttransformedmins);
+ VectorAdd(starttransformed, maxs, starttransformedmaxs);
+ VectorAdd(endtransformed, mins, endtransformedmins);
+ VectorAdd(endtransformed, maxs, endtransformedmaxs);
+
+ memset (&trace, 0 , sizeof(trace_t));
+ trace.fraction = 1;
+ trace.realfraction = 1;
if (ent->model && ent->model->TraceBox)
- ent->model->TraceBox(ent->model, 0, &trace, starttransformed, starttransformed, endtransformed, endtransformed, hitsupercontentsmask);
+ ent->model->TraceBox(ent->model, 0, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs, hitsupercontentsmask);
- cl_traceline_startsupercontents |= trace.startsupercontents;
- if (maxrealfrac > trace.realfraction)
+ // LordHavoc: take the 'best' answers from the new trace and combine with existing data
+ if (trace.allsolid)
+ cliptrace.allsolid = true;
+ if (trace.startsolid)
{
+ cliptrace.startsolid = true;
+ if (cliptrace.realfraction == 1)
+ if (hitent)
+ *hitent = cl_brushmodel_entities[n];
+ }
+ // don't set this except on the world, because it can easily confuse
+ // monsters underwater if there's a bmodel involved in the trace
+ // (inopen && inwater is how they check water visibility)
+ //if (trace.inopen)
+ // cliptrace.inopen = true;
+ if (trace.inwater)
+ cliptrace.inwater = true;
+ if (trace.realfraction < cliptrace.realfraction)
+ {
+ cliptrace.fraction = trace.fraction;
+ cliptrace.realfraction = trace.realfraction;
+ cliptrace.plane = trace.plane;
if (hitent)
*hitent = cl_brushmodel_entities[n];
- maxfrac = trace.fraction;
- maxrealfrac = trace.realfraction;
- if (normal)
+ Matrix4x4_Transform3x3(&ent->matrix, trace.plane.normal, cliptrace.plane.normal);
+ }
+ cliptrace.startsupercontents |= trace.startsupercontents;
+ }
+ }
+ if (hitplayers)
+ {
+ tracemins[0] = min(start[0], end[0]) + mins[0];
+ tracemaxs[0] = max(start[0], end[0]) + maxs[0];
+ tracemins[1] = min(start[1], end[1]) + mins[1];
+ tracemaxs[1] = max(start[1], end[1]) + maxs[1];
+ tracemins[2] = min(start[2], end[2]) + mins[2];
+ tracemaxs[2] = max(start[2], end[2]) + maxs[2];
+
+ for (n = 1;n < cl.maxclients+1;n++)
+ {
+ if (n != cl.playerentity)
+ {
+ ent = &cl_entities[n].render;
+ // FIXME: crouch
+ playermins = cl_playerstandmins;
+ playermaxs = cl_playerstandmaxs;
+ VectorAdd(ent->origin, playermins, entmins);
+ VectorAdd(ent->origin, playermaxs, entmaxs);
+ if (!BoxesOverlap(tracemins, tracemaxs, entmins, entmaxs))
+ continue;
+
+ memset (&trace, 0 , sizeof(trace_t));
+ trace.fraction = 1;
+ trace.realfraction = 1;
+
+ Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
+ Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
+ Collision_ClipTrace_Box(&trace, playermins, playermaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, SUPERCONTENTS_SOLID);
+
+ // LordHavoc: take the 'best' answers from the new trace and combine with existing data
+ if (trace.allsolid)
+ cliptrace.allsolid = true;
+ if (trace.startsolid)
+ {
+ cliptrace.startsolid = true;
+ if (cliptrace.realfraction == 1)
+ if (hitent)
+ *hitent = n;
+ }
+ // don't set this except on the world, because it can easily confuse
+ // monsters underwater if there's a bmodel involved in the trace
+ // (inopen && inwater is how they check water visibility)
+ //if (trace.inopen)
+ // cliptrace.inopen = true;
+ if (trace.inwater)
+ cliptrace.inwater = true;
+ if (trace.realfraction < cliptrace.realfraction)
{
- VectorCopy(trace.plane.normal, tempnormal);
- Matrix4x4_Transform3x3(&ent->matrix, tempnormal, normal);
+ cliptrace.fraction = trace.fraction;
+ cliptrace.realfraction = trace.realfraction;
+ cliptrace.plane = trace.plane;
+ if (hitent)
+ *hitent = n;
+ Matrix4x4_Transform3x3(&ent->matrix, trace.plane.normal, cliptrace.plane.normal);
}
+ cliptrace.startsupercontents |= trace.startsupercontents;
}
}
}
- maxfrac = bound(0, maxfrac, 1);
- maxrealfrac = bound(0, maxrealfrac, 1);
- //if (maxfrac < 0 || maxfrac > 1) Con_Printf("fraction out of bounds %f %s:%d\n", maxfrac, __FILE__, __LINE__);
- if (impact)
- VectorLerp(start, maxfrac, end, impact);
- return maxfrac;
+ cliptrace.fraction = bound(0, cliptrace.fraction, 1);
+ cliptrace.realfraction = bound(0, cliptrace.realfraction, 1);
+ VectorLerp(start, cliptrace.fraction, end, cliptrace.endpos);
+ return cliptrace;
}
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent)
if (normal)
VectorCopy(trace.plane.normal, normal);
- cl_traceline_startsupercontents = trace.startsupercontents;
+ //cl_traceline_startsupercontents = trace.startsupercontents;
maxfrac = trace.fraction;
maxrealfrac = trace.realfraction;
if (ent->model && ent->model->TraceBox)
ent->model->TraceBox(ent->model, ent->frameblend[0].frame, &trace, starttransformed, starttransformed, endtransformed, endtransformed, SUPERCONTENTS_SOLID);
- cl_traceline_startsupercontents |= trace.startsupercontents;
+ //cl_traceline_startsupercontents |= trace.startsupercontents;
if (maxrealfrac > trace.realfraction)
{
if (hitent)
int CL_PointQ1Contents(const vec3_t p)
{
- CL_TraceLine(p, p, NULL, NULL, true, NULL, 0);
- return Mod_Q1BSP_NativeContentsFromSuperContents(NULL, cl_traceline_startsupercontents);
+ return Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_TraceBox(p, vec3_origin, vec3_origin, p, true, NULL, 0, false).startsupercontents);
/*
// FIXME: check multiple brush models
if (cl.worldmodel && cl.worldmodel->brush.PointContentsQ1)
int CL_PointSuperContents(const vec3_t p)
{
- CL_TraceLine(p, p, NULL, NULL, true, NULL, 0);
- return cl_traceline_startsupercontents;
+ return CL_TraceBox(p, vec3_origin, vec3_origin, p, true, NULL, 0, false).startsupercontents;
/*
// FIXME: check multiple brush models
if (cl.worldmodel && cl.worldmodel->brush.PointContentsQ1)
#ifndef CL_COLLISION_H
#define CL_COLLISION_H
-// if contents is not zero, it will impact on content changes
-// (leafs matching contents are considered empty, others are solid)
-extern int cl_traceline_startcontents; // set by TraceLine
-
-float CL_TraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int hitbmodels, int *hitent, int hitsupercontentsmask);
+trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers);
float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, vec3_t normal, int *hitent, entity_render_t *ignoreent);
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
int CL_PointQ1Contents(const vec3_t p);
cvar_t cl_anglespeedkey = {CVAR_SAVE, "cl_anglespeedkey","1.5"};
+cvar_t cl_movement = {CVAR_SAVE, "cl_movement", "0"};
+cvar_t cl_movement_latency = {0, "cl_movement_latency", "0"};
+cvar_t cl_movement_maxspeed = {0, "cl_movement_maxspeed", "320"};
+cvar_t cl_movement_maxairspeed = {0, "cl_movement_maxairspeed", "30"};
+cvar_t cl_movement_stopspeed = {0, "cl_movement_stopspeed", "100"};
+cvar_t cl_movement_friction = {0, "cl_movement_friction", "4"};
+cvar_t cl_movement_edgefriction = {0, "cl_movement_edgefriction", "2"};
+cvar_t cl_movement_stepheight = {0, "cl_movement_stepheight", "18"};
+cvar_t cl_movement_accelerate = {0, "cl_movement_accelerate", "10"};
+cvar_t cl_gravity = {0, "cl_gravity", "800"};
+cvar_t cl_slowmo = {0, "cl_slowmo", "1"};
+
+
/*
================
CL_AdjustAngles
//CL_SparkShower(cl.cmd.cursor_impact, cl.cmd.cursor_normal, 5, 0);
}
+void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
+{
+ int i, n, bump, contents, crouch;
+ //double simulatedtime;
+ double currenttime;
+ double newtime;
+ double frametime;
+ double t;
+ vec_t wishspeed, addspeed, accelspeed, f, *playermins, *playermaxs;
+ client_movementqueue_t *q;
+ vec3_t currentorigin, currentvelocity, forward, right, up, wishvel, wishdir, neworigin, currentorigin2, neworigin2, yawangles;
+ trace_t trace, trace2, trace3;
+ // remove stale queue items
+ n = cl.movement_numqueue;
+ cl.movement_numqueue = 0;
+ for (i = 0;i < n;i++)
+ if (cl.movement_queue[i].time >= cl.mtime[0])
+ cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
+ // add to input queue if there is room
+ if (cl.movement_numqueue < sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0]))
+ {
+ // add to input queue
+ cl.movement_queue[cl.movement_numqueue].time = cl.mtime[0] + cl_movement_latency.value;
+ VectorCopy(cl.viewangles, cl.movement_queue[cl.movement_numqueue].viewangles);
+ cl.movement_queue[cl.movement_numqueue].move[0] = cl.cmd.forwardmove;
+ cl.movement_queue[cl.movement_numqueue].move[1] = cl.cmd.sidemove;
+ cl.movement_queue[cl.movement_numqueue].move[2] = cl.cmd.upmove;
+ cl.movement_queue[cl.movement_numqueue].jump = buttonjump;
+ cl.movement_queue[cl.movement_numqueue].crouch = buttoncrouch;
+ cl.movement_numqueue++;
+ }
+ cl.movement = false;
+ // abort if client movement is disabled
+ if (!cl_movement.integer || cl.stats[STAT_HEALTH] <= 0)
+ return;
+ // fetch current starting values
+ currenttime = cl.mtime[0];
+ VectorCopy(cl_entities[cl.playerentity].state_current.origin, currentorigin);
+ VectorCopy(cl.mvelocity[0], currentvelocity);
+ // calculate time to execute for
+ //simulatedtime = currenttime + cl_movement_latency.value;
+ // FIXME: try minor nudges in various directions if startsolid to find a
+ // safe place to start the walk (due to network compression in some
+ // protocols this starts in solid)
+ //currentorigin[2] += (1.0 / 32.0); // slight nudge to get out of the floor
+ crouch = false; // this will be updated on first move
+ //Con_Printf("%f: ", currenttime);
+ // replay input queue, and remove any stale queue items
+ // note: this relies on the fact there's always one queue item at the end
+ for (i = 0, q = cl.movement_queue;i < cl.movement_numqueue;i++, q++)
+ {
+ //newtime = (i == cl.movement_numqueue) ? simulatedtime : q->time;
+ newtime = q->time;
+ frametime = newtime - currenttime;
+ if (frametime < 0)
+ continue;
+ //Con_Printf(" %f", frametime);
+ currenttime = newtime;
+ if (crouch)
+ {
+ playermins = cl_playercrouchmins;
+ playermaxs = cl_playercrouchmaxs;
+ }
+ else
+ {
+ playermins = cl_playerstandmins;
+ playermaxs = cl_playerstandmaxs;
+ }
+ for (bump = 0, t = frametime;bump < 8 && VectorLength2(currentvelocity) > 0;bump++)
+ {
+ VectorMA(currentorigin, t, currentvelocity, neworigin);
+ trace = CL_TraceBox(currentorigin, playermins, playermaxs, neworigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ if (trace.fraction < 1 && trace.plane.normal[2] == 0)
+ {
+ // may be a step or wall, try stepping up
+ // first move forward at a higher level
+ VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + cl_movement_stepheight.value);
+ VectorSet(neworigin2, neworigin[0], neworigin[1], currentorigin[2] + cl_movement_stepheight.value);
+ trace2 = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ // then move down from there
+ VectorCopy(trace2.endpos, currentorigin2);
+ VectorSet(neworigin2, trace2.endpos[0], trace2.endpos[1], currentorigin[2]);
+ trace3 = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ //Con_Printf("%f %f %f %f : %f %f %f %f : %f %f %f %f\n", trace.fraction, trace.endpos[0], trace.endpos[1], trace.endpos[2], trace2.fraction, trace2.endpos[0], trace2.endpos[1], trace2.endpos[2], trace3.fraction, trace3.endpos[0], trace3.endpos[1], trace3.endpos[2]);
+ // accept the new trace if it made some progress
+ if (fabs(trace3.endpos[0] - trace.endpos[0]) >= 0.03125 || fabs(trace3.endpos[1] - trace.endpos[1]) >= 0.03125)
+ {
+ trace = trace2;
+ VectorCopy(trace3.endpos, trace.endpos);
+ }
+ }
+ if (trace.fraction == 1)
+ {
+ VectorCopy(trace.endpos, currentorigin);
+ break;
+ }
+ t *= 1 - trace.fraction;
+ if (trace.fraction >= 0.001)
+ VectorCopy(trace.endpos, currentorigin);
+ f = DotProduct(currentvelocity, trace.plane.normal);
+ VectorMA(currentvelocity, -f, trace.plane.normal, currentvelocity);
+ }
+ if (i < cl.movement_numqueue)
+ {
+ if (q->crouch)
+ {
+ // wants to crouch, this always works...
+ if (!crouch)
+ crouch = true;
+ }
+ else
+ {
+ // wants to stand, if currently crouching we need to check for a
+ // low ceiling first
+ if (crouch)
+ {
+ trace = CL_TraceBox(currentorigin, cl_playerstandmins, cl_playerstandmaxs, currentorigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ if (!trace.startsolid)
+ crouch = false;
+ }
+ }
+ // change velocity according to q->viewangles and q->move
+ contents = CL_PointSuperContents(currentorigin);
+ if (contents & SUPERCONTENTS_LIQUIDSMASK)
+ {
+ // swim
+ AngleVectors(q->viewangles, forward, right, up);
+ VectorSet(up, 0, 0, 1);
+ VectorMAMAM(q->move[0], forward, q->move[1], right, q->move[2], up, wishvel);
+ wishspeed = VectorLength(wishvel);
+ if (wishspeed)
+ VectorScale(wishvel, 1 / wishspeed, wishdir);
+ wishspeed = min(wishspeed, cl_movement_maxspeed.value);
+ if (crouch)
+ wishspeed *= 0.5;
+ wishspeed *= 0.6;
+ VectorScale(currentvelocity, (1 - frametime * cl_movement_friction.value), currentvelocity);
+ f = wishspeed - DotProduct(currentvelocity, wishdir);
+ if (f > 0)
+ {
+ f = min(f, cl_movement_accelerate.value * frametime * wishspeed);
+ VectorMA(currentvelocity, f, wishdir, currentvelocity);
+ }
+ if (q->jump)
+ {
+ if (contents & SUPERCONTENTS_LAVA)
+ currentvelocity[2] = 50;
+ else if (contents & SUPERCONTENTS_SLIME)
+ currentvelocity[2] = 80;
+ else
+ {
+ if (gamemode == GAME_NEXUIZ)
+ currentvelocity[2] = 200;
+ else
+ currentvelocity[2] = 100;
+ }
+ }
+ }
+ else
+ {
+ // walk
+ VectorSet(yawangles, 0, cl.viewangles[1], 0);
+ AngleVectors(yawangles, forward, right, up);
+ VectorMAM(q->move[0], forward, q->move[1], right, wishvel);
+ wishspeed = VectorLength(wishvel);
+ if (wishspeed)
+ VectorScale(wishvel, 1 / wishspeed, wishdir);
+ wishspeed = min(wishspeed, cl_movement_maxspeed.value);
+ if (crouch)
+ wishspeed *= 0.5;
+ // check if onground
+ VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + 1);
+ VectorSet(neworigin2, currentorigin[0], currentorigin[1], currentorigin[2] - 1);
+ trace = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ if (trace.fraction < 1 && trace.plane.normal[2] > 0.7)
+ {
+ // apply ground friction
+ f = sqrt(currentvelocity[0] * currentvelocity[0] + currentvelocity[1] * currentvelocity[1]);
+ VectorSet(currentorigin2, currentorigin[0] + currentvelocity[0]*(16/f), currentorigin[1] + currentvelocity[1]*(16/f), currentorigin[2] + playermins[2]);
+ VectorSet(neworigin2, currentorigin2[0], currentorigin2[1], currentorigin2[2] - 34);
+ trace = CL_TraceBox(currentorigin2, vec3_origin, vec3_origin, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ // apply friction
+ f = 1 - frametime * (trace.fraction == 1 ? cl_movement_edgefriction.value : 1) * ((f < cl_movement_stopspeed.value) ? (cl_movement_stopspeed.value / f) : 1) * cl_movement_friction.value;
+ f = max(f, 0);
+ VectorScale(currentvelocity, f, currentvelocity);
+ }
+ else
+ {
+ // apply air speed limit
+ wishspeed = min(wishspeed, cl_movement_maxairspeed.value);
+ }
+ if (gamemode == GAME_NEXUIZ)
+ addspeed = wishspeed;
+ else
+ addspeed = wishspeed - DotProduct(currentvelocity, wishdir);
+ if (addspeed > 0)
+ {
+ accelspeed = min(cl_movement_accelerate.value * frametime * wishspeed, addspeed);
+ VectorMA(currentvelocity, accelspeed, wishdir, currentvelocity);
+ }
+ currentvelocity[2] -= cl_gravity.value * frametime;
+ }
+ }
+ }
+ //Con_Printf(" :%f\n", currenttime);
+ // store replay location
+ cl.movement = true;
+ VectorCopy(cl.movement_origin, cl.movement_oldorigin);
+ VectorCopy(currentorigin, cl.movement_origin);
+ //VectorCopy(currentorigin, cl_entities[cl.playerentity].state_current.origin);
+ //VectorSet(cl_entities[cl.playerentity].state_current.angles, 0, cl.viewangles[1], 0);
+}
+
/*
==============
CL_SendMove
int bits;
sizebuf_t buf;
qbyte data[128];
- static double nextmovetime = 0;
#define MOVEAVERAGING 0
#if MOVEAVERAGING
static float forwardmove, sidemove, upmove, total; // accumulation
float forwardmove, sidemove, upmove;
#endif
- CL_UpdatePrydonCursor();
-
#if MOVEAVERAGING
// accumulate changes between messages
forwardmove += cl.cmd.forwardmove;
upmove += cl.cmd.upmove;
total++;
#endif
- // LordHavoc: cap outgoing movement messages to sys_ticrate
- nextmovetime = bound(realtime - sys_ticrate.value, nextmovetime, realtime + sys_ticrate.value);
- if (!cl.islocalgame && realtime < nextmovetime)
+ if (cls.signon != SIGNONS)
return;
- nextmovetime += sys_ticrate.value;
#if MOVEAVERAGING
// average the accumulated changes
total = 1.0f / total;
if (!buf.cursize)
return;
+ // FIXME: bits & 64 is +button5, Nexuiz specific
+ CL_ClientMovement((bits & 2) != 0, (bits & 64) != 0);
+
if (NetConn_SendUnreliableMessage(cls.netcon, &buf) == -1)
{
Con_Print("CL_SendMove: lost server connection\n");
Cmd_AddCommand ("-button7", IN_Button7Up);
Cmd_AddCommand ("+button8", IN_Button8Down);
Cmd_AddCommand ("-button8", IN_Button8Up);
+
+ Cvar_RegisterVariable(&cl_movement);
+ Cvar_RegisterVariable(&cl_movement_latency);
+ Cvar_RegisterVariable(&cl_movement_maxspeed);
+ Cvar_RegisterVariable(&cl_movement_maxairspeed);
+ Cvar_RegisterVariable(&cl_movement_stopspeed);
+ Cvar_RegisterVariable(&cl_movement_friction);
+ Cvar_RegisterVariable(&cl_movement_edgefriction);
+ Cvar_RegisterVariable(&cl_movement_stepheight);
+ Cvar_RegisterVariable(&cl_movement_accelerate);
+ Cvar_RegisterVariable(&cl_gravity);
+ Cvar_RegisterVariable(&cl_slowmo);
}
cvar_t cl_prydoncursor = {0, "cl_prydoncursor", "0"};
+vec3_t cl_playerstandmins;
+vec3_t cl_playerstandmaxs;
+vec3_t cl_playercrouchmins;
+vec3_t cl_playercrouchmaxs;
+
mempool_t *cl_mempool;
client_static_t cls;
cl_entities[i].state_current = defaultstate;
}
+ if (gamemode == GAME_NEXUIZ)
+ {
+ VectorSet(cl_playerstandmins, -16, -16, -24);
+ VectorSet(cl_playerstandmaxs, 16, 16, 45);
+ VectorSet(cl_playercrouchmins, -16, -16, -24);
+ VectorSet(cl_playercrouchmaxs, 16, 16, 25);
+ }
+ else
+ {
+ VectorSet(cl_playerstandmins, -16, -16, -24);
+ VectorSet(cl_playerstandmaxs, 16, 16, 24);
+ VectorSet(cl_playercrouchmins, -16, -16, -24);
+ VectorSet(cl_playercrouchmaxs, 16, 16, 24);
+ }
+
CL_Screen_NewMap();
CL_Particles_Clear();
CL_CGVM_Clear();
matrix4x4_t *matrix, blendmatrix, tempmatrix, matrix2;
//matrix4x4_t dlightmatrix;
int j, k, l, trailtype, temp;
- float origin[3], angles[3], delta[3], lerp, dlightcolor[3], dlightradius, mins[3], maxs[3], v[3], v2[3], d;
+ float origin[3], angles[3], delta[3], lerp, dlightcolor[3], dlightradius, mins[3], maxs[3], v2[3], d;
entity_t *t;
model_t *model;
+ trace_t trace;
//entity_persistent_t *p = &e->persistent;
//entity_render_t *r = &e->render;
if (e->persistent.linkframe != entitylinkframenumber)
}
// movement lerp
- if (e->persistent.lerpdeltatime > 0 && (lerp = (cl.time - e->persistent.lerpstarttime) / e->persistent.lerpdeltatime) < 1)
+ // if it's the player entity, update according to client movement
+ if (e == cl_entities + cl.playerentity && cl.movement)
+ {
+ lerp = (cl.time - cl.mtime[0]) / (cl.mtime[0] - cl.mtime[1]);
+ lerp = bound(0, lerp, 1);
+ VectorLerp(cl.movement_oldorigin, lerp, cl.movement_origin, origin);
+ VectorSet(angles, 0, cl.viewangles[1], 0);
+ }
+ else if (e->persistent.lerpdeltatime > 0 && (lerp = (cl.time - e->persistent.lerpstarttime) / e->persistent.lerpdeltatime) < 1)
{
// interpolate the origin and angles
VectorLerp(e->persistent.oldorigin, lerp, e->persistent.neworigin, origin);
if (e->persistent.muzzleflash > 0)
{
Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
- CL_TraceLine(origin, v2, v, NULL, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY);
+ trace = CL_TraceBox(origin, vec3_origin, vec3_origin, v2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
tempmatrix = e->render.matrix;
- tempmatrix.m[0][3] = v[0];
- tempmatrix.m[1][3] = v[1];
- tempmatrix.m[2][3] = v[2];
+ tempmatrix.m[0][3] = trace.endpos[0];
+ tempmatrix.m[1][3] = trace.endpos[1];
+ tempmatrix.m[2][3] = trace.endpos[2];
CL_AllocDlight(NULL, &tempmatrix, 100, e->persistent.muzzleflash, e->persistent.muzzleflash, e->persistent.muzzleflash, 0, 0, 0, -1, true, 0, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
e->persistent.muzzleflash -= cl.frametime * 10;
}
CL_SendCmd
=================
*/
+void CL_UpdatePrydonCursor(void);
void CL_SendCmd(void)
{
if (cls.signon == SIGNONS)
- CL_SendMove();
+ CL_UpdatePrydonCursor();
if (cls.demoplayback)
{
qbyte cmdlog[32];
char *cmdlogname[32], *temp;
int cmdindex, cmdcount = 0;
+ qboolean sendmove = false;
if (cls.demorecording)
CL_WriteDemoMessage ();
case svc_time:
cl.mtime[1] = cl.mtime[0];
cl.mtime[0] = MSG_ReadFloat ();
+ sendmove = true;
break;
case svc_clientdata:
EntityFrameQuake_ISeeDeadEntities();
+ if (sendmove)
+ {
+ // send one move per server frame
+ CL_SendMove();
+ }
+
parsingerror = false;
}
#include "pmove.h"
extern qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace);
#endif
-float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int hitbmodels, int *hitent, int hitsupercontentsmask)
+trace_t CL_TraceBox (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitbmodels, int *hitent, int hitsupercontentsmask, qboolean hitplayers)
{
#if QW
pmtrace_t trace;
#else
RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
#endif
- VectorCopy(trace.endpos, impact);
- VectorCopy(trace.plane.normal, normal);
- return trace.fraction;
+ return trace;
}
#else
#include "cl_collision.h"
{
int i;
float bestfrac, bestorg[3], bestnormal[3];
- float frac, v[3], normal[3], org2[3];
+ float org2[3];
int besthitent = 0, hitent;
+ trace_t trace;
bestfrac = 10;
for (i = 0;i < 32;i++)
{
VectorRandom(org2);
VectorMA(org, maxdist, org2, org2);
- frac = CL_TraceLine(org, org2, v, normal, true, &hitent, SUPERCONTENTS_SOLID);
- if (bestfrac > frac)
+ trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, &hitent, SUPERCONTENTS_SOLID, false);
+ if (bestfrac > trace.fraction)
{
- bestfrac = frac;
+ bestfrac = trace.fraction;
besthitent = hitent;
- VectorCopy(v, bestorg);
- VectorCopy(normal, bestnormal);
+ VectorCopy(trace.endpos, bestorg);
+ VectorCopy(trace.plane.normal, bestnormal);
}
}
if (bestfrac < 1)
void CL_ParticleExplosion (vec3_t org)
{
int i;
+ trace_t trace;
//vec3_t v;
//vec3_t v2;
if (cl_stainmaps.integer)
v[0] = org[0] + lhrandom(-48, 48);
v[1] = org[1] + lhrandom(-48, 48);
v[2] = org[2] + lhrandom(-48, 48);
- if (CL_TraceLine(org, v, v2, NULL, true, NULL, SUPERCONTENTS_SOLID) >= 0.1)
+ trace = CL_TraceBox(org, vec3_origin, vec3_origin, v, true, NULL, SUPERCONTENTS_SOLID, false);
+ if (trace.fraction >= 0.1)
break;
}
- VectorSubtract(v2, org, v2);
+ VectorSubtract(trace.endpos, org, v2);
#endif
VectorScale(v2, 2.0f, v2);
particle(particletype + pt_smoke, 0x202020, 0x404040, tex_smoke[rand()&7], 12, 32, 64, 0, 0, org[0], org[1], org[2], v2[0], v2[1], v2[2], 0);
void CL_Smoke (vec3_t org, vec3_t dir, int count)
{
- vec3_t org2, org3;
+ vec3_t org2;
int k;
+ trace_t trace;
if (!cl_particles.integer) return;
org2[0] = org[0] + 0.125f * lhrandom(-count, count);
org2[1] = org[1] + 0.125f * lhrandom(-count, count);
org2[2] = org[2] + 0.125f * lhrandom(-count, count);
- CL_TraceLine(org, org2, org3, NULL, true, NULL, SUPERCONTENTS_SOLID);
- particle(particletype + pt_smoke, 0x101010, 0x202020, tex_smoke[rand()&7], 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 0, 0, org3[0], org3[1], org3[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 0);
+ trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, NULL, SUPERCONTENTS_SOLID, false);
+ particle(particletype + pt_smoke, 0x101010, 0x202020, tex_smoke[rand()&7], 3, (1.0f / cl_particles_quality.value) * 255, (1.0f / cl_particles_quality.value) * 1024, 0, 0, trace.endpos[0], trace.endpos[1], trace.endpos[2], lhrandom(-8, 8), lhrandom(-8, 8), lhrandom(-8, 8), 0);
}
}
}
void CL_BloodPuff (vec3_t org, vec3_t vel, int count)
{
float s;
- vec3_t org2, org3;
+ vec3_t org2;
+ trace_t trace;
// bloodcount is used to accumulate counts too small to cause a blood particle
if (!cl_particles.integer) return;
if (!cl_particles_blood.integer) return;
org2[0] = org[0] + 0.125f * lhrandom(-bloodcount, bloodcount);
org2[1] = org[1] + 0.125f * lhrandom(-bloodcount, bloodcount);
org2[2] = org[2] + 0.125f * lhrandom(-bloodcount, bloodcount);
- CL_TraceLine(org, org2, org3, NULL, true, NULL, SUPERCONTENTS_SOLID);
- particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768 / cl_particles_quality.value, cl_particles_blood_alpha.value * 384 / cl_particles_quality.value, 0, -1, org3[0], org3[1], org3[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 1);
+ trace = CL_TraceBox(org, vec3_origin, vec3_origin, org2, true, NULL, SUPERCONTENTS_SOLID, false);
+ particle(particletype + pt_blood, 0xFFFFFF, 0xFFFFFF, tex_bloodparticle[rand()&7], 8, cl_particles_blood_alpha.value * 768 / cl_particles_quality.value, cl_particles_blood_alpha.value * 384 / cl_particles_quality.value, 0, -1, trace.endpos[0], trace.endpos[1], trace.endpos[2], vel[0] + lhrandom(-s, s), vel[1] + lhrandom(-s, s), vel[2] + lhrandom(-s, s), 1);
bloodcount -= 16 / cl_particles_quality.value;
}
}
{
particle_t *p;
int i, maxparticle, j, a, content;
- float gravity, dvel, bloodwaterfade, frametime, f, dist, normal[3], v[3], org[3], oldorg[3];
+ float gravity, dvel, bloodwaterfade, frametime, f, dist, org[3], oldorg[3];
int hitent;
+ trace_t trace;
// LordHavoc: early out condition
if (!cl_numparticles)
if (p->type == particletype + pt_rain)
{
// raindrop - splash on solid/water/slime/lava
- if (CL_TraceLine(oldorg, p->org, v, normal, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK) < 1)
+ trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK, false);
+ if (trace.fraction < 1)
{
- VectorCopy(v, p->org);
- // splash
- p->type = particletype + pt_raindecal;
// convert from a raindrop particle to a rainsplash decal
+ VectorCopy(trace.endpos, p->org);
+ VectorCopy(trace.plane.normal, p->vel);
+ VectorAdd(p->org, p->vel, p->org);
+ p->type = particletype + pt_raindecal;
p->texnum = tex_rainsplash[0];
p->time2 = cl.time;
p->alphafade = p->alpha / 0.4;
- VectorCopy(normal, p->vel);
- VectorAdd(p->org, normal, p->org);
p->bounce = 0;
p->friction = 0;
p->gravity = 0;
else if (p->type == particletype + pt_blood)
{
// blood - splash on solid
- if (CL_TraceLine(oldorg, p->org, v, normal, true, &hitent, SUPERCONTENTS_SOLID) < 1)
+ trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID, false);
+ if (trace.fraction < 1)
{
- VectorCopy(v, p->org);
+ // convert from a blood particle to a blood decal
+ VectorCopy(trace.endpos, p->org);
+ VectorCopy(trace.plane.normal, p->vel);
+ VectorAdd(p->org, p->vel, p->org);
#ifndef WORKINGLQUAKE
if (cl_stainmaps.integer)
- R_Stain(v, 32, 32, 16, 16, p->alpha * p->size * (1.0f / 40.0f), 192, 48, 48, p->alpha * p->size * (1.0f / 40.0f));
+ R_Stain(p->org, 32, 32, 16, 16, p->alpha * p->size * (1.0f / 40.0f), 192, 48, 48, p->alpha * p->size * (1.0f / 40.0f));
#endif
if (!cl_decals.integer)
{
}
p->type = particletype + pt_decal;
- // convert from a blood particle to a blood decal
p->texnum = tex_blooddecal[rand()&7];
#ifndef WORKINGLQUAKE
p->owner = hitent;
p->ownermodel = cl_entities[hitent].render.model;
- Matrix4x4_Transform(&cl_entities[hitent].render.inversematrix, v, p->relativeorigin);
- Matrix4x4_Transform3x3(&cl_entities[hitent].render.inversematrix, normal, p->relativedirection);
- VectorAdd(p->relativeorigin, p->relativedirection, p->relativeorigin);
+ Matrix4x4_Transform(&cl_entities[hitent].render.inversematrix, p->org, p->relativeorigin);
+ Matrix4x4_Transform3x3(&cl_entities[hitent].render.inversematrix, p->vel, p->relativedirection);
#endif
p->time2 = cl.time;
p->alphafade = 0;
- VectorCopy(normal, p->vel);
- VectorAdd(p->org, normal, p->org);
p->bounce = 0;
p->friction = 0;
p->gravity = 0;
}
else
{
- if (CL_TraceLine(oldorg, p->org, v, normal, true, NULL, SUPERCONTENTS_SOLID) < 1)
+ trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, NULL, SUPERCONTENTS_SOLID, false);
+ if (trace.fraction < 1)
{
- VectorCopy(v, p->org);
+ VectorCopy(trace.endpos, p->org);
if (p->bounce < 0)
{
p->type = NULL;
}
else
{
- dist = DotProduct(p->vel, normal) * -p->bounce;
- VectorMA(p->vel, dist, normal, p->vel);
+ dist = DotProduct(p->vel, trace.plane.normal) * -p->bounce;
+ VectorMA(p->vel, dist, trace.plane.normal, p->vel);
if (DotProduct(p->vel, p->vel) < 0.03)
VectorClear(p->vel);
}
extern client_static_t cls;
+typedef struct client_movementqueue_s
+{
+ double time;
+ float viewangles[3];
+ float move[3];
+ qboolean jump;
+ qboolean crouch;
+}
+client_movementqueue_t;
+
//
// the client_state_t structure is wiped completely at every
// server signon
// update by server, can be used by mods for zooming
vec_t mviewzoom[2], viewzoom;
+ // client movement simulation
+ // these fields are only updated by CL_ClientMovement (called by CL_SendMove after parsing each network packet)
+ qboolean movement;
+ // simulated origin
+ vec3_t movement_origin;
+ vec3_t movement_oldorigin;
+ // queue of proposed moves
+ int movement_numqueue;
+ client_movementqueue_t movement_queue[256];
+
// pitch drifting vars
float idealpitch;
float pitchvel;
extern cvar_t cl_prydoncursor;
+extern vec3_t cl_playerstandmins;
+extern vec3_t cl_playerstandmaxs;
+extern vec3_t cl_playercrouchmins;
+extern vec3_t cl_playercrouchmaxs;
+
// these are updated by CL_ClearState
extern int cl_num_entities;
extern int cl_num_static_entities;
model_t *loadmodel;
-// LordHavoc: increased from 512 to 2048
-#define MAX_MOD_KNOWN 2048
+// LordHavoc: was 512
+#define MAX_MOD_KNOWN (MAX_MODELS + 256)
static model_t mod_known[MAX_MOD_KNOWN];
rtexturepool_t *mod_shared_texturepool;
if (cls.connect_trying && cls.connect_nextsendtime < realtime)
{
if (cls.connect_remainingtries == 0)
+ M_Update_Return_Reason("Connect: Waiting 10 seconds for reply");
+ cls.connect_nextsendtime = realtime + 1;
+ cls.connect_remainingtries--;
+ if (cls.connect_remainingtries <= -10)
{
cls.connect_trying = false;
M_Update_Return_Reason("Connect: Failed");
return;
}
- cls.connect_nextsendtime = realtime + 1;
- cls.connect_remainingtries--;
// try challenge first (newer server)
NetConn_WriteString(cls.connect_mysocket, "\377\377\377\377getchallenge", &cls.connect_address);
// then try netquake as a fallback (old server, or netquake)
else
{
bits = changedbits;
- if ((bits & E5_ORIGIN) && (s->origin[0] < -4096 || s->origin[0] >= 4096 || s->origin[1] < -4096 || s->origin[1] >= 4096 || s->origin[2] < -4096 || s->origin[2] >= 4096))
+ if ((bits & E5_ORIGIN) && (!(s->flags & RENDER_LOWPRECISION) || s->origin[0] < -4096 || s->origin[0] >= 4096 || s->origin[1] < -4096 || s->origin[1] >= 4096 || s->origin[2] < -4096 || s->origin[2] >= 4096))
bits |= E5_ORIGIN32;
if ((bits & E5_ANGLES) && !(s->flags & RENDER_LOWPRECISION))
bits |= E5_ANGLES16;
vec3_t v1, v2, spriteorigin;
vec_t spritescale;
vec4_t color;
+ trace_t trace;
if (r_letterbox.value)
return;
if (crosshair_static.integer)
AngleVectors(cl.viewangles, v2, NULL, NULL);
//VectorCopy(r_vieworigin, v1);
VectorMA(v1, 8192, v2, v2);
- spritescale = CL_TraceLine(v1, v2, spriteorigin, NULL, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY) * (8192.0f / 40.0f) * crosshair_size.value;
+ trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+ spritescale = trace.fraction * (8192.0f / 40.0f) * crosshair_size.value;
+ VectorCopy(trace.endpos, spriteorigin);
// draw the sprite
R_DrawSprite(GL_SRC_ALPHA, GL_ONE, pic->tex, true, spriteorigin, r_viewright, r_viewup, spritescale, -spritescale, -spritescale, spritescale, color[0], color[1], color[2], color[3]);
{
int i, j;
float dist, n;
- vec3_t impact;
explosion_t *e;
+ trace_t trace;
qbyte noise[EXPLOSIONGRID*EXPLOSIONGRID];
fractalnoisequick(noise, EXPLOSIONGRID, 4); // adjust noise grid size according to explosion
for (i = 0, e = explosion;i < MAX_EXPLOSIONS;i++, e++)
// clip start origin
if (e->clipping)
{
- CL_TraceLine(e->origin, e->vert[j], impact, NULL, true, NULL, SUPERCONTENTS_SOLID);
- VectorCopy(impact, e->vert[i]);
+ trace = CL_TraceBox(e->origin, vec3_origin, vec3_origin, e->vert[j], true, NULL, SUPERCONTENTS_SOLID, false);
+ VectorCopy(trace.endpos, e->vert[i]);
}
}
break;
void R_MoveExplosion(explosion_t *e)
{
int i;
- float dot, end[3], impact[3], normal[3], frametime;
+ float dot, end[3], frametime;
+ trace_t trace;
frametime = cl.time - e->time;
e->time = cl.time;
VectorMA(e->vert[i], frametime, e->vertvel[i], end);
if (e->clipping)
{
- if (CL_TraceLine(e->vert[i], end, impact, normal, true, NULL, SUPERCONTENTS_SOLID) < 1)
+ trace = CL_TraceBox(e->vert[i], vec3_origin, vec3_origin, end, true, NULL, SUPERCONTENTS_SOLID, false);
+ if (trace.fraction < 1)
{
// clip velocity against the wall
- dot = -DotProduct(e->vertvel[i], normal);
- VectorMA(e->vertvel[i], dot, normal, e->vertvel[i]);
+ dot = -DotProduct(e->vertvel[i], trace.plane.normal);
+ VectorMA(e->vertvel[i], dot, trace.plane.normal, e->vertvel[i]);
}
- VectorCopy(impact, e->vert[i]);
+ VectorCopy(trace.endpos, e->vert[i]);
}
else
VectorCopy(end, e->vert[i]);
flag = r_rtworld ? LIGHTFLAG_REALTIMEMODE : LIGHTFLAG_NORMALMODE;
for (lnum = 0, light = r_shadow_worldlightchain;light;light = light->next, lnum++)
{
- if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceLine(light->rtlight.shadoworigin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1)
+ if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (r_shadow_debuglight.integer < 0 || r_shadow_debuglight.integer == lnum) && (dist = (DotProduct(light->rtlight.shadoworigin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceBox(light->rtlight.shadoworigin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
{
cscale = light->rtlight.corona * r_coronas.value * 0.25f;
scale = light->rtlight.radius * light->rtlight.coronasizescale;
}
for (i = 0, light = r_dlight;i < r_numdlights;i++, light++)
{
- if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (dist = (DotProduct(light->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceLine(light->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1)
+ if ((light->flags & flag) && light->corona * r_coronas.value > 0 && (dist = (DotProduct(light->origin, r_viewforward) - viewdist)) >= 24.0f && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
{
cscale = light->corona * r_coronas.value * 0.25f;
scale = light->rtlight.radius * light->rtlight.coronasizescale;
{
VectorSubtract (p, sl->origin, v);
f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract);
- if (f > 0 && CL_TraceLine(p, sl->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1)
+ if (f > 0 && CL_TraceBox(p, vec3_origin, vec3_origin, sl->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
{
f *= d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
VectorMA(ambientcolor, f, sl->light, ambientcolor);
light = r_dlight + i;
VectorSubtract(p, light->origin, v);
f = DotProduct(v, v);
- if (f < light->rtlight.lightmap_cullradius2 && CL_TraceLine(p, light->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1)
+ if (f < light->rtlight.lightmap_cullradius2 && CL_TraceBox(p, vec3_origin, vec3_origin, light->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
{
f = (1.0f / (f + LIGHTOFFSET)) - light->rtlight.lightmap_subtract;
VectorMA(ambientcolor, f, light->rtlight.lightmap_light, ambientcolor);
VectorSubtract (v, light->origin, v);
if (DotProduct(v, v) < light->rtlight.lightmap_cullradius2)
{
- if (CL_TraceLine(ent->origin, light->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) != 1)
+ if (CL_TraceBox(ent->origin, vec3_origin, vec3_origin, light->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction != 1)
continue;
VectorSubtract (ent->origin, light->origin, v);
f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - light->rtlight.lightmap_subtract);
ent->numentlights = 0;
if (r_refdef.worldmodel)
for (i = 0, sl = r_refdef.worldmodel->brushq1.lights;i < r_refdef.worldmodel->brushq1.numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
- if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1)
+ if (CL_TraceBox(ent->origin, vec3_origin, vec3_origin, sl->origin, false, NULL, SUPERCONTENTS_SOLID, false).fraction == 1)
ent->entlights[ent->numentlights++] = i;
}
ent->entlightsframe = r_framecount;
if (rating >= 0.95)
{
rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
- if (bestrating < rating && CL_TraceLine(light->origin, r_vieworigin, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1.0f)
+ if (bestrating < rating && CL_TraceBox(light->origin, vec3_origin, vec3_origin, r_vieworigin, true, NULL, SUPERCONTENTS_SOLID, false).fraction == 1.0f)
{
bestrating = rating;
best = light;
void R_Shadow_SetCursorLocationForView(void)
{
- vec_t dist, push, frac;
- vec3_t dest, endpos, normal;
+ vec_t dist, push;
+ vec3_t dest, endpos;
+ trace_t trace;
VectorMA(r_vieworigin, r_editlights_cursordistance.value, r_viewforward, dest);
- frac = CL_TraceLine(r_vieworigin, dest, endpos, normal, true, NULL, SUPERCONTENTS_SOLID);
- if (frac < 1)
+ trace = CL_TraceBox(r_vieworigin, vec3_origin, vec3_origin, dest, true, NULL, SUPERCONTENTS_SOLID, false);
+ if (trace.fraction < 1)
{
- dist = frac * r_editlights_cursordistance.value;
+ dist = trace.fraction * r_editlights_cursordistance.value;
push = r_editlights_cursorpushback.value;
if (push > dist)
push = dist;
push = -push;
- VectorMA(endpos, push, r_viewforward, endpos);
- VectorMA(endpos, r_editlights_cursorpushoff.value, normal, endpos);
+ VectorMA(trace.endpos, push, r_viewforward, endpos);
+ VectorMA(endpos, r_editlights_cursorpushoff.value, trace.plane.normal, endpos);
}
r_editlights_cursorlocation[0] = floor(endpos[0] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value;
r_editlights_cursorlocation[1] = floor(endpos[1] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value;
static float oldz;
entity_t *ent;
float vieworg[3], viewangles[3];
+ trace_t trace;
Matrix4x4_CreateIdentity(&viewmodelmatrix);
Matrix4x4_CreateIdentity(&r_refdef.viewentitymatrix);
if (cls.state == ca_connected && cls.signon == SIGNONS)
if (chase_active.value)
{
// observing entity from third person
- vec_t camback, camup, dist, forward[3], stop[3], chase_dest[3], normal[3];
+ vec_t camback, camup, dist, forward[3], chase_dest[3];
camback = bound(0, chase_back.value, 128);
if (chase_back.value != camback)
chase_dest[0] = vieworg[0] + forward[0] * dist;
chase_dest[1] = vieworg[1] + forward[1] * dist;
chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
- CL_TraceLine(vieworg, chase_dest, stop, normal, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY);
- vieworg[0] = stop[0] + forward[0] * 8 + normal[0] * 4;
- vieworg[1] = stop[1] + forward[1] * 8 + normal[1] * 4;
- vieworg[2] = stop[2] + forward[2] * 8 + normal[2] * 4;
+ trace = CL_TraceBox(vieworg, vec3_origin, vec3_origin, chase_dest, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+ VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
}
else
{