1. cl_main.c --> Cmd_AddCommand ("nqconnect", CL_NQConnect_f);
2. Still cl_main.c (notable cls.nqprotocol = true;)
Code: Select all
void CL_NQConnect_f (void)
{
char *server;
if (Cmd_Argc() != 2)
{
Com_Printf ("usage: nqconnect <server>\n");
return;
}
server = Cmd_Argv (1);
Host_EndGame ();
cls.nqprotocol = true;
strlcpy (cls.servername, server, sizeof(cls.servername));
CL_BeginServerConnect();
}Code: Select all
void CL_BeginServerConnect(void)
{
connect_time = -999; // CL_CheckForResend() will fire immediately
CL_CheckForResend();
}Code: Select all
void CL_CheckForResend (void)
{
char data[2048];
double t1, t2;
if (cls.state == ca_disconnected && com_serveractive) {
// if the local server is running and we are not, then connect
cls.nqprotocol = false;
strlcpy (cls.servername, "local", sizeof(cls.servername));
NET_StringToAdr ("local", &cls.server_adr);
CL_SendConnectPacket (); // we don't need a challenge on the local server
// FIXME: cls.state = ca_connecting so that we don't send the packet twice?
return;
}
if (cls.state != ca_disconnected || !connect_time)
return;
if (cls.realtime - connect_time < 5.0)
return;
t1 = Sys_DoubleTime ();
if (!NET_StringToAdr (cls.servername, &cls.server_adr))
{
Com_Printf ("Bad server address\n");
connect_time = 0;
return;
}
t2 = Sys_DoubleTime ();
connect_time = cls.realtime + t2 - t1; // for retransmit requests
if (cls.server_adr.port == 0)
cls.server_adr.port = BigShort (cls.nqprotocol ? 26000 : PORT_SERVER);
Com_Printf ("Connecting to %s...\n", cls.servername);
if (cls.nqprotocol) {
memcpy (data, "\x80\x00\x00\x0C" "\x01" "QUAKE\x00" "\x03", 12);
NET_SendPacket (NS_CLIENT, 12, data, cls.server_adr);
}
else {
sprintf (data, "\xff\xff\xff\xff" "getchallenge\n");
NET_SendPacket (NS_CLIENT, strlen(data), data, cls.server_adr);
}
}We'll approach this from the CL_Frame (cl_main.c) point of view ...
CL_Frame (near end) --> CL_SendToServer -- > CL_SendCmd (only if ca != ca_disconnected) -> CLNQ_SendCmd -> ...
Code: Select all
void CLNQ_SendCmd (void)
{
int i;
usercmd_t cmd;
sizebuf_t buf;
byte data[128];
SZ_Init (&buf, data, sizeof(data));
CL_Move(&cmd);
MSG_WriteByte (&buf, clc_move);
MSG_WriteFloat (&buf, cl.time); // so server can get ping times
for (i=0 ; i<3 ; i++)
MSG_WriteAngle (&buf, cmd.angles[i]);
MSG_WriteShort (&buf, cmd.forwardmove);
MSG_WriteShort (&buf, cmd.sidemove);
MSG_WriteShort (&buf, cmd.upmove);
MSG_WriteByte (&buf, cmd.buttons);
MSG_WriteByte (&buf, cmd.impulse);
//
// deliver the message
//
Netchan_Transmit (&cls.netchan, buf.cursize, buf.data);
}(Note the nq_viewentity variable)
Code: Select all
oid NQD_LinkEntities (void)
{
entity_t ent;
centity_t *cent;
entity_state_t *state;
float f;
struct model_s *model;
int modelflags;
vec3_t cur_origin;
vec3_t old_origin;
float autorotate;
int i;
int num;
f = NQD_LerpPoint ();
NQD_LerpPlayerinfo (f);
autorotate = anglemod (100*cl.time);
memset (&ent, 0, sizeof(ent));
for (num = 1; num < nq_num_entities; num++)
{
cent = &cl_entities[num];
state = ¢->current;
if (cent->lastframe != cl_entframecount)
continue; // not present in this frame
MSG_UnpackOrigin (state->s_origin, cur_origin);
if (state->effects & EF_BRIGHTFIELD)
CL_EntityParticles (cur_origin);
// spawn light flashes, even ones coming from invisible objects
if (state->effects & EF_MUZZLEFLASH) {
vec3_t angles, forward;
cdlight_t *dl;
dl = CL_AllocDlight (-num);
MSG_UnpackAngles (state->s_angles, angles);
AngleVectors (angles, forward, NULL, NULL);
VectorMA (cur_origin, 18, forward, dl->origin);
dl->origin[2] += 16;
dl->radius = 200 + (rand()&31);
dl->minlight = 32;
dl->die = cl.time + 0.1;
dl->type = lt_muzzleflash;
}
if (state->effects & EF_BRIGHTLIGHT) {
if (state->modelindex != cl_playerindex || r_powerupglow.value) {
vec3_t tmp;
VectorCopy (cur_origin, tmp);
tmp[2] += 16;
V_AddDlight (state->number, tmp, 400 + (rand()&31), 0, lt_default);
}
}
if (state->effects & EF_DIMLIGHT)
if (state->modelindex != cl_playerindex || r_powerupglow.value)
V_AddDlight (state->number, cur_origin, 200 + (rand()&31), 0, lt_default);
// if set to invisible, skip
if (!state->modelindex)
continue;
cent->current = *state;
ent.model = model = cl.model_precache[state->modelindex];
if (!model)
Host_Error ("CL_LinkPacketEntities: bad modelindex");
if (cl_r2g.value && cl_grenadeindex != -1)
if (state->modelindex == cl_rocketindex)
ent.model = cl.model_precache[cl_grenadeindex];
modelflags = R_ModelFlags (model);
// rotate binary objects locally
if (modelflags & MF_ROTATE)
{
ent.angles[0] = 0;
ent.angles[1] = autorotate;
ent.angles[2] = 0;
}
else
{
vec3_t old, cur;
MSG_UnpackAngles (cent->current.s_angles, old);
MSG_UnpackAngles (cent->previous.s_angles, cur);
LerpAngles (old, cur, f, ent.angles);
}
if (num == nq_viewentity) {
extern float nq_speed;
float f;
nq_speed = 0;
for (i = 0; i < 3; i++) {
f = (cent->current.s_origin[i] - cent->previous.s_origin[i]) * 0.125;
nq_speed += f * f;
}
if (nq_speed) nq_speed = sqrt(nq_speed);
nq_speed /= nq_mtime[0] - nq_mtime[1];
}
// calculate origin
for (i = 0; i < 3; i++)
{
if (abs(cent->current.s_origin[i] - cent->previous.s_origin[i]) > 128 * 8) {
// teleport or something, don't lerp
VectorCopy (cur_origin, ent.origin);
if (num == nq_viewentity)
nq_player_teleported = true;
break;
}
ent.origin[i] = cent->previous.s_origin[i] * 0.125 +
f * (cur_origin[i] - cent->previous.s_origin[i] * 0.125);
}
if (num == nq_viewentity) {
VectorCopy (ent.origin, cent->trail_origin); // FIXME?
continue; // player entity
}
if (cl_deadbodyfilter.value && state->modelindex == cl_playerindex
&& ( (i=state->frame)==49 || i==60 || i==69 || i==84 || i==93 || i==102) )
continue;
if (cl_gibfilter.value && cl.modelinfos[state->modelindex] == mi_gib)
continue;
// set colormap
if (state->colormap && state->colormap <= MAX_CLIENTS
&& state->modelindex == cl_playerindex
)
ent.colormap = state->colormap;
else
ent.colormap = 0;
// set skin
ent.skinnum = state->skinnum;
// set frame
ent.frame = state->frame;
// add automatic particle trails
if ((modelflags & ~MF_ROTATE))
{
if (false /*cl_entframecount == 1 || cent->lastframe != cl_entframecount-1*/)
{ // not in last message
VectorCopy (ent.origin, old_origin);
}
else
{
VectorCopy (cent->trail_origin, old_origin);
for (i=0 ; i<3 ; i++)
if ( abs(old_origin[i] - ent.origin[i]) > 128)
{ // no trail if too far
VectorCopy (ent.origin, old_origin);
break;
}
}
if (modelflags & MF_ROCKET)
{
if (r_rockettrail.value) {
if (r_rockettrail.value == 2)
CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin);
else
CL_RocketTrail (old_origin, ent.origin, cent->trail_origin);
} else
VectorCopy (ent.origin, cent->trail_origin);
if (r_rocketlight.value)
CL_NewDlight (state->number, ent.origin, 200, 0.1, lt_rocket);
}
else if (modelflags & MF_GRENADE && r_grenadetrail.value)
CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin);
else if (modelflags & MF_GIB)
CL_BloodTrail (old_origin, ent.origin, cent->trail_origin);
else if (modelflags & MF_ZOMGIB)
CL_SlightBloodTrail (old_origin, ent.origin, cent->trail_origin);
else if (modelflags & MF_TRACER)
CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 52);
else if (modelflags & MF_TRACER2)
CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 230);
else if (modelflags & MF_TRACER3)
CL_VoorTrail (old_origin, ent.origin, cent->trail_origin);
}
cent->lastframe = cl_entframecount;
V_AddEntity (&ent);
}
if (nq_viewentity == 0)
Host_Error ("viewentity == 0");
VectorCopy (cl_entities[nq_viewentity].trail_origin, cl.simorg);
}