ent = &cl_entities[n].render;
if (!ent->model || !ent->model->TraceBox)
continue;
- //if (((ent->model->type != mod_brushq1 && ent->model->type != mod_brushq2 && ent->model->type != mod_brushq3) || ent->alpha < 1) && !(cl_entities[n].state_current.effects & EF_SELECTABLE))
- // continue;
+ // if transparent and not selectable, skip entity
+ if (!(cl_entities[n].state_current.effects & EF_SELECTABLE) && (ent->alpha < 1 || (ent->effects & (EF_ADDITIVE | EF_NODEPTHTEST))))
+ continue;
if (ent->mins[0] > tracemaxs[0] || ent->maxs[0] < tracemins[0]
|| ent->mins[1] > tracemaxs[1] || ent->maxs[1] < tracemins[1]
|| ent->mins[2] > tracemaxs[2] || ent->maxs[2] < tracemins[2])
kbutton_t in_mlook, in_klook;
kbutton_t in_left, in_right, in_forward, in_back;
kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright;
-kbutton_t in_strafe, in_speed, in_jump, in_attack;
+kbutton_t in_strafe, in_speed, in_jump, in_attack, in_use;
kbutton_t in_up, in_down;
// LordHavoc: added 6 new buttons
kbutton_t in_button3, in_button4, in_button5, in_button6, in_button7, in_button8;
void IN_AttackDown(void) {KeyDown(&in_attack);}
void IN_AttackUp(void) {KeyUp(&in_attack);}
+void IN_UseDown(void) {KeyDown(&in_use);}
+void IN_UseUp(void) {KeyUp(&in_use);}
+
// LordHavoc: added 6 new buttons
void IN_Button3Down(void) {KeyDown(&in_button3);}
void IN_Button3Up(void) {KeyUp(&in_button3);}
Send the intended movement message to the server
================
*/
-void CL_BaseMove (usercmd_t *cmd)
+void CL_BaseMove (void)
{
+ vec3_t temp;
if (cls.signon != SIGNONS)
return;
CL_AdjustAngles ();
- memset (cmd, 0, sizeof(*cmd));
+ // PRYDON_CLIENTCURSOR needs to survive basemove resets
+ VectorCopy (cl.cmd.cursor_screen, temp);
+ memset (&cl.cmd, 0, sizeof(cl.cmd));
+ VectorCopy (temp, cl.cmd.cursor_screen);
if (in_strafe.state & 1)
{
- cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right);
- cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left);
+ cl.cmd.sidemove += cl_sidespeed.value * CL_KeyState (&in_right);
+ cl.cmd.sidemove -= cl_sidespeed.value * CL_KeyState (&in_left);
}
- cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright);
- cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft);
+ cl.cmd.sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright);
+ cl.cmd.sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft);
- cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up);
- cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down);
+ cl.cmd.upmove += cl_upspeed.value * CL_KeyState (&in_up);
+ cl.cmd.upmove -= cl_upspeed.value * CL_KeyState (&in_down);
if (! (in_klook.state & 1) )
{
- cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward);
- cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back);
+ cl.cmd.forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward);
+ cl.cmd.forwardmove -= cl_backspeed.value * CL_KeyState (&in_back);
}
//
//
if (in_speed.state & 1)
{
- cmd->forwardmove *= cl_movespeedkey.value;
- cmd->sidemove *= cl_movespeedkey.value;
- cmd->upmove *= cl_movespeedkey.value;
+ cl.cmd.forwardmove *= cl_movespeedkey.value;
+ cl.cmd.sidemove *= cl_movespeedkey.value;
+ cl.cmd.upmove *= cl_movespeedkey.value;
}
}
+#include "cl_collision.h"
+
+void CL_UpdatePrydonCursor(void)
+{
+ vec3_t temp, scale;
+
+ if (!cl_prydoncursor.integer)
+ VectorClear(cl.cmd.cursor_screen);
+
+ /*
+ if (cl.cmd.cursor_screen[0] < -1)
+ {
+ cl.viewangles[YAW] -= m_yaw.value * (cl.cmd.cursor_screen[0] - -1) * vid.realwidth * sensitivity.value * cl.viewzoom;
+ cl.cmd.cursor_screen[0] = -1;
+ }
+ if (cl.cmd.cursor_screen[0] > 1)
+ {
+ cl.viewangles[YAW] -= m_yaw.value * (cl.cmd.cursor_screen[0] - 1) * vid.realwidth * sensitivity.value * cl.viewzoom;
+ cl.cmd.cursor_screen[0] = 1;
+ }
+ if (cl.cmd.cursor_screen[1] < -1)
+ {
+ cl.viewangles[PITCH] += m_pitch.value * (cl.cmd.cursor_screen[1] - -1) * vid.realheight * sensitivity.value * cl.viewzoom;
+ cl.cmd.cursor_screen[1] = -1;
+ }
+ if (cl.cmd.cursor_screen[1] > 1)
+ {
+ cl.viewangles[PITCH] += m_pitch.value * (cl.cmd.cursor_screen[1] - 1) * vid.realheight * sensitivity.value * cl.viewzoom;
+ cl.cmd.cursor_screen[1] = 1;
+ }
+ */
+ cl.cmd.cursor_screen[0] = bound(-1, cl.cmd.cursor_screen[0], 1);
+ cl.cmd.cursor_screen[1] = bound(-1, cl.cmd.cursor_screen[1], 1);
+ cl.cmd.cursor_screen[2] = 1;
+
+ scale[0] = -tan(r_refdef.fov_x * M_PI / 360.0);
+ scale[1] = -tan(r_refdef.fov_y * M_PI / 360.0);
+ scale[2] = 1;
+
+ // trace distance
+ VectorScale(scale, 1000000, scale);
+
+ // FIXME: use something other than renderer variables here
+ // (but they need to match)
+ VectorCopy(r_vieworigin, cl.cmd.cursor_start);
+ VectorSet(temp, cl.cmd.cursor_screen[2] * scale[2], cl.cmd.cursor_screen[0] * scale[0], cl.cmd.cursor_screen[1] * scale[1]);
+ Matrix4x4_Transform(&r_view_matrix, temp, cl.cmd.cursor_end);
+ cl.cmd.cursor_fraction = CL_SelectTraceLine(cl.cmd.cursor_start, cl.cmd.cursor_end, cl.cmd.cursor_impact, cl.cmd.cursor_normal, &cl.cmd.cursor_entitynumber);
+ // makes sparks where cursor is
+ //CL_SparkShower(cl.cmd.cursor_impact, cl.cmd.cursor_normal, 5, 0);
+}
/*
==============
CL_SendMove
==============
*/
-void CL_SendMove(usercmd_t *cmd)
+void CL_SendMove(void)
{
int i;
int bits;
static double lastmovetime;
static float forwardmove, sidemove, upmove, total; // accumulation
- forwardmove += cmd->forwardmove;
- sidemove += cmd->sidemove;
- upmove += cmd->upmove;
+ CL_UpdatePrydonCursor();
+
+ forwardmove += cl.cmd.forwardmove;
+ sidemove += cl.cmd.sidemove;
+ upmove += cl.cmd.upmove;
total++;
// LordHavoc: cap outgoing movement messages to sys_ticrate
if (!cl.islocalgame && (realtime - lastmovetime < sys_ticrate.value))
buf.cursize = 0;
buf.data = data;
- cl.cmd = *cmd;
-
// send the movement message
MSG_WriteByte (&buf, clc_move);
for (i = 0;i < 3;i++)
MSG_WriteAngle32f (&buf, cl.viewangles[i]);
}
- else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5)
+ else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
{
for (i = 0;i < 3;i++)
MSG_WriteAngle16i (&buf, cl.viewangles[i]);
// send button bits
bits = 0;
- // LordHavoc: added 6 new buttons
- if (in_attack.state & 3) bits |= 1;in_attack.state &= ~2;
- if (in_jump.state & 3) bits |= 2;in_jump.state &= ~2;
- if (in_button3.state & 3) bits |= 4;in_button3.state &= ~2;
- if (in_button4.state & 3) bits |= 8;in_button4.state &= ~2;
- if (in_button5.state & 3) bits |= 16;in_button5.state &= ~2;
- if (in_button6.state & 3) bits |= 32;in_button6.state &= ~2;
- if (in_button7.state & 3) bits |= 64;in_button7.state &= ~2;
- if (in_button8.state & 3) bits |= 128;in_button8.state &= ~2;
-
- MSG_WriteByte (&buf, bits);
+ // LordHavoc: added 13 new buttons and chat button
+ if (in_attack.state & 3) bits |= 1;in_attack.state &= ~2;
+ if (in_jump.state & 3) bits |= 2;in_jump.state &= ~2;
+ if (in_button3.state & 3) bits |= 4;in_button3.state &= ~2;
+ if (in_button4.state & 3) bits |= 8;in_button4.state &= ~2;
+ if (in_button5.state & 3) bits |= 16;in_button5.state &= ~2;
+ if (in_button6.state & 3) bits |= 32;in_button6.state &= ~2;
+ if (in_button7.state & 3) bits |= 64;in_button7.state &= ~2;
+ if (in_button8.state & 3) bits |= 128;in_button8.state &= ~2;
+ if (in_use.state & 3) bits |= 256;in_use.state &= ~2;
+ if (key_dest != key_game || key_consoleactive) bits |= 512;
+ if (cl_prydoncursor.integer) bits |= 1024;
+ // button bits 11-31 unused currently
+ if (cl.cmd.cursor_screen[0] <= -1) bits |= 8;
+ if (cl.cmd.cursor_screen[0] >= 1) bits |= 16;
+ if (cl.cmd.cursor_screen[1] <= -1) bits |= 32;
+ if (cl.cmd.cursor_screen[1] >= 1) bits |= 64;
+
+ if (cl.protocol == PROTOCOL_DARKPLACES6)
+ MSG_WriteLong (&buf, bits);
+ else
+ MSG_WriteByte (&buf, bits);
MSG_WriteByte (&buf, in_impulse);
in_impulse = 0;
- // FIXME: should ack latest 3 frames perhaps?
- if (cl.latestframenum > 0)
+ // PRYDON_CLIENTCURSOR
+ if (cl.protocol == PROTOCOL_DARKPLACES6)
+ {
+ // 30 bytes
+ MSG_WriteShort (&buf, cl.cmd.cursor_screen[0] * 32767.0f);
+ MSG_WriteShort (&buf, cl.cmd.cursor_screen[1] * 32767.0f);
+ MSG_WriteFloat (&buf, cl.cmd.cursor_start[0]);
+ MSG_WriteFloat (&buf, cl.cmd.cursor_start[1]);
+ MSG_WriteFloat (&buf, cl.cmd.cursor_start[2]);
+ MSG_WriteFloat (&buf, cl.cmd.cursor_impact[0]);
+ MSG_WriteFloat (&buf, cl.cmd.cursor_impact[1]);
+ MSG_WriteFloat (&buf, cl.cmd.cursor_impact[2]);
+ MSG_WriteShort (&buf, cl.cmd.cursor_entitynumber);
+ }
+
+ // ack the last few frame numbers
+ // (redundent to improve handling of client->server packet loss)
+ if (cl.latestframenums[LATESTFRAMENUMS-1] > 0)
{
if (developer_networkentities.integer >= 1)
- Con_Printf("send clc_ackentities %i\n", cl.latestframenum);
- MSG_WriteByte(&buf, clc_ackentities);
- MSG_WriteLong(&buf, cl.latestframenum);
+ Con_Printf("send clc_ackframe %i\n", cl.latestframenums[LATESTFRAMENUMS-1]);
+ for (i = 0;i < LATESTFRAMENUMS;i++)
+ {
+ MSG_WriteByte(&buf, clc_ackframe);
+ MSG_WriteLong(&buf, cl.latestframenums[i]);
+ }
}
// deliver the message
Cmd_AddCommand ("+mlook", IN_MLookDown);
Cmd_AddCommand ("-mlook", IN_MLookUp);
+ // LordHavoc: added use button
+ Cmd_AddCommand ("+use", IN_UseDown);
+ Cmd_AddCommand ("-use", IN_UseUp);
+
// LordHavoc: added 6 new buttons
Cmd_AddCommand ("+button3", IN_Button3Down);
Cmd_AddCommand ("-button3", IN_Button3Up);
cvar_t cl_noplayershadow = {CVAR_SAVE, "cl_noplayershadow", "0"};
+cvar_t cl_prydoncursor = {0, "cl_prydoncursor", "0"};
+
mempool_t *cl_refdef_mempool;
mempool_t *cl_entities_mempool;
ent->render.colormap = -1; // no special coloring
ent->render.scale = 1;
ent->render.alpha = 1;
+ VectorSet(ent->render.colormod, 1, 1, 1);
return ent;
}
else
e->render.colormap = -1; // no special coloring
e->render.skinnum = e->state_current.skin;
+ VectorScale(e->state_current.colormod, (1.0f / 32.0f), e->render.colormod);
if (e->render.flags & RENDER_VIEWMODEL)
{
if (!r_drawviewmodel.integer || chase_active.integer || envmap)
// transfer certain model flags to effects
if (e->render.model->flags2 & EF_FULLBRIGHT)
e->render.effects |= EF_FULLBRIGHT;
+ if (cl_prydoncursor.integer && (e->render.effects & EF_SELECTABLE) && cl.cmd.cursor_entitynumber == e - cl_entities)
+ VectorScale(e->render.colormod, 2, e->render.colormod);
}
// animation lerp
ent->render.flags = RENDER_SHADOW;
if (!r_fullbright.integer)
ent->render.flags |= RENDER_LIGHT;
+ VectorSet(ent->render.colormod, 1, 1, 1);
}
static void CL_RelinkStaticEntities(void)
// hide player shadow during intermission or nehahra movie
if (!(e->render.effects & EF_NOSHADOW) && !(e->render.flags & RENDER_TRANSPARENT))
e->render.flags |= RENDER_SHADOW;
+ VectorSet(e->render.colormod, 1, 1, 1);
R_LerpAnimation(&e->render);
r_refdef.entities[r_refdef.numentities++] = &e->render;
}
ent->state_current.flags = RENDER_VIEWMODEL;
if (cl.stats[STAT_HEALTH] <= 0 || cl.intermission)
ent->state_current.modelindex = 0;
- else if (cl.items & IT_INVISIBILITY)
+ else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
{
if (gamemode == GAME_TRANSFUSION)
ent->state_current.alpha = 128;
ent->render.frame = ent->render.frame2;
ent->render.colormap = -1; // no special coloring
ent->render.alpha = 1;
+ VectorSet(ent->render.colormod, 1, 1, 1);
Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, e->origin[0], e->origin[1], e->origin[2], 0, 0, 0, 1);
Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix);
CL_SendCmd
=================
*/
-void CL_SendCmd(usercmd_t *cmd)
+void CL_SendCmd(void)
{
if (cls.signon == SIGNONS)
- CL_SendMove(cmd);
+ CL_SendMove();
if (cls.demoplayback)
{
Cvar_RegisterVariable(&cl_beams_lightatend);
Cvar_RegisterVariable(&cl_noplayershadow);
+ Cvar_RegisterVariable(&cl_prydoncursor);
+
if (gamemode == GAME_NETHERWORLD)
{
Cvar_RegisterVariable (&cl_playermodel);
"", // 48
"", // 49
"svc_cgame", // 50 // [short] length [bytes] data
- "svc_unusedlh1", // 51 // unused
+ "svc_updatestatubyte", // 51 // [byte] stat [byte] value
"svc_effect", // 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
"svc_effect2", // 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
"svc_sound2", // 54 // short soundindex instead of byte
// hack for unmarked Nehahra movie demos which had a custom protocol
if (i == PROTOCOL_QUAKE && cls.demoplayback && demo_nehahra.integer)
i = PROTOCOL_NEHAHRAMOVIE;
- if (i != PROTOCOL_QUAKE && i != PROTOCOL_DARKPLACES1 && i != PROTOCOL_DARKPLACES2 && i != PROTOCOL_DARKPLACES3 && i != PROTOCOL_DARKPLACES4 && i != PROTOCOL_DARKPLACES5 && i != PROTOCOL_NEHAHRAMOVIE)
+ if (i != PROTOCOL_QUAKE && i != PROTOCOL_DARKPLACES1 && i != PROTOCOL_DARKPLACES2 && i != PROTOCOL_DARKPLACES3 && i != PROTOCOL_DARKPLACES4 && i != PROTOCOL_DARKPLACES5 && i != PROTOCOL_DARKPLACES6 && i != PROTOCOL_NEHAHRAMOVIE)
{
- Host_Error("CL_ParseServerInfo: Server is protocol %i, not %i (Quake), %i (DP1), %i (DP2), %i (DP3), %i (DP4), %i (DP5), or %i (Nehahra movie)", i, PROTOCOL_QUAKE, PROTOCOL_DARKPLACES1, PROTOCOL_DARKPLACES2, PROTOCOL_DARKPLACES3, PROTOCOL_DARKPLACES4, PROTOCOL_DARKPLACES5, PROTOCOL_NEHAHRAMOVIE);
+ Host_Error("CL_ParseServerInfo: Server is protocol %i, not %i (Quake), %i (DP1), %i (DP2), %i (DP3), %i (DP4), %i (DP5), %i (DP6), or %i (Nehahra movie)", i, PROTOCOL_QUAKE, PROTOCOL_DARKPLACES1, PROTOCOL_DARKPLACES2, PROTOCOL_DARKPLACES3, PROTOCOL_DARKPLACES4, PROTOCOL_DARKPLACES5, PROTOCOL_DARKPLACES6, PROTOCOL_NEHAHRAMOVIE);
return;
}
cl.protocol = i;
{
int i, j;
+ VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
+
+ if (cl.protocol != PROTOCOL_DARKPLACES6)
+ {
+ cl.stats[STAT_VIEWHEIGHT] = DEFAULT_VIEWHEIGHT;
+ cl.stats[STAT_ITEMS] = 0;
+ cl.stats[STAT_VIEWZOOM] = 255;
+ }
+ cl.idealpitch = 0;
+ cl.punchangle[0] = 0;
+ cl.punchangle[1] = 0;
+ cl.punchangle[2] = 0;
+ cl.punchvector[0] = 0;
+ cl.punchvector[1] = 0;
+ cl.punchvector[2] = 0;
+ cl.mvelocity[0][0] = 0;
+ cl.mvelocity[0][1] = 0;
+ cl.mvelocity[0][2] = 0;
+
bits &= 0xFFFF;
if (bits & SU_EXTEND1)
bits |= (MSG_ReadByte() << 16);
bits |= (MSG_ReadByte() << 24);
if (bits & SU_VIEWHEIGHT)
- cl.viewheight = MSG_ReadChar ();
- else
- cl.viewheight = DEFAULT_VIEWHEIGHT;
+ cl.stats[STAT_VIEWHEIGHT] = MSG_ReadChar ();
if (bits & SU_IDEALPITCH)
cl.idealpitch = MSG_ReadChar ();
- else
- cl.idealpitch = 0;
- VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
for (i = 0;i < 3;i++)
{
if (bits & (SU_PUNCH1<<i) )
{
- if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5)
+ if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
cl.punchangle[i] = MSG_ReadAngle16i();
else if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_NEHAHRAMOVIE)
cl.punchangle[i] = MSG_ReadChar();
else
Host_Error("CL_ParseClientData: unknown cl.protocol %i\n", cl.protocol);
}
- else
- cl.punchangle[i] = 0;
if (bits & (SU_PUNCHVEC1<<i))
{
if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3 || cl.protocol == PROTOCOL_DARKPLACES4)
cl.punchvector[i] = MSG_ReadCoord16i();
- else if (cl.protocol == PROTOCOL_DARKPLACES5)
+ else if (cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
cl.punchvector[i] = MSG_ReadCoord32f();
else
Host_Error("CL_ParseClientData: unknown cl.protocol %i\n", cl.protocol);
}
- else
- cl.punchvector[i] = 0;
if (bits & (SU_VELOCITY1<<i) )
{
if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_NEHAHRAMOVIE || cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3 || cl.protocol == PROTOCOL_DARKPLACES4)
cl.mvelocity[0][i] = MSG_ReadChar()*16;
- else if (cl.protocol == PROTOCOL_DARKPLACES5)
+ else if (cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
cl.mvelocity[0][i] = MSG_ReadCoord32f();
else
Host_Error("CL_ParseClientData: unknown cl.protocol %i\n", cl.protocol);
}
- else
- cl.mvelocity[0][i] = 0;
}
- i = MSG_ReadLong ();
- if (cl.items != i)
- { // set flash times
- for (j=0 ; j<32 ; j++)
- if ( (i & (1<<j)) && !(cl.items & (1<<j)))
- cl.item_gettime[j] = cl.time;
- cl.items = i;
- }
+ if (bits & SU_ITEMS)
+ cl.stats[STAT_ITEMS] = MSG_ReadLong ();
cl.onground = (bits & SU_ONGROUND) != 0;
cl.inwater = (bits & SU_INWATER) != 0;
- if (cl.protocol == PROTOCOL_DARKPLACES5)
+ if (cl.protocol == PROTOCOL_DARKPLACES6)
+ {
+ }
+ else if (cl.protocol == PROTOCOL_DARKPLACES5)
{
cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadShort() : 0;
cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadShort() : 0;
cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadShort() : 0;
cl.stats[STAT_HEALTH] = MSG_ReadShort();
cl.stats[STAT_AMMO] = MSG_ReadShort();
-
cl.stats[STAT_SHELLS] = MSG_ReadShort();
cl.stats[STAT_NAILS] = MSG_ReadShort();
cl.stats[STAT_ROCKETS] = MSG_ReadShort();
cl.stats[STAT_CELLS] = MSG_ReadShort();
- //cl.stats[STAT_GENERIC1] = MSG_ReadShort();
- //cl.stats[STAT_GENERIC2] = MSG_ReadShort();
- //cl.stats[STAT_GENERIC3] = MSG_ReadShort();
- //cl.stats[STAT_GENERIC4] = MSG_ReadShort();
- //cl.stats[STAT_GENERIC5] = MSG_ReadShort();
- //cl.stats[STAT_GENERIC6] = MSG_ReadShort();
-
- i = (unsigned short) MSG_ReadShort ();
+ cl.stats[STAT_ACTIVEWEAPON] = (unsigned short) MSG_ReadShort ();
}
else
{
cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
cl.stats[STAT_HEALTH] = MSG_ReadShort();
cl.stats[STAT_AMMO] = MSG_ReadByte();
-
cl.stats[STAT_SHELLS] = MSG_ReadByte();
cl.stats[STAT_NAILS] = MSG_ReadByte();
cl.stats[STAT_ROCKETS] = MSG_ReadByte();
cl.stats[STAT_CELLS] = MSG_ReadByte();
-
- i = MSG_ReadByte ();
- if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
- i = (1<<i);
+ if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_NEXUIZ)
+ cl.stats[STAT_ACTIVEWEAPON] = (1<<MSG_ReadByte ());
+ else
+ cl.stats[STAT_ACTIVEWEAPON] = MSG_ReadByte ();
}
- // GAME_NEXUIZ hud needs weapon change time
- // GAME_NEXUIZ uses a bit number as it's STAT_ACTIVEWEAPON, not a bitfield
- // like other modes
- if (cl.stats[STAT_ACTIVEWEAPON] != i)
- cl.weapontime = cl.time;
- cl.stats[STAT_ACTIVEWEAPON] = i;
-
- cl.viewzoomold = cl.viewzoomnew; // for interpolation
if (bits & SU_VIEWZOOM)
{
- if (cl.protocol == PROTOCOL_DARKPLACES5)
- i = (unsigned short) MSG_ReadShort();
+ if (cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
+ cl.stats[STAT_VIEWZOOM] = (unsigned short) MSG_ReadShort();
else
- i = MSG_ReadByte();
- if (i < 2)
- i = 2;
- cl.viewzoomnew = (float) i * (1.0f / 255.0f);
+ cl.stats[STAT_VIEWZOOM] = MSG_ReadByte();
}
- else
- cl.viewzoomnew = 1;
+ // check for important changes
+
+ // set flash times
+ if (cl.olditems != cl.stats[STAT_ITEMS])
+ for (j = 0;j < 32;j++)
+ if ((cl.stats[STAT_ITEMS] & (1<<j)) && !(cl.olditems & (1<<j)))
+ cl.item_gettime[j] = cl.time;
+ cl.olditems = cl.stats[STAT_ITEMS];
+
+ // GAME_NEXUIZ hud needs weapon change time
+ if (cl.activeweapon != cl.stats[STAT_ACTIVEWEAPON])
+ cl.weapontime = cl.time;
+ cl.activeweapon = cl.stats[STAT_ACTIVEWEAPON];
+
+ // viewzoom interpolation
+ cl.viewzoomold = cl.viewzoomnew;
+ cl.viewzoomnew = (float) max(cl.stats[STAT_VIEWZOOM], 2) * (1.0f / 255.0f);
}
/*
// hack for unmarked Nehahra movie demos which had a custom protocol
if (i == PROTOCOL_QUAKE && cls.demoplayback && demo_nehahra.integer)
i = PROTOCOL_NEHAHRAMOVIE;
- if (i != PROTOCOL_QUAKE && i != PROTOCOL_DARKPLACES1 && i != PROTOCOL_DARKPLACES2 && i != PROTOCOL_DARKPLACES3 && i != PROTOCOL_DARKPLACES4 && i != PROTOCOL_DARKPLACES5 && i != PROTOCOL_NEHAHRAMOVIE)
- Host_Error("CL_ParseServerMessage: Server is protocol %i, not %i (Quake), %i (DP1), %i (DP2), %i (DP3), %i (DP4), %i (DP5), or %i (Nehahra movie)", i, PROTOCOL_QUAKE, PROTOCOL_DARKPLACES1, PROTOCOL_DARKPLACES2, PROTOCOL_DARKPLACES3, PROTOCOL_DARKPLACES4, PROTOCOL_DARKPLACES5, PROTOCOL_NEHAHRAMOVIE);
+ if (i != PROTOCOL_QUAKE && i != PROTOCOL_DARKPLACES1 && i != PROTOCOL_DARKPLACES2 && i != PROTOCOL_DARKPLACES3 && i != PROTOCOL_DARKPLACES4 && i != PROTOCOL_DARKPLACES5 && i != PROTOCOL_DARKPLACES6 && i != PROTOCOL_NEHAHRAMOVIE)
+ Host_Error("CL_ParseServerMessage: Server is protocol %i, not %i (Quake), %i (DP1), %i (DP2), %i (DP3), %i (DP4), %i (DP5), %i (DP6), or %i (Nehahra movie)", i, PROTOCOL_QUAKE, PROTOCOL_DARKPLACES1, PROTOCOL_DARKPLACES2, PROTOCOL_DARKPLACES3, PROTOCOL_DARKPLACES4, PROTOCOL_DARKPLACES5, PROTOCOL_DARKPLACES6, PROTOCOL_NEHAHRAMOVIE);
cl.protocol = i;
break;
CL_ParseStartSoundPacket(false);
break;
- case svc_sound2:
- CL_ParseStartSoundPacket(true);
+ case svc_precache:
+ if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
+ {
+ // was svc_sound2 in protocols 1, 2, 3, removed in 4, 5, changed to svc_precache in 6
+ CL_ParseStartSoundPacket(true);
+ }
+ else
+ {
+ int i = (unsigned short)MSG_ReadShort();
+ char *s = MSG_ReadString();
+ if (i < 32768)
+ {
+ if (i >= 1 && i < MAX_MODELS)
+ {
+ model_t *model = Mod_ForName(s, false, false, i == 1);
+ if (!model)
+ Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
+ cl.model_precache[i] = model;
+ }
+ else
+ Con_Printf("svc_precache: index %i outside range %i...%i\n", i, 1, MAX_MODELS);
+ }
+ else
+ {
+ i -= 32768;
+ if (i >= 1 && i < MAX_SOUNDS)
+ {
+ sfx_t *sfx = S_PrecacheSound (s, true, false);
+ // FIXME: SFXFLAG_SERVEROSUND should be set on the sfx
+ if (!sfx)
+ Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);
+ cl.sound_precache[i] = sfx;
+ }
+ else
+ Con_Printf("svc_precache: index %i outside range %i...%i\n", i, 1, MAX_SOUNDS);
+ }
+ }
break;
case svc_stopsound:
cl.stats[i] = MSG_ReadLong ();
break;
+ case svc_updatestatubyte:
+ i = MSG_ReadByte ();
+ if (i < 0 || i >= MAX_CL_STATS)
+ Host_Error ("svc_updatestat: %i is invalid", i);
+ cl.stats[i] = MSG_ReadByte ();
+ break;
+
case svc_spawnstaticsound:
CL_ParseStaticSound (false);
break;
EntityFrame_CL_ReadFrame();
else if (cl.protocol == PROTOCOL_DARKPLACES4)
EntityFrame4_CL_ReadFrame();
- else if (cl.protocol == PROTOCOL_DARKPLACES5)
+ else if (cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
EntityFrame5_CL_ReadFrame();
else
Host_Error("CL_ParseServerMessage: svc_entities: unknown cl.protocol %i\n", cl.protocol);
// render flags
int flags;
+ // colormod tinting of models
+ float colormod[3];
+
// interpolated animation
// frame that the model is interpolating from
float forwardmove;
float sidemove;
float upmove;
+
+ vec3_t cursor_screen;
+ vec3_t cursor_start;
+ vec3_t cursor_end;
+ vec3_t cursor_impact;
+ vec3_t cursor_normal;
+ vec_t cursor_fraction;
+ int cursor_entitynumber;
} usercmd_t;
typedef struct
// send a clc_nop periodically until connected
float sendnoptime;
- // last command sent to the server
+ // current input to send to the server
usercmd_t cmd;
// information for local display
// health, etc
int stats[MAX_CL_STATS];
- // inventory bit flags
- int items;
+ // last known inventory bit flags, for blinking
+ int olditems;
// cl.time of acquiring item, for blinking
float item_gettime[32];
+ // last known STAT_ACTIVEWEAPON
+ int activeweapon;
// cl.time of changing STAT_ACTIVEWEAPON
float weapontime;
// use pain anim frame if cl.time < this
float driftmove;
double laststop;
- float viewheight;
// local amount for smoothing stepups
//float crouch;
int protocol;
// entity database stuff
- // latest received entity frame number
- int latestframenum;
+ // latest received entity frame numbers
+#define LATESTFRAMENUMS 3
+ int latestframenums[LATESTFRAMENUMS];
entityframe_database_t *entitydatabase;
entityframe4_database_t *entitydatabase4;
}
extern cvar_t cl_stainmaps;
extern cvar_t cl_stainmapsclearonload;
+extern cvar_t cl_prydoncursor;
+
// these are updated by CL_ClearState
extern int cl_num_entities;
extern int cl_num_static_entities;
extern kbutton_t in_speed;
void CL_InitInput (void);
-void CL_SendCmd (usercmd_t *cmd);
-void CL_SendMove (usercmd_t *cmd);
+void CL_SendCmd (void);
+void CL_SendMove (void);
void CL_ValidateState(entity_state_t *s);
void CL_MoveLerpEntityStates(entity_t *ent);
int CL_ReadFromServer (void);
-void CL_WriteToServer (usercmd_t *cmd);
-void CL_BaseMove (usercmd_t *cmd);
+void CL_WriteToServer (void);
+void CL_BaseMove (void);
float CL_KeyState (kbutton_t *key);
void MSG_WriteCoord (sizebuf_t *sb, float f, int protocol)
{
- if (protocol == PROTOCOL_QUAKE)
+ if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_NEHAHRAMOVIE)
MSG_WriteCoord13i (sb, f);
- else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5)
+ else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6)
MSG_WriteCoord32f (sb, f);
else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
MSG_WriteCoord16i (sb, f);
void MSG_WriteAngle (sizebuf_t *sb, float f, int protocol)
{
- if (protocol == PROTOCOL_DARKPLACES5)
+ if (protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6)
MSG_WriteAngle16i (sb, f);
else
MSG_WriteAngle8i (sb, f);
float MSG_ReadCoord (int protocol)
{
- if (protocol == PROTOCOL_QUAKE || protocol == 250)
+ if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_NEHAHRAMOVIE)
return MSG_ReadCoord13i();
- else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5)
+ else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6)
return MSG_ReadCoord32f();
else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
return MSG_ReadCoord16i();
float MSG_ReadAngle (int protocol)
{
- if (protocol == PROTOCOL_DARKPLACES5)
+ if (protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6)
return MSG_ReadAngle16i ();
else
return MSG_ReadAngle8i ();
pic->tex = draw_generateconchars();
if (pic->tex == NULL && !strcmp(path, "ui/mousepointer.tga"))
pic->tex = draw_generatemousepointer();
+ if (pic->tex == NULL && !strcmp(path, "gfx/prydoncursor001.tga"))
+ pic->tex = draw_generatemousepointer();
if (pic->tex == NULL && !strcmp(path, "gfx/crosshair1.tga"))
pic->tex = draw_generatecrosshair(0);
if (pic->tex == NULL && !strcmp(path, "gfx/crosshair2.tga"))
}
else
tint[0] = tint[1] = tint[2] = 1;
+ tint[0] *= ent->colormod[0];
+ tint[1] *= ent->colormod[1];
+ tint[2] *= ent->colormod[2];
if (!fullbright && !(ent->flags & RENDER_TRANSPARENT))
colorscale *= r_lightmapintensity;
colorscale *= ifog;
base = fullbright ? 2.0f : r_ambient.value * (1.0f / 64.0f);
if (surf->flags & SURF_DRAWTURB)
base *= 0.5f;
- if ((surf->flags & SURF_DRAWTURB) && gl_textureshader && r_watershader.value && !fogenabled && fullbright)
+ if ((surf->flags & SURF_DRAWTURB) && gl_textureshader && r_watershader.value && !fogenabled && fullbright && ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1)
{
// NVIDIA Geforce3 distortion texture shader on water
GL_Color(1, 1, 1, currentalpha);
m.texrgbscale[0] = 4;
colorscale *= 0.25f;
}
- R_FillColors(varray_color4f, surf->mesh.num_vertices, base, base, base, currentalpha);
+ R_FillColors(varray_color4f, surf->mesh.num_vertices, base * ent->colormod[0], base * ent->colormod[1], base * ent->colormod[2], currentalpha);
if (!fullbright)
{
if (surf->dlightframe == r_framecount)
m.tex[3] = R_GetTexture(texture->skin.glow);
m.texcombinergb[3] = GL_ADD;
}
- GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
while((surf = *surfchain++) != NULL)
{
m.texrgbscale[1] = 2;
m.tex[2] = R_GetTexture(texture->skin.detail);
m.texrgbscale[2] = 2;
- GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
while((surf = *surfchain++) != NULL)
{
m.tex[0] = R_GetTexture(texture->skin.base);
m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
m.texrgbscale[1] = 2;
- GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
GL_BlendFunc(GL_ONE, GL_ZERO);
m.tex[0] = R_GetTexture(texture->skin.base);
if (ent->flags & RENDER_LIGHT)
- GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
else
- GL_Color(1, 1, 1, 1);
+ GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
GL_DepthMask(false);
GL_DepthTest(true);
m.tex[0] = R_GetTexture(texture->skin.base);
- GL_Color(r_ambient.value * (1.0f / 128.0f), r_ambient.value * (1.0f / 128.0f), r_ambient.value * (1.0f / 128.0f), 1);
+ GL_Color(r_ambient.value * (1.0f / 128.0f) * ent->colormod[0], r_ambient.value * (1.0f / 128.0f) * ent->colormod[1], r_ambient.value * (1.0f / 128.0f) * ent->colormod[2], 1);
while((surf = *surfchain++) != NULL)
{
if (surf->visframe == r_framecount)
{
m.tex[1] = R_GetTexture(face->lightmaptexture);
m.pointer_texcoord[1] = face->data_texcoordlightmap2f;
- GL_Color(1, 1, 1, ent->alpha);
+ GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], ent->alpha);
}
else
{
- if (ent->alpha == 1)
+ if (ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1 && ent->alpha == 1)
m.pointer_color = face->data_color4f;
else
{
int i;
for (i = 0;i < face->num_vertices;i++)
{
- varray_color4f[i*4+0] = face->data_color4f[i*4+0];
- varray_color4f[i*4+1] = face->data_color4f[i*4+1];
- varray_color4f[i*4+2] = face->data_color4f[i*4+2];
+ varray_color4f[i*4+0] = face->data_color4f[i*4+0] * ent->colormod[0];
+ varray_color4f[i*4+1] = face->data_color4f[i*4+1] * ent->colormod[1];
+ varray_color4f[i*4+2] = face->data_color4f[i*4+2] * ent->colormod[2];
varray_color4f[i*4+3] = face->data_color4f[i*4+3] * ent->alpha;
}
m.pointer_color = varray_color4f;
int i;
for (i = 0;i < face->num_vertices;i++)
{
- varray_color4f[i*4+0] = face->data_color4f[i*4+0] * 2.0f;
- varray_color4f[i*4+1] = face->data_color4f[i*4+1] * 2.0f;
- varray_color4f[i*4+2] = face->data_color4f[i*4+2] * 2.0f;
+ varray_color4f[i*4+0] = face->data_color4f[i*4+0] * ent->colormod[0] * 2.0f;
+ varray_color4f[i*4+1] = face->data_color4f[i*4+1] * ent->colormod[1] * 2.0f;
+ varray_color4f[i*4+2] = face->data_color4f[i*4+2] * ent->colormod[2] * 2.0f;
varray_color4f[i*4+3] = face->data_color4f[i*4+3] * ent->alpha;
}
m.pointer_color = varray_color4f;
GL_DepthMask(true);
GL_DepthTest(true);
GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_Color(1, 1, 1, 1);
+ GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
qglDisable(GL_CULL_FACE);
memset(&m, 0, sizeof(m));
}
if (t->skin.glow)
{
+ GL_Color(1, 1, 1, 1);
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
GL_DepthMask(false);
m.tex[0] = R_GetTexture(t->skin.glow);
m.texrgbscale[1] = 2;
if (face->lightmaptexture)
{
- GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
m.pointer_color = NULL;
}
- else if (r_lightmapintensity == 1)
+ else if (r_lightmapintensity == 1 && ent->colormod[0] == 1 && ent->colormod[1] == 1 && ent->colormod[2] == 1)
m.pointer_color = face->data_color4f;
else
{
m.pointer_color = varray_color4f;
for (i = 0;i < face->num_vertices;i++)
{
- varray_color4f[i*4+0] = face->data_color4f[i*4+0] * r_lightmapintensity;
- varray_color4f[i*4+1] = face->data_color4f[i*4+1] * r_lightmapintensity;
- varray_color4f[i*4+2] = face->data_color4f[i*4+2] * r_lightmapintensity;
+ varray_color4f[i*4+0] = face->data_color4f[i*4+0] * ent->colormod[0] * r_lightmapintensity;
+ varray_color4f[i*4+1] = face->data_color4f[i*4+1] * ent->colormod[1] * r_lightmapintensity;
+ varray_color4f[i*4+2] = face->data_color4f[i*4+2] * ent->colormod[2] * r_lightmapintensity;
varray_color4f[i*4+3] = face->data_color4f[i*4+3];
}
}
}
GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
GL_DepthMask(false);
- GL_Color(r_lightmapintensity, r_lightmapintensity, r_lightmapintensity, 1);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(t->skin.base);
for (texturefaceindex = 0;texturefaceindex < texturenumfaces;texturefaceindex++)
{
GL_BlendFunc(GL_ONE, GL_ONE);
GL_DepthMask(false);
- GL_Color(r_ambient.value * (1.0f / 128.0f), r_ambient.value * (1.0f / 128.0f), r_ambient.value * (1.0f / 128.0f), 1);
+ GL_Color(r_ambient.value * (1.0f / 128.0f) * ent->colormod[0], r_ambient.value * (1.0f / 128.0f) * ent->colormod[1], r_ambient.value * (1.0f / 128.0f) * ent->colormod[2], 1);
memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(t->skin.base);
for (texturefaceindex = 0;texturefaceindex < texturenumfaces;texturefaceindex++)
static double time2 = 0;
static double time3 = 0;
int pass1, pass2, pass3;
- usercmd_t cmd; // Used for receiving input
if (setjmp(host_abortserver))
return; // something bad happened, or the server disconnected
IN_Commands();
// Collect input into cmd
- IN_ProcessMove(&cmd);
+ IN_ProcessMove();
// process console commands
Cbuf_Execute();
// if running the server locally, make intentions now
if (cls.state == ca_connected && sv.active)
- CL_SendCmd(&cmd);
+ CL_SendCmd();
//-------------------
//
// if running the server remotely, send intentions now after
// the incoming messages have been read
if (!sv.active)
- CL_SendCmd(&cmd);
+ CL_SendCmd();
CL_ReadFromServer();
}
case PROTOCOL_DARKPLACES3: protocolname = "PROTOCOL_DARKPLACES3";break;
case PROTOCOL_DARKPLACES4: protocolname = "PROTOCOL_DARKPLACES4";break;
case PROTOCOL_DARKPLACES5: protocolname = "PROTOCOL_DARKPLACES5";break;
+ case PROTOCOL_DARKPLACES6: protocolname = "PROTOCOL_DARKPLACES6";break;
default: protocolname = "PROTOCOL_UNKNOWN";break;
}
print ("protocol: %i (%s)\n", sv.protocol, protocolname);
client_t *client;
func_t RestoreGame;
mfunction_t *f;
+ int stats[MAX_CL_STATS];
if (cmd_source == src_command)
{
MSG_WriteAngle (&host_client->message, host_client->edict->v->angles[1], sv.protocol);
MSG_WriteAngle (&host_client->message, 0, sv.protocol);
- SV_WriteClientdataToMessage (host_client->edict, &host_client->message);
+ SV_WriteClientdataToMessage (host_client, host_client->edict, &host_client->message, stats);
MSG_WriteByte (&host_client->message, svc_signonnum);
MSG_WriteByte (&host_client->message, 3);
// oportunity for devices to stick commands on the script buffer
// AK added to allow mouse movement for the menu
-void IN_ProcessMove(usercmd_t *cmd);
+void IN_ProcessMove(void);
-void IN_Move (usercmd_t *cmd);
+void IN_Move (void);
// add additional movement on top of the keyboard move cmd
void IN_PreMove(void);
void IN_PostMove(void);
-void IN_Mouse(usercmd_t *cmd, float mx, float my);
+void IN_Mouse(float mx, float my);
void IN_ClearStates (void);
// restores all button and position states to defaults
}
char *ENGINE_EXTENSIONS =
+"DP_BUTTONCHAT "
+"DP_BUTTONUSE "
"DP_CL_LOADSKY "
"DP_CON_SET "
"DP_CON_SETA "
"NEH_CMD_PLAY2 "
"NEH_RESTOREGAME "
"NXQ_GFX_LETTERBOX "
+"PRYDON_CLIENTCURSOR "
"TENEBRAE_GFX_DLIGHTS "
"TW_SV_STEPCONTROL "
;
setmodel(entity, model)
=================
*/
+static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
void PF_setmodel (void)
{
edict_t *e;
- char *m, **check;
model_t *mod;
int i;
PF_WARNING("setmodel: can not modify world entity\n");
if (e->e->free)
PF_WARNING("setmodel: can not modify free entity\n");
- m = G_STRING(OFS_PARM1);
-
-// check to see if model was properly precached
- for (i=0, check = sv.model_precache ; *check ; i++, check++)
- if (!strcmp(*check, m))
- break;
-
- if (!*check)
- PF_WARNING(va("setmodel: no precache for model \"%s\"\n", m));
-
-
- e->v->model = PR_SetString(*check);
+ i = SV_ModelIndex(G_STRING(OFS_PARM1), 1);
+ e->v->model = PR_SetString(sv.model_precache[i]);
e->v->modelindex = i;
- mod = sv.models[ (int)e->v->modelindex];
+ mod = sv.models[i];
if (mod)
- SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
+ {
+ if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
+ SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
+ else
+ SetMinMaxSize (e, quakemins, quakemaxs, true);
+ }
else
SetMinMaxSize (e, vec3_origin, vec3_origin, true);
}
*/
void PF_ambientsound (void)
{
- char **check;
char *samp;
float *pos;
float vol, attenuation;
attenuation = G_FLOAT(OFS_PARM3);
// check to see if samp was properly precached
- for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++)
- if (!strcmp(*check,samp))
- break;
-
- if (!*check)
- {
- Con_Printf("no precache: %s\n", samp);
+ soundnum = SV_SoundIndex(samp, 1);
+ if (!soundnum)
return;
- }
large = false;
if (soundnum >= 256)
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
}
+
void PF_precache_sound (void)
{
- char *s;
- int i;
- int limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_SOUNDS);
-
- if (sv.state != ss_loading)
- PF_ERROR("PF_Precache_*: Precache can only be done in spawn functions");
-
- s = G_STRING(OFS_PARM0);
+ SV_SoundIndex(G_STRING(OFS_PARM0), 2);
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
- PR_CheckEmptyString (s);
-
- for (i=0 ; i<limit ; i++)
- {
- if (!sv.sound_precache[i])
- {
- sv.sound_precache[i] = s;
- return;
- }
- if (!strcmp(sv.sound_precache[i], s))
- return;
- }
- PF_ERROR("PF_precache_sound: overflow");
}
void PF_precache_model (void)
{
- char *s;
- int i;
- int limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_MODELS);
-
- if (sv.state != ss_loading)
- PF_ERROR("PF_Precache_*: Precache can only be done in spawn functions");
-
- s = G_STRING(OFS_PARM0);
- if (sv.worldmodel->brush.ishlbsp && ((!s) || (!s[0])))
- return;
+ SV_ModelIndex(G_STRING(OFS_PARM0), 2);
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
- PR_CheckEmptyString (s);
-
- for (i = 0;i < limit;i++)
- {
- if (!sv.model_precache[i])
- {
- sv.model_precache[i] = s;
- sv.models[i] = Mod_ForName (s, true, false, false);
- return;
- }
- if (!strcmp(sv.model_precache[i], s))
- return;
- }
- PF_ERROR("PF_precache_model: overflow");
}
if (!s || !s[0])
PF_WARNING("effect: no model specified\n");
- i = SV_ModelIndex(s);
- if (i < 0)
+ i = SV_ModelIndex(s, 1);
+ if (!i)
PF_WARNING("effect: model not precached\n");
SV_StartEffect(G_VECTOR(OFS_PARM0), i, G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
}
int tagindex, i;
model_t *model;
- model = sv.models[(int)e->v->modelindex];
+ i = e->v->modelindex;
+ if (i < 1 || i >= MAX_MODELS)
+ return -1;
+ model = sv.models[i];
tagindex = -1;
if (model->data_overridetagnamesforskin && (unsigned int)e->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)e->v->skin].num_overridetagnames)
{
attachent = EDICT_NUM(val->edict); // to this it entity our entity is attached
val = GETEDICTFIELDVALUE(ent, eval_tag_index);
- if (val->_float)
- {// got tagname on parent entity attachment tag via tag_index (and got it's matrix)
+ Matrix4x4_CreateIdentity(&attachmatrix);
+ if (val->_float >= 1 && attachent->v->modelindex >= 1 && attachent->v->modelindex < MAX_MODELS)
+ {
model = sv.models[(int)attachent->v->modelindex];
- reqtag = (val->_float - 1) + attachent->v->frame*model->alias.aliasnum_tags;
- Matrix4x4_Copy(&attachmatrix, &model->alias.aliasdata_tags[reqtag].matrix);
+ if (val->_float < model->alias.aliasnum_tags)
+ {
+ // got tagname on parent entity attachment tag via tag_index (and got it's matrix)
+ model = sv.models[(int)attachent->v->modelindex];
+ reqtag = (val->_float - 1) + attachent->v->frame*model->alias.aliasnum_tags;
+ Matrix4x4_Copy(&attachmatrix, &model->alias.aliasdata_tags[reqtag].matrix);
+ }
}
- else
- Matrix4x4_CreateIdentity(&attachmatrix);
// apply transformation by child entity matrix
val = GETEDICTFIELDVALUE(ent, eval_scale);
attachloop += 1;
if (attachloop > 255) // prevent runaway looping
return 5;
- }
+ }
while ((val = GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict);
}
int eval_button6;
int eval_button7;
int eval_button8;
+int eval_buttonuse;
+int eval_buttonchat;
int eval_glow_size;
int eval_glow_trail;
int eval_glow_color;
int eval_color;
int eval_style;
int eval_pflags;
+int eval_cursor_active;
+int eval_cursor_screen;
+int eval_cursor_trace_start;
+int eval_cursor_trace_endpos;
+int eval_cursor_trace_ent;
+int eval_colormod;
mfunction_t *SV_PlayerPhysicsQC;
mfunction_t *EndFrameQC;
eval_button6 = FindFieldOffset("button6");
eval_button7 = FindFieldOffset("button7");
eval_button8 = FindFieldOffset("button8");
+ eval_buttonuse = FindFieldOffset("buttonuse");
+ eval_buttonchat = FindFieldOffset("buttonchat");
eval_glow_size = FindFieldOffset("glow_size");
eval_glow_trail = FindFieldOffset("glow_trail");
eval_glow_color = FindFieldOffset("glow_color");
eval_color = FindFieldOffset("color");
eval_style = FindFieldOffset("style");
eval_pflags = FindFieldOffset("pflags");
+ eval_cursor_active = FindFieldOffset("cursor_active");
+ eval_cursor_screen = FindFieldOffset("cursor_screen");
+ eval_cursor_trace_start = FindFieldOffset("cursor_trace_start");
+ eval_cursor_trace_endpos = FindFieldOffset("cursor_trace_endpos");
+ eval_cursor_trace_ent = FindFieldOffset("cursor_trace_ent");
+ eval_colormod = FindFieldOffset("colormod");
// LordHavoc: allowing QuakeC to override the player movement code
SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
dpfield_t dpfields[] =
{
- {ev_float, "gravity"},
+ {ev_entity, "cursor_trace_ent"},
+ {ev_entity, "drawonlytoclient"},
+ {ev_entity, "exteriormodeltoclient"},
+ {ev_entity, "nodrawtoclient"},
+ {ev_entity, "tag_entity"},
+ {ev_entity, "viewmodelforclient"},
+ {ev_float, "alpha"},
+ {ev_float, "ammo_cells1"},
+ {ev_float, "ammo_lava_nails"},
+ {ev_float, "ammo_multi_rockets"},
+ {ev_float, "ammo_nails1"},
+ {ev_float, "ammo_plasma"},
+ {ev_float, "ammo_rockets1"},
+ {ev_float, "ammo_shells1"},
{ev_float, "button3"},
{ev_float, "button4"},
{ev_float, "button5"},
{ev_float, "button6"},
{ev_float, "button7"},
{ev_float, "button8"},
+ {ev_float, "buttonchat"},
+ {ev_float, "buttonuse"},
+ {ev_float, "clientcolors"},
+ {ev_float, "cursor_active"},
+ {ev_float, "fullbright"},
+ {ev_float, "glow_color"},
{ev_float, "glow_size"},
{ev_float, "glow_trail"},
- {ev_float, "glow_color"},
- {ev_float, "items2"},
- {ev_float, "scale"},
- {ev_float, "alpha"},
- {ev_float, "renderamt"},
- {ev_float, "rendermode"},
- {ev_float, "fullbright"},
- {ev_float, "ammo_shells1"},
- {ev_float, "ammo_nails1"},
- {ev_float, "ammo_lava_nails"},
- {ev_float, "ammo_rockets1"},
- {ev_float, "ammo_multi_rockets"},
- {ev_float, "ammo_cells1"},
- {ev_float, "ammo_plasma"},
+ {ev_float, "gravity"},
{ev_float, "idealpitch"},
- {ev_float, "pitch_speed"},
- {ev_entity, "viewmodelforclient"},
- {ev_entity, "nodrawtoclient"},
- {ev_entity, "exteriormodeltoclient"},
- {ev_entity, "drawonlytoclient"},
+ {ev_float, "items2"},
+ {ev_float, "light_lev"},
+ {ev_float, "pflags"},
{ev_float, "ping"},
- {ev_vector, "movement"},
+ {ev_float, "pitch_speed"},
{ev_float, "pmodel"},
- {ev_vector, "punchvector"},
- {ev_float, "clientcolors"},
- {ev_entity, "tag_entity"},
+ {ev_float, "renderamt"}, // HalfLife support
+ {ev_float, "rendermode"}, // HalfLife support
+ {ev_float, "scale"},
+ {ev_float, "style"},
{ev_float, "tag_index"},
- {ev_float, "light_lev"},
+ {ev_float, "viewzoom"},
{ev_vector, "color"},
- {ev_float, "style"},
- {ev_float, "pflags"}
+ {ev_vector, "colormod"},
+ {ev_vector, "cursor_screen"},
+ {ev_vector, "cursor_trace_endpos"},
+ {ev_vector, "cursor_trace_start"},
+ {ev_vector, "movement"},
+ {ev_vector, "punchvector"}
};
/*
extern int eval_button6;
extern int eval_button7;
extern int eval_button8;
+extern int eval_buttonuse;
+extern int eval_buttonchat;
extern int eval_glow_size;
extern int eval_glow_trail;
extern int eval_glow_color;
extern int eval_color;
extern int eval_style;
extern int eval_pflags;
+extern int eval_cursor_active;
+extern int eval_cursor_screen;
+extern int eval_cursor_trace_start;
+extern int eval_cursor_trace_endpos;
+extern int eval_cursor_trace_ent;
+extern int eval_colormod;
#define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((qbyte *)ed->v + fieldoffset) : NULL)
254,//unsigned char glowcolor;
0,//unsigned char flags;
0,//unsigned char tagindex;
- 255,//unsigned char colormod;
+ {32, 32, 32},//unsigned char colormod[3];
// padding to a multiple of 8 bytes (to align the double time)
- {0,0,0,0}//unsigned char unused[4]; // !
+ {0,0}//unsigned char unused[2]; // !
};
// keep track of quake entities because they need to be killed if they get stale
if (bits & U_EFFECTS2) s.effects = (s.effects & 0x00FF) | (MSG_ReadByte() << 8);
if (bits & U_GLOWSIZE) s.glowsize = MSG_ReadByte();
if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte();
- if (bits & U_COLORMOD) s.colormod = MSG_ReadByte();
+ if (bits & U_COLORMOD) {int c = MSG_ReadByte();s.colormod[0] = (qbyte)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (qbyte)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (qbyte)((c & 3) * (32.0f / 3.0f));}
if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL;
if (bits & U_FRAME2) s.frame = (s.frame & 0x00FF) | (MSG_ReadByte() << 8);
if (bits & U_MODEL2) s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
if (bits & U_EFFECTS2) MSG_WriteByte(&buf, s->effects >> 8);
if (bits & U_GLOWSIZE) MSG_WriteByte(&buf, s->glowsize);
if (bits & U_GLOWCOLOR) MSG_WriteByte(&buf, s->glowcolor);
- if (bits & U_COLORMOD) MSG_WriteByte(&buf, s->colormod);
+ if (bits & U_COLORMOD) {int c = ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 5) | ((int)bound(0, s->colormod[0] * (7.0f / 32.0f), 7) << 2) | ((int)bound(0, s->colormod[0] * (3.0f / 32.0f), 3) << 0);MSG_WriteByte(&buf, c);}
if (bits & U_FRAME2) MSG_WriteByte(&buf, s->frame >> 8);
if (bits & U_MODEL2) MSG_WriteByte(&buf, s->modelindex >> 8);
if (bits & E_ORIGIN3)
MSG_WriteCoord16i(msg, ent->origin[2]);
}
- else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
{
// LordHavoc: have to write flags first, as they can modify protocol
if (bits & E_FLAGS)
MSG_WriteCoord32f(msg, ent->origin[2]);
}
}
- if (sv.protocol == PROTOCOL_DARKPLACES5 && !(ent->flags & RENDER_LOWPRECISION))
+ if ((sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6) && !(ent->flags & RENDER_LOWPRECISION))
{
if (bits & E_ANGLE1)
MSG_WriteAngle16i(msg, ent->angles[0]);
if (bits & E_ORIGIN3)
e->origin[2] = MSG_ReadCoord16i();
}
- else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES3 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5)
+ else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES3 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6)
{
if (bits & E_FLAGS)
e->flags = MSG_ReadByte();
}
else
Host_Error("EntityState_ReadFields: unknown cl.protocol %i\n", cl.protocol);
- if (cl.protocol == PROTOCOL_DARKPLACES5 && !(e->flags & RENDER_LOWPRECISION))
+ if ((cl.protocol == PROTOCOL_DARKPLACES5 || cl.protocol == PROTOCOL_DARKPLACES6) && !(e->flags & RENDER_LOWPRECISION))
{
if (bits & E_ANGLE1)
e->angles[0] = MSG_ReadAngle16i();
// read the frame header info
f->time = cl.mtime[0];
number = MSG_ReadLong();
- cl.latestframenum = f->framenum = MSG_ReadLong();
+ for (i = 0;i < LATESTFRAMENUMS-1;i++)
+ cl.latestframenums[i] = cl.latestframenums[i+1];
+ cl.latestframenums[LATESTFRAMENUMS-1] = f->framenum = MSG_ReadLong();
f->eye[0] = MSG_ReadFloat();
f->eye[1] = MSG_ReadFloat();
f->eye[2] = MSG_ReadFloat();
// read the number of the frame this refers to
referenceframenum = MSG_ReadLong();
// read the number of this frame
- cl.latestframenum = framenum = MSG_ReadLong();
+ for (i = 0;i < LATESTFRAMENUMS-1;i++)
+ cl.latestframenums[i] = cl.latestframenums[i+1];
+ cl.latestframenums[LATESTFRAMENUMS-1] = framenum = MSG_ReadLong();
// read the start number
enumber = (unsigned short) MSG_ReadShort();
if (developer_networkentities.integer >= 1)
MSG_WriteByte(msg, s->glowsize);
MSG_WriteByte(msg, s->glowcolor);
}
+ if (bits & E5_COLORMOD)
+ {
+ MSG_WriteByte(msg, s->colormod[0]);
+ MSG_WriteByte(msg, s->colormod[1]);
+ MSG_WriteByte(msg, s->colormod[2]);
+ }
}
}
s->glowsize = MSG_ReadByte();
s->glowcolor = MSG_ReadByte();
}
+ if (bits & E5_COLORMOD)
+ {
+ s->colormod[0] = MSG_ReadByte();
+ s->colormod[1] = MSG_ReadByte();
+ s->colormod[2] = MSG_ReadByte();
+ }
if (developer_networkentities.integer >= 2)
Con_Printf(" E5_LIGHT %i:%i:%i:%i %i:%i", s->light[0], s->light[1], s->light[2], s->light[3], s->lightstyle, s->lightpflags);
if (bits & E5_GLOW)
Con_Printf(" E5_GLOW %i:%i", s->glowsize * 4, s->glowcolor);
+ if (bits & E5_COLORMOD)
+ Con_Printf(" E5_COLORMOD %f:%f:%f", s->colormod[0] / 32.0f, s->colormod[1] / 32.0f, s->colormod[2] / 32.0f);
Con_Print("\n");
}
}
bits |= E5_LIGHT;
if (o->glowsize != n->glowsize || o->glowcolor != n->glowcolor)
bits |= E5_GLOW;
+ if (o->colormod[0] != n->colormod[0] || o->colormod[1] != n->colormod[1] || o->colormod[2] != n->colormod[2])
+ bits |= E5_COLORMOD;
}
else
if (o->active)
void EntityFrame5_CL_ReadFrame(void)
{
- int n, enumber;
+ int i, n, enumber;
entity_t *ent;
entity_state_t *s;
// read the number of this frame to echo back in next input packet
- cl.latestframenum = MSG_ReadLong();
+ for (i = 0;i < LATESTFRAMENUMS-1;i++)
+ cl.latestframenums[i] = cl.latestframenums[i+1];
+ cl.latestframenums[LATESTFRAMENUMS-1] = MSG_ReadLong();
// read entity numbers until we find a 0x8000
// (which would be remove world entity, but is actually a terminator)
while ((n = (unsigned short)MSG_ReadShort()) != 0x8000 && !msg_badread)
}
}
-void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum, int viewentnum)
+void EntityFrame5_LostFrame(entityframe5_database_t *d, int framenum, int viewentnum)
{
int i, j, k, l, bits;
entityframe5_changestate_t *s, *s2;
entityframe5_packetlog_t *p, *p2;
- // scan for packets made obsolete by this ack
+ qbyte statsdeltabits[(MAX_CL_STATS+7)/8];
+ // scan for packets that were lost
for (i = 0, p = d->packetlog;i < ENTITYFRAME5_MAXPACKETLOGS;i++, p++)
{
- // skip packets that are empty or in the future
- if (p->packetnumber == 0 || p->packetnumber > framenum)
- continue;
- // if the packetnumber matches it is deleted without any processing
- // (since it was received).
- // if the packet number is less than this ack it was lost and its
- // important information will be repeated in this update if it is not
- // already obsolete due to a later update.
- if (p->packetnumber < framenum)
+ if (p->packetnumber && p->packetnumber <= framenum)
{
// packet was lost - merge deltabits into the main array so they
// will be re-sent, but only if there is no newer update of that
{
if (p2->packetnumber > framenum)
{
- for (l = 0, s2 = p2->states;l < p2->numstates;l++, p2++)
+ for (l = 0, s2 = p2->states;l < p2->numstates;l++, s2++)
{
if (s2->number == s->number)
{
d->priorities[s->number] = EntityState5_Priority(d, d->states + viewentnum, d->states + s->number, d->deltabits[s->number], d->latestframenum - d->updateframenum[s->number]);
}
}
+ // mark lost stats
+ for (j = 0;j < MAX_CL_STATS;j++)
+ {
+ for (l = 0;l < (MAX_CL_STATS+7)/8;l++)
+ statsdeltabits[l] = p->statsdeltabits[l] & ~d->statsdeltabits[l];
+ for (k = 0, p2 = d->packetlog;k < ENTITYFRAME5_MAXPACKETLOGS;k++, p2++)
+ if (p2->packetnumber > framenum)
+ for (l = 0;l < (MAX_CL_STATS+7)/8;l++)
+ statsdeltabits[l] = p->statsdeltabits[l] & ~p2->statsdeltabits[l];
+ for (l = 0;l < (MAX_CL_STATS+7)/8;l++)
+ d->statsdeltabits[l] |= statsdeltabits[l];
+ }
+ // delete this packet log as it is now obsolete
+ p->packetnumber = 0;
}
- // delete this packet log as it is now obsolete
- p->packetnumber = 0;
}
}
+void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum)
+{
+ int i;
+ // scan for packets made obsolete by this ack and delete them
+ for (i = 0;i < ENTITYFRAME5_MAXPACKETLOGS;i++)
+ if (d->packetlog[i].packetnumber <= framenum)
+ d->packetlog[i].packetnumber = 0;
+}
+
int entityframe5_prioritychaincounts[E5_PROTOCOL_PRIORITYLEVELS];
unsigned short entityframe5_prioritychains[E5_PROTOCOL_PRIORITYLEVELS][ENTITYFRAME5_MAXSTATES];
-void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum)
+void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int *stats)
{
const entity_state_t *n;
int i, num, l, framenum, packetlognumber, priority;
framenum = d->latestframenum + 1;
+ // if packet log is full, mark all frames as lost, this will cause
+ // it to send the lost data again
+ for (packetlognumber = 0;packetlognumber < ENTITYFRAME5_MAXPACKETLOGS;packetlognumber++)
+ if (d->packetlog[packetlognumber].packetnumber == 0)
+ break;
+ if (packetlognumber == ENTITYFRAME5_MAXPACKETLOGS)
+ {
+ EntityFrame5_LostFrame(d, framenum, viewentnum);
+ packetlognumber = 0;
+ }
+
// prepare the buffer
memset(&buf, 0, sizeof(buf));
buf.data = data;
buf.maxsize = sizeof(data);
+ // detect changes in stats
+ for (i = 0;i < MAX_CL_STATS;i++)
+ {
+ if (d->stats[i] != stats[i])
+ {
+ d->statsdeltabits[i>>3] |= (1<<(i&7));
+ d->stats[i] = stats[i];
+ }
+ }
+
// detect changes in states
num = 0;
for (i = 0, n = states;i < numstates;i++, n++)
}
}
- // return early if there are no entities to send this time
- if (l == 0)
- return;
-
+ // add packetlog entry
+ packetlog = d->packetlog + packetlognumber;
+ packetlog->packetnumber = framenum;
+ packetlog->numstates = 0;
+ // write stat updates
+ if (sv.protocol == PROTOCOL_DARKPLACES6)
+ {
+ for (i = 0;i < MAX_CL_STATS;i++)
+ {
+ if (d->statsdeltabits[i>>3] & (1<<(i&7)))
+ {
+ d->statsdeltabits[i>>3] &= ~(1<<(i&7));
+ packetlog->statsdeltabits[i>>3] |= (1<<(i&7));
+ if (d->stats[i] >= 0 && d->stats[i] < 256)
+ {
+ MSG_WriteByte(msg, svc_updatestatubyte);
+ MSG_WriteByte(msg, i);
+ MSG_WriteByte(msg, d->stats[i]);
+ }
+ else
+ {
+ MSG_WriteByte(msg, svc_updatestat);
+ MSG_WriteByte(msg, i);
+ MSG_WriteLong(msg, d->stats[i]);
+ }
+ }
+ }
+ }
+ // write state updates
d->latestframenum = framenum;
MSG_WriteByte(msg, svc_entities);
MSG_WriteLong(msg, framenum);
-
- // if packet log is full, an empty update is still written
- // (otherwise the client might have nothing to ack to remove packetlogs)
- for (packetlognumber = 0, packetlog = d->packetlog;packetlognumber < ENTITYFRAME5_MAXPACKETLOGS;packetlognumber++, packetlog++)
- if (packetlog->packetnumber == 0)
- break;
- if (packetlognumber < ENTITYFRAME5_MAXPACKETLOGS)
+ for (priority = E5_PROTOCOL_PRIORITYLEVELS - 1;priority >= 0 && packetlog->numstates < ENTITYFRAME5_MAXSTATES;priority--)
{
- // write to packet and log
- packetlog->packetnumber = framenum;
- packetlog->numstates = 0;
- for (priority = E5_PROTOCOL_PRIORITYLEVELS - 1;priority >= 0 && packetlog->numstates < ENTITYFRAME5_MAXSTATES;priority--)
+ for (i = 0;i < entityframe5_prioritychaincounts[priority] && packetlog->numstates < ENTITYFRAME5_MAXSTATES;i++)
{
- for (i = 0;i < entityframe5_prioritychaincounts[priority] && packetlog->numstates < ENTITYFRAME5_MAXSTATES;i++)
- {
- num = entityframe5_prioritychains[priority][i];
- n = d->states + num;
- if (d->deltabits[num] & E5_FULLUPDATE)
- d->deltabits[num] = E5_FULLUPDATE | EntityState5_DeltaBits(&defaultstate, n);
- buf.cursize = 0;
- EntityState5_WriteUpdate(num, n, d->deltabits[num], &buf);
- // if the entity won't fit, try the next one
- if (msg->cursize + buf.cursize + 2 > msg->maxsize)
- continue;
- // write entity to the packet
- SZ_Write(msg, buf.data, buf.cursize);
- // mark age on entity for prioritization
- d->updateframenum[num] = framenum;
- // log entity so deltabits can be restored later if lost
- packetlog->states[packetlog->numstates].number = num;
- packetlog->states[packetlog->numstates].bits = d->deltabits[num];
- packetlog->numstates++;
- // clear deltabits and priority so it won't be sent again
- d->deltabits[num] = 0;
- d->priorities[num] = 0;
- }
+ num = entityframe5_prioritychains[priority][i];
+ n = d->states + num;
+ if (d->deltabits[num] & E5_FULLUPDATE)
+ d->deltabits[num] = E5_FULLUPDATE | EntityState5_DeltaBits(&defaultstate, n);
+ buf.cursize = 0;
+ EntityState5_WriteUpdate(num, n, d->deltabits[num], &buf);
+ // if the entity won't fit, try the next one
+ if (msg->cursize + buf.cursize + 2 > msg->maxsize)
+ continue;
+ // write entity to the packet
+ SZ_Write(msg, buf.data, buf.cursize);
+ // mark age on entity for prioritization
+ d->updateframenum[num] = framenum;
+ // log entity so deltabits can be restored later if lost
+ packetlog->states[packetlog->numstates].number = num;
+ packetlog->states[packetlog->numstates].bits = d->deltabits[num];
+ packetlog->numstates++;
+ // clear deltabits and priority so it won't be sent again
+ d->deltabits[num] = 0;
+ d->priorities[num] = 0;
}
}
-
MSG_WriteShort(msg, 0x8000);
}
// entityframe5 protocol
#define PROTOCOL_DARKPLACES5 3502
+#define PROTOCOL_DARKPLACES6 3503
// model effects
#define EF_ROCKET 1 // leave a trail
#define EF_STARDUST 2048 // LordHavoc: showering sparks
#define EF_NOSHADOW 4096 // LordHavoc: does not cast a shadow
#define EF_NODEPTHTEST 8192 // LordHavoc: shows through walls
+#define EF_SELECTABLE 16384 // LordHavoc: highlights when PRYDON_CLIENTCURSOR mouse is over it
#define EF_STEP 0x80000000 // internal client use only - present on MOVETYPE_STEP entities, not QC accessible (too many bits)
#define U_EFFECTS2 (1<<19) // 1 byte, this is .effects & 0xFF00 (second byte)
#define U_GLOWSIZE (1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0
#define U_GLOWCOLOR (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set)
-// LordHavoc: colormod feature has been removed, because no one used it
#define U_COLORMOD (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend...
#define U_EXTEND2 (1<<23) // another byte to follow
// LordHavoc: second extend byte
// LordHavoc: my svc_ range, 50-59
#define svc_cgame 50 // [short] length [bytes] data
-#define svc_unusedlh1 51
+#define svc_updatestatubyte 51 // [byte] stat [byte] value
#define svc_effect 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
#define svc_effect2 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
-#define svc_sound2 54 // short soundindex instead of byte
+#define svc_sound2 54 // (obsolete in DP6 and later) short soundindex instead of byte
+#define svc_precache 54 // [short] precacheindex [string] filename, precacheindex is + 0 for modelindex and +32768 for soundindex
#define svc_spawnbaseline2 55 // short modelindex instead of byte
#define svc_spawnstatic2 56 // short modelindex instead of byte
#define svc_entities 57 // [int] deltaframe [int] thisframe [float vector] eye [variable length] entitydata
#define clc_stringcmd 4 // [string] message
// LordHavoc: my clc_ range, 50-59
-#define clc_ackentities 50 // [int] framenumber
+#define clc_ackframe 50 // [int] framenumber
#define clc_unusedlh1 51
#define clc_unusedlh2 52
#define clc_unusedlh3 53
unsigned char glowcolor;
unsigned char flags;
unsigned char tagindex;
- unsigned char colormod;
+ unsigned char colormod[3];
// padding to a multiple of 8 bytes (to align the double time)
- unsigned char unused[4];
+ unsigned char unused[2];
}
entity_state_t;
#define E5_EFFECTS32 (1<<20)
// flag
#define E5_FRAME16 (1<<21)
-// unused
-#define E5_UNUSED22 (1<<22)
+// byte[3] = s->colormod[0], s->colormod[1], s->colormod[2]
+#define E5_COLORMOD (1<<22)
// bits >= (1<<24)
#define E5_EXTEND3 (1<<23)
int packetnumber;
int numstates;
entityframe5_changestate_t states[ENTITYFRAME5_MAXSTATES];
+ qbyte statsdeltabits[(MAX_CL_STATS+7)/8];
}
entityframe5_packetlog_t;
// (derived from states)
qbyte visiblebits[(MAX_EDICTS+7)/8];
+ // delta compression of stats
+ qbyte statsdeltabits[(MAX_CL_STATS+7)/8];
+ int stats[MAX_CL_STATS];
+
// old notes
// this is used to decide which changestates to set each frame
void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbits, sizebuf_t *msg);
int EntityState5_DeltaBitsForState(entity_state_t *o, entity_state_t *n);
void EntityFrame5_CL_ReadFrame(void);
-void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum, int viewentnum);
-void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum);
+void EntityFrame5_LostFrame(entityframe5_database_t *d, int framenum, int viewentnum);
+void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum);
+void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int *stats);
extern cvar_t developer_networkentities;
//
// stats are integers communicated to the client by the server
//
-#define MAX_CL_STATS 32
+#define MAX_CL_STATS 256
#define STAT_HEALTH 0
#define STAT_FRAGS 1
#define STAT_WEAPON 2
#define STAT_TOTALMONSTERS 12
#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret
#define STAT_MONSTERS 14 // bumped by svc_killedmonster
+#define STAT_ITEMS 15 // FTE, DP
+#define STAT_VIEWHEIGHT 16 // FTE, DP
+//#define STAT_TIME 17 // FTE
+//#define STAT_VIEW2 20 // FTE
+#define STAT_VIEWZOOM 21 // DP
// stock defines
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
VectorScale(lightcolor, colorscale, color2);
+ GL_LockArrays(0, numverts);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
GL_Color(bound(0, color2[0], 1), bound(0, color2[1], 1), bound(0, color2[2], 1), 1);
- GL_LockArrays(0, numverts);
R_Mesh_Draw(numverts, numtriangles, elements);
- GL_LockArrays(0, 0);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
+ GL_LockArrays(0, 0);
}
if (diffusescale)
{
GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
VectorScale(lightcolor, colorscale, color2);
+ GL_LockArrays(0, numverts);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
GL_Color(bound(0, color2[0], 1), bound(0, color2[1], 1), bound(0, color2[2], 1), 1);
- GL_LockArrays(0, numverts);
R_Mesh_Draw(numverts, numtriangles, elements);
- GL_LockArrays(0, 0);
c_rt_lightmeshes++;
c_rt_lighttris += numtriangles;
}
+ GL_LockArrays(0, 0);
}
if (specularscale && (r_shadow_gloss.integer >= 2 || (r_shadow_gloss.integer >= 1 && glosstexture != r_shadow_blankglosstexture)))
{
#endif
}
}
+ R_Mesh_State(&m);
+ GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
+ GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
+ VectorScale(lightcolor, colorscale, color2);
+ GL_LockArrays(0, numverts);
+ for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
+ {
+ GL_Color(bound(0, color2[0], 1), bound(0, color2[1], 1), bound(0, color2[2], 1), 1);
+ R_Mesh_Draw(numverts, numtriangles, elements);
+ c_rt_lightmeshes++;
+ c_rt_lighttris += numtriangles;
+ }
+ GL_LockArrays(0, 0);
}
- R_Mesh_State(&m);
- GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 0);
- GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
- VectorScale(lightcolor, colorscale, color2);
- GL_LockArrays(0, numverts);
- for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
- {
- GL_Color(bound(0, color2[0], 1), bound(0, color2[1], 1), bound(0, color2[2], 1), 1);
- R_Mesh_Draw(numverts, numtriangles, elements);
- c_rt_lightmeshes++;
- c_rt_lighttris += numtriangles;
- }
- GL_LockArrays(0, 0);
}
}
else
#endif
}
}
+ if (r_textureunits.integer >= 3)
+ m.pointer_color = NULL;
+ else
+ m.pointer_color = varray_color4f;
R_Mesh_State(&m);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[1] = bound(0, color2[1], 1);
color[2] = bound(0, color2[2], 1);
if (r_textureunits.integer >= 3)
- {
GL_Color(color[0], color[1], color[2], 1);
- m.pointer_color = NULL;
- }
else if (r_textureunits.integer >= 2)
- {
R_Shadow_VertexNoShadingWithZAttenuation(numverts, vertex3f, color, matrix_modeltolight);
- m.pointer_color = varray_color4f;
- }
else
- {
R_Shadow_VertexNoShadingWithXYZAttenuation(numverts, vertex3f, color, matrix_modeltolight);
- m.pointer_color = varray_color4f;
- }
GL_LockArrays(0, numverts);
R_Mesh_Draw(numverts, numtriangles, elements);
GL_LockArrays(0, 0);
ent = &cl_entities[0].render;
if (ent->model && ent->model->DrawLight && (ent->flags & RENDER_LIGHT))
{
+ lightcolor2[0] = lightcolor[0] * ent->colormod[0] * ent->alpha;
+ lightcolor2[1] = lightcolor[1] * ent->colormod[1] * ent->alpha;
+ lightcolor2[2] = lightcolor[2] * ent->colormod[2] * ent->alpha;
Matrix4x4_Transform(&ent->inversematrix, rtlight->shadoworigin, relativelightorigin);
Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
Matrix4x4_Concat(&matrix_modeltolight, &rtlight->matrix_worldtolight, &ent->matrix);
{
R_Mesh_Matrix(&ent->matrix);
for (mesh = rtlight->static_meshchain_light;mesh;mesh = mesh->next)
- R_Shadow_RenderLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, mesh->map_specular, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale);
+ R_Shadow_RenderLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, mesh->map_specular, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale);
}
else
- ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, numsurfaces, surfacelist);
+ ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, rtlight->radius, lightcolor2, &matrix_modeltolight, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, cubemaptexture, rtlight->ambientscale, rtlight->diffusescale, rtlight->specularscale, numsurfaces, surfacelist);
}
if (r_drawentities.integer)
{
// transparent meshes are deferred for later
if (ent->visframe == r_framecount && BoxesOverlap(ent->mins, ent->maxs, cullmins, cullmaxs) && ent->model && ent->model->DrawLight && (ent->flags & (RENDER_LIGHT | RENDER_TRANSPARENT)) == RENDER_LIGHT)
{
- VectorScale(lightcolor, ent->alpha, lightcolor2);
+ lightcolor2[0] = lightcolor[0] * ent->colormod[0] * ent->alpha;
+ lightcolor2[1] = lightcolor[1] * ent->colormod[1] * ent->alpha;
+ lightcolor2[2] = lightcolor[2] * ent->colormod[2] * ent->alpha;
Matrix4x4_Transform(&ent->inversematrix, rtlight->shadoworigin, relativelightorigin);
Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, relativeeyeorigin);
Matrix4x4_Concat(&matrix_modeltolight, &rtlight->matrix_worldtolight, &ent->matrix);
R_CompleteLightPoint(color, diffusecolor, diffusenormal, ent->origin, true, NULL);
VectorMA(color, 0.5f, diffusecolor, color);
}
+ color[0] *= ent->colormod[0];
+ color[1] *= ent->colormod[1];
+ color[2] *= ent->colormod[2];
if (fogenabled)
{
// weapons
for (i=0 ; i<7 ; i++)
{
- if (cl.items & (IT_SHOTGUN<<i) )
+ if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
{
time = cl.item_gettime[i];
flashon = (int)((cl.time - time)*10);
int grenadeflashing=0;
for (i=0 ; i<4 ; i++)
{
- if (cl.items & (1<<hipweapons[i]) )
+ if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
{
time = cl.item_gettime[hipweapons[i]];
flashon = (int)((cl.time - time)*10);
// check grenade launcher
if (i==2)
{
- if (cl.items & HIT_PROXIMITY_GUN)
+ if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
{
if (flashon)
{
}
else if (i==3)
{
- if (cl.items & (IT_SHOTGUN<<4))
+ if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
{
if (!grenadeflashing)
Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
// items
for (i=0 ; i<6 ; i++)
- if (cl.items & (1<<(17+i)))
+ if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
{
//MED 01/04/97 changed keys
if (gamemode != GAME_HIPNOTIC || (i>1))
if (gamemode == GAME_HIPNOTIC)
{
for (i=0 ; i<2 ; i++)
- if (cl.items & (1<<(24+i)))
+ if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
}
{
// new rogue items
for (i=0 ; i<2 ; i++)
- if (cl.items & (1<<(29+i)))
+ if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
}
else
{
// sigils
for (i=0 ; i<4 ; i++)
- if (cl.items & (1<<(28+i)))
+ if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
}
}
}
// PGM 01/19/97 - team color drawing
- if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
+ if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
Sbar_DrawPic (112, 0, sb_face_invis_invuln);
- else if (cl.items & IT_QUAD)
+ else if (cl.stats[STAT_ITEMS] & IT_QUAD)
Sbar_DrawPic (112, 0, sb_face_quad );
- else if (cl.items & IT_INVISIBILITY)
+ else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
Sbar_DrawPic (112, 0, sb_face_invis );
- else if (cl.items & IT_INVULNERABILITY)
+ else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
Sbar_DrawPic (112, 0, sb_face_invuln);
else
{
// armor
if (cl.stats[STAT_ARMOR])
{
- if (cl.items & IT_ARMOR3)
+ if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
Sbar_DrawPic(0, 0, somsb_armor[2]);
- else if (cl.items & IT_ARMOR2)
+ else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
Sbar_DrawPic(0, 0, somsb_armor[1]);
- else if (cl.items & IT_ARMOR1)
+ else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
Sbar_DrawPic(0, 0, somsb_armor[0]);
Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
}
Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
// ammo icon
- if (cl.items & IT_SHELLS)
+ if (cl.stats[STAT_ITEMS] & IT_SHELLS)
Sbar_DrawPic(0, 48, somsb_ammo[0]);
- else if (cl.items & IT_NAILS)
+ else if (cl.stats[STAT_ITEMS] & IT_NAILS)
Sbar_DrawPic(0, 48, somsb_ammo[1]);
- else if (cl.items & IT_ROCKETS)
+ else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
Sbar_DrawPic(0, 48, somsb_ammo[2]);
- else if (cl.items & IT_CELLS)
+ else if (cl.stats[STAT_ITEMS] & IT_CELLS)
Sbar_DrawPic(0, 48, somsb_ammo[3]);
Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
if (cl.stats[STAT_SHELLS])
fade *= fade;
for (i = 0; i < 8;i++)
{
- if (!(cl.items & (1 << i)))
+ if (!(cl.stats[STAT_ITEMS] & (1 << i)))
continue;
Sbar_DrawWeapon(i + 1, fade, ((1<<i) == cl.stats[STAT_ACTIVEWEAPON]));
}
- if((cl.items & (1<<12)))
+ if((cl.stats[STAT_ITEMS] & (1<<12)))
Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == (1<<12)));
}
Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
// special items
- if (cl.items & IT_INVULNERABILITY)
+ if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
{
Sbar_DrawNum (36, 0, 666, 3, 1);
Sbar_DrawPic (0, 0, sb_disc);
// AK dont draw ammo for the laser
if(cl.stats[STAT_ACTIVEWEAPON] != 12)
{
- if (cl.items & NEX_IT_SHELLS)
+ if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
Sbar_DrawPic (519, 0, sb_ammo[0]);
- else if (cl.items & NEX_IT_BULLETS)
+ else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
Sbar_DrawPic (519, 0, sb_ammo[1]);
- else if (cl.items & NEX_IT_ROCKETS)
+ else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
Sbar_DrawPic (519, 0, sb_ammo[2]);
- else if (cl.items & NEX_IT_CELLS)
+ else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
Sbar_DrawPic (519, 0, sb_ammo[3]);
if(cl.stats[STAT_AMMO] <= 10)
//MED 01/04/97 moved keys here so they would not be overwritten
if (gamemode == GAME_HIPNOTIC)
{
- if (cl.items & IT_KEY1)
+ if (cl.stats[STAT_ITEMS] & IT_KEY1)
Sbar_DrawPic (209, 3, sb_items[0]);
- if (cl.items & IT_KEY2)
+ if (cl.stats[STAT_ITEMS] & IT_KEY2)
Sbar_DrawPic (209, 12, sb_items[1]);
}
// armor
if (gamemode != GAME_GOODVSBAD2)
{
- if (cl.items & IT_INVULNERABILITY)
+ if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
{
Sbar_DrawNum (24, 0, 666, 3, 1);
Sbar_DrawPic (0, 0, sb_disc);
if (gamemode == GAME_ROGUE)
{
Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
- if (cl.items & RIT_ARMOR3)
+ if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
Sbar_DrawPic (0, 0, sb_armor[2]);
- else if (cl.items & RIT_ARMOR2)
+ else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
Sbar_DrawPic (0, 0, sb_armor[1]);
- else if (cl.items & RIT_ARMOR1)
+ else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
Sbar_DrawPic (0, 0, sb_armor[0]);
}
else
{
Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
- if (cl.items & IT_ARMOR3)
+ if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
Sbar_DrawPic (0, 0, sb_armor[2]);
- else if (cl.items & IT_ARMOR2)
+ else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
Sbar_DrawPic (0, 0, sb_armor[1]);
- else if (cl.items & IT_ARMOR1)
+ else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
Sbar_DrawPic (0, 0, sb_armor[0]);
}
}
// ammo icon
if (gamemode == GAME_ROGUE)
{
- if (cl.items & RIT_SHELLS)
+ if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
Sbar_DrawPic (224, 0, sb_ammo[0]);
- else if (cl.items & RIT_NAILS)
+ else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
Sbar_DrawPic (224, 0, sb_ammo[1]);
- else if (cl.items & RIT_ROCKETS)
+ else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
Sbar_DrawPic (224, 0, sb_ammo[2]);
- else if (cl.items & RIT_CELLS)
+ else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
Sbar_DrawPic (224, 0, sb_ammo[3]);
- else if (cl.items & RIT_LAVA_NAILS)
+ else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
Sbar_DrawPic (224, 0, rsb_ammo[0]);
- else if (cl.items & RIT_PLASMA_AMMO)
+ else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
Sbar_DrawPic (224, 0, rsb_ammo[1]);
- else if (cl.items & RIT_MULTI_ROCKETS)
+ else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
Sbar_DrawPic (224, 0, rsb_ammo[2]);
}
else
{
- if (cl.items & IT_SHELLS)
+ if (cl.stats[STAT_ITEMS] & IT_SHELLS)
Sbar_DrawPic (224, 0, sb_ammo[0]);
- else if (cl.items & IT_NAILS)
+ else if (cl.stats[STAT_ITEMS] & IT_NAILS)
Sbar_DrawPic (224, 0, sb_ammo[1]);
- else if (cl.items & IT_ROCKETS)
+ else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
Sbar_DrawPic (224, 0, sb_ammo[2]);
- else if (cl.items & IT_CELLS)
+ else if (cl.stats[STAT_ITEMS] & IT_CELLS)
Sbar_DrawPic (224, 0, sb_ammo[3]);
}
Sbar_ShowFPS();
R_Draw2DCrosshair();
+
+ if (cl_prydoncursor.integer)
+ DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid.conwidth, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid.conheight, va("gfx/prydoncursor%03i.lmp", cl_prydoncursor.integer), 0, 0, 1, 1, 1, 1, 0);
}
//=============================================================================
char modelname[64];
struct model_s *worldmodel;
// NULL terminated
- char *model_precache[MAX_MODELS];
+ // LordHavoc: precaches are now MAX_QPATH rather than a pointer
+ // updated by SV_ModelIndex
+ char model_precache[MAX_MODELS][MAX_QPATH];
struct model_s *models[MAX_MODELS];
// NULL terminated
- char *sound_precache[MAX_SOUNDS];
+ // LordHavoc: precaches are now MAX_QPATH rather than a pointer
+ // updated by SV_SoundIndex
+ char sound_precache[MAX_SOUNDS][MAX_QPATH];
char *lightstyles[MAX_LIGHTSTYLES];
int num_edicts;
int max_edicts;
// prevent animated names
float nametime;
+ // latest received clc_ackframe (used to detect packet loss)
+ int latestframenum;
+
entityframe_database_t *entitydatabase;
entityframe4_database_t *entitydatabase4;
entityframe5_database_t *entitydatabase5;
extern cvar_t sv_gameplayfix_stepdown;
extern cvar_t sv_gameplayfix_stepwhilejumping;
extern cvar_t sv_gameplayfix_swiminbmodels;
+extern cvar_t sv_gameplayfix_setmodelrealbox;
extern mempool_t *sv_clients_mempool;
extern mempool_t *sv_edicts_mempool;
void SV_ReadClientMessage(void);
-int SV_ModelIndex (const char *name);
+// precachemode values:
+// 0 = fail if not precached,
+// 1 = warn if not found and precache if possible
+// 2 = precache
+int SV_ModelIndex(char *s, int precachemode);
+int SV_SoundIndex(char *s, int precachemode);
void SV_SetIdealPitch (void);
qboolean SV_CheckBottom (edict_t *ent);
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);
-void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg);
+void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg, int *stats);
void SV_MoveToGoal (void);
#include "quakedef.h"
// select which protocol to host, by name
-// this is named the same as PROTOCOL_DARKPLACES5 for example, minus the PROTOCOL_ prefix
-cvar_t sv_protocolname = {0, "sv_protocolname", "DARKPLACES5"};
+// this is named the same as PROTOCOL_DARKPLACES6 for example, minus the PROTOCOL_ prefix
+cvar_t sv_protocolname = {0, "sv_protocolname", "DARKPLACES6"};
cvar_t sv_ratelimitlocalplayer = {0, "sv_ratelimitlocalplayer", "0"};
cvar_t sv_maxrate = {CVAR_SAVE | CVAR_NOTIFY, "sv_maxrate", "10000"};
cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "1"};
cvar_t sv_gameplayfix_stepwhilejumping = {0, "sv_gameplayfix_stepwhilejumping", "1"};
cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1"};
+cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1"};
server_t sv;
server_static_t svs;
-static char localmodels[MAX_MODELS][5]; // inline model names for precache
-
mempool_t *sv_edicts_mempool = NULL;
//============================================================================
*/
void SV_Init (void)
{
- int i;
-
Cmd_AddCommand("sv_saveentfile", SV_SaveEntFile_f);
Cvar_RegisterVariable (&sv_maxvelocity);
Cvar_RegisterVariable (&sv_gravity);
Cvar_RegisterVariable (&sv_gameplayfix_stepdown);
Cvar_RegisterVariable (&sv_gameplayfix_stepwhilejumping);
Cvar_RegisterVariable (&sv_gameplayfix_swiminbmodels);
+ Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
Cvar_RegisterVariable (&sv_protocolname);
Cvar_RegisterVariable (&sv_ratelimitlocalplayer);
Cvar_RegisterVariable (&sv_maxrate);
SV_Phys_Init();
SV_World_Init();
- for (i = 0;i < MAX_MODELS;i++)
- sprintf (localmodels[i], "*%i", i);
-
sv_edicts_mempool = Mem_AllocPool("server edicts", 0, NULL);
}
FS_WriteFile(va("%s.ent", basename), sv.worldmodel->brush.entities, strlen(sv.worldmodel->brush.entities));
}
+
/*
=============================================================================
return;
// find precache number for sound
- for (sound_num=1 ; sound_num<MAX_SOUNDS && sv.sound_precache[sound_num] ; sound_num++)
- if (!strcmp(sample, sv.sound_precache[sound_num]))
- break;
-
- if ( sound_num == MAX_SOUNDS || !sv.sound_precache[sound_num] )
- {
- Con_Printf("SV_StartSound: %s not precached\n", sample);
+ sound_num = SV_SoundIndex(sample, 1);
+ if (!sound_num)
return;
- }
ent = NUM_FOR_EDICT(entity);
*/
void SV_SendServerinfo (client_t *client)
{
- char **s;
- char message[128];
+ int i;
+ char message[128];
// edicts get reallocated on level changes, so we need to update it here
client->edict = EDICT_NUM((client - svs.clients) + 1);
// client info that normally requires networking
if (!client->netconnection)
{
- int i;
-
// set up the edict
ED_ClearEdict(client->edict);
}
// LordHavoc: clear entityframe tracking
+ client->latestframenum = 0;
if (client->entitydatabase)
EntityFrame_FreeDatabase(client->entitydatabase);
client->entitydatabase = EntityFrame_AllocDatabase(sv_clients_mempool);
if (sv.protocol == PROTOCOL_DARKPLACES4)
client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool);
- if (sv.protocol == PROTOCOL_DARKPLACES5)
+ if (sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
client->entitydatabase5 = EntityFrame5_AllocDatabase(sv_clients_mempool);
MSG_WriteByte (&client->message, svc_print);
MSG_WriteString (&client->message,PR_GetString(sv.edicts->v->message));
- for (s = sv.model_precache+1 ; *s ; s++)
- MSG_WriteString (&client->message, *s);
+ for (i = 1;i < MAX_MODELS && sv.model_precache[i][0];i++)
+ MSG_WriteString (&client->message, sv.model_precache[i]);
MSG_WriteByte (&client->message, 0);
- for (s = sv.sound_precache+1 ; *s ; s++)
- MSG_WriteString (&client->message, *s);
+ for (i = 1;i < MAX_SOUNDS && sv.sound_precache[i][0];i++)
+ MSG_WriteString (&client->message, sv.sound_precache[i]);
MSG_WriteByte (&client->message, 0);
// send music
if (sententities[s->tagentity] != sententitiesmark)
return;
}
+ // skip invalid modelindexes to avoid crashes
+ else if (s->modelindex >= MAX_MODELS)
+ return;
// always send world submodels, they don't generate much traffic
// except in PROTOCOL_QUAKE where they hog bandwidth like crazy
- else if ((!(isbmodel = (model = sv.models[s->modelindex]) != NULL && model->name[0] == '*') && !(s->effects & EF_NODEPTHTEST)) || sv.protocol == PROTOCOL_QUAKE)
+ else if (!(s->effects & EF_NODEPTHTEST) && (sv.protocol == PROTOCOL_QUAKE || !(isbmodel = (model = sv.models[s->modelindex]) != NULL && model->name[0] == '*')))
{
Mod_CheckLoaded(model);
// entity has survived every check so far, check if visible
entity_state_t sendstates[MAX_EDICTS];
-void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg)
+void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg, int *stats)
{
int i, numsendstates;
entity_state_t *s;
Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv_writeentitiestoclient_totalentities, sv_writeentitiestoclient_visibleentities, sv_writeentitiestoclient_culled_pvs + sv_writeentitiestoclient_culled_trace, sv_writeentitiestoclient_culled_pvs, sv_writeentitiestoclient_culled_trace);
if (client->entitydatabase5)
- EntityFrame5_WriteFrame(msg, client->entitydatabase5, numsendstates, sendstates, client - svs.clients + 1);
+ EntityFrame5_WriteFrame(msg, client->entitydatabase5, numsendstates, sendstates, client - svs.clients + 1, stats);
else if (client->entitydatabase4)
EntityFrame4_WriteFrame(msg, client->entitydatabase4, numsendstates, sendstates);
else if (client->entitydatabase)
==================
*/
-void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
+void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg, int *stats)
{
int bits;
int i;
eval_t *val;
vec3_t punchvector;
qbyte viewzoom;
+ int weaponmodelindex;
//
// send a damage message
ent->v->fixangle = 0;
}
- bits = 0;
-
- if (ent->v->view_ofs[2] != DEFAULT_VIEWHEIGHT)
- bits |= SU_VIEWHEIGHT;
-
- if (ent->v->idealpitch)
- bits |= SU_IDEALPITCH;
-
-// stuff the sigil bits into the high bits of items for sbar, or else
-// mix in items2
+ // stuff the sigil bits into the high bits of items for sbar, or else
+ // mix in items2
val = GETEDICTFIELDVALUE(ent, eval_items2);
-
if (val)
items = (int)ent->v->items | ((int)val->_float << 23);
else
items = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
- bits |= SU_ITEMS;
-
- if ( (int)ent->v->flags & FL_ONGROUND)
- bits |= SU_ONGROUND;
-
- if ( ent->v->waterlevel >= 2)
- bits |= SU_INWATER;
-
- // PROTOCOL_DARKPLACES
VectorClear(punchvector);
if ((val = GETEDICTFIELDVALUE(ent, eval_punchvector)))
VectorCopy(val->vector, punchvector);
- i = 255;
- if ((val = GETEDICTFIELDVALUE(ent, eval_viewzoom)))
+ weaponmodelindex = SV_ModelIndex(PR_GetString(ent->v->weaponmodel), 1);
+ if (!weaponmodelindex)
{
- i = val->_float * 255.0f;
- if (i == 0)
- i = 255;
- else
- i = bound(0, i, 65535);
+ Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
+ weaponmodelindex = 0;
}
- viewzoom = i;
- // FIXME: which protocols support this? does PROTOCOL_DARKPLACES3 support viewzoom?
- if (sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
- if (viewzoom != 255)
- bits |= SU_VIEWZOOM;
+ viewzoom = 255;
+ if ((val = GETEDICTFIELDVALUE(ent, eval_viewzoom)))
+ viewzoom = val->_float * 255.0f;
+ if (viewzoom == 0)
+ viewzoom = 255;
+
+ bits = 0;
+
+ if ((int)ent->v->flags & FL_ONGROUND)
+ bits |= SU_ONGROUND;
+ if (ent->v->waterlevel >= 2)
+ bits |= SU_INWATER;
+ if (ent->v->idealpitch)
+ bits |= SU_IDEALPITCH;
for (i=0 ; i<3 ; i++)
{
if (ent->v->punchangle[i])
bits |= (SU_PUNCH1<<i);
- if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
if (punchvector[i])
bits |= (SU_PUNCHVEC1<<i);
if (ent->v->velocity[i])
bits |= (SU_VELOCITY1<<i);
}
- if (ent->v->weaponframe)
- bits |= SU_WEAPONFRAME;
-
- if (ent->v->armorvalue)
- bits |= SU_ARMOR;
-
- bits |= SU_WEAPON;
+ memset(stats, 0, sizeof(int[MAX_CL_STATS]));
+ stats[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
+ stats[STAT_ITEMS] = items;
+ stats[STAT_WEAPONFRAME] = ent->v->weaponframe;
+ stats[STAT_ARMOR] = ent->v->armorvalue;
+ stats[STAT_WEAPON] = weaponmodelindex;
+ stats[STAT_HEALTH] = ent->v->health;
+ stats[STAT_AMMO] = ent->v->currentammo;
+ stats[STAT_SHELLS] = ent->v->ammo_shells;
+ stats[STAT_NAILS] = ent->v->ammo_nails;
+ stats[STAT_ROCKETS] = ent->v->ammo_rockets;
+ stats[STAT_CELLS] = ent->v->ammo_cells;
+ stats[STAT_ACTIVEWEAPON] = ent->v->weapon;
+ stats[STAT_VIEWZOOM] = viewzoom;
+ // the QC bumps these itself by sending svc_'s, so we have to keep them
+ // zero or they'll be corrected by the engine
+ //stats[STAT_TOTALSECRETS] = pr_global_struct->total_secrets;
+ //stats[STAT_TOTALMONSTERS] = pr_global_struct->total_monsters;
+ //stats[STAT_SECRETS] = pr_global_struct->found_secrets;
+ //stats[STAT_MONSTERS] = pr_global_struct->killed_monsters;
+
+ if (sv.protocol != PROTOCOL_DARKPLACES6)
+ {
+ if (stats[STAT_VIEWHEIGHT] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT;
+ bits |= SU_ITEMS;
+ if (stats[STAT_WEAPONFRAME]) bits |= SU_WEAPONFRAME;
+ if (stats[STAT_ARMOR]) bits |= SU_ARMOR;
+ bits |= SU_WEAPON;
+ // FIXME: which protocols support this? does PROTOCOL_DARKPLACES3 support viewzoom?
+ if (sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ if (viewzoom != 255)
+ bits |= SU_VIEWZOOM;
+ }
if (bits >= 65536)
bits |= SU_EXTEND1;
if (bits >= 16777216)
bits |= SU_EXTEND2;
-// send the data
-
+ // send the data
MSG_WriteByte (msg, svc_clientdata);
MSG_WriteShort (msg, bits);
if (bits & SU_EXTEND1)
MSG_WriteByte(msg, bits >> 24);
if (bits & SU_VIEWHEIGHT)
- MSG_WriteChar (msg, ent->v->view_ofs[2]);
+ MSG_WriteChar (msg, stats[STAT_VIEWHEIGHT]);
if (bits & SU_IDEALPITCH)
MSG_WriteChar (msg, ent->v->idealpitch);
{
if (sv.protocol == PROTOCOL_QUAKE)
MSG_WriteChar(msg, ent->v->punchangle[i]);
- else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
MSG_WriteAngle16i(msg, ent->v->punchangle[i]);
}
- if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
{
if (bits & (SU_PUNCHVEC1<<i))
{
if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
MSG_WriteCoord16i(msg, punchvector[i]);
- else if (sv.protocol == PROTOCOL_DARKPLACES5)
+ else if (sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
MSG_WriteCoord32f(msg, punchvector[i]);
}
}
{
if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
MSG_WriteChar(msg, ent->v->velocity[i] * (1.0f / 16.0f));
- else if (sv.protocol == PROTOCOL_DARKPLACES5)
+ else if (sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
MSG_WriteCoord32f(msg, ent->v->velocity[i]);
}
}
-// [always sent] if (bits & SU_ITEMS)
- MSG_WriteLong (msg, items);
+ if (bits & SU_ITEMS)
+ MSG_WriteLong (msg, stats[STAT_ITEMS]);
if (sv.protocol == PROTOCOL_DARKPLACES5)
{
if (bits & SU_WEAPONFRAME)
- MSG_WriteShort (msg, ent->v->weaponframe);
+ MSG_WriteShort (msg, stats[STAT_WEAPONFRAME]);
if (bits & SU_ARMOR)
- MSG_WriteShort (msg, ent->v->armorvalue);
+ MSG_WriteShort (msg, stats[STAT_ARMOR]);
if (bits & SU_WEAPON)
- {
- i = SV_ModelIndex(PR_GetString(ent->v->weaponmodel));
- if (i < 0)
- {
- Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
- i = 0;
- }
- MSG_WriteShort (msg, i);
- }
-
- MSG_WriteShort (msg, ent->v->health);
- MSG_WriteShort (msg, ent->v->currentammo);
- MSG_WriteShort (msg, ent->v->ammo_shells);
- MSG_WriteShort (msg, ent->v->ammo_nails);
- MSG_WriteShort (msg, ent->v->ammo_rockets);
- MSG_WriteShort (msg, ent->v->ammo_cells);
-
- MSG_WriteShort (msg, ent->v->weapon);
-
+ MSG_WriteShort (msg, stats[STAT_WEAPON]);
+ MSG_WriteShort (msg, stats[STAT_HEALTH]);
+ MSG_WriteShort (msg, stats[STAT_AMMO]);
+ MSG_WriteShort (msg, stats[STAT_SHELLS]);
+ MSG_WriteShort (msg, stats[STAT_NAILS]);
+ MSG_WriteShort (msg, stats[STAT_ROCKETS]);
+ MSG_WriteShort (msg, stats[STAT_CELLS]);
+ MSG_WriteShort (msg, stats[STAT_ACTIVEWEAPON]);
if (bits & SU_VIEWZOOM)
- MSG_WriteShort (msg, viewzoom);
+ MSG_WriteShort (msg, min(stats[STAT_VIEWZOOM], 65535));
}
- else
+ else if (sv.protocol != PROTOCOL_DARKPLACES6)
{
if (bits & SU_WEAPONFRAME)
- MSG_WriteByte (msg, ent->v->weaponframe);
+ MSG_WriteByte (msg, stats[STAT_WEAPONFRAME]);
if (bits & SU_ARMOR)
- MSG_WriteByte (msg, ent->v->armorvalue);
+ MSG_WriteByte (msg, stats[STAT_ARMOR]);
if (bits & SU_WEAPON)
- {
- i = SV_ModelIndex(PR_GetString(ent->v->weaponmodel));
- if (i < 0)
- {
- Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel));
- i = 0;
- }
- MSG_WriteByte (msg, i);
- }
-
- MSG_WriteShort (msg, ent->v->health);
- MSG_WriteByte (msg, ent->v->currentammo);
- MSG_WriteByte (msg, ent->v->ammo_shells);
- MSG_WriteByte (msg, ent->v->ammo_nails);
- MSG_WriteByte (msg, ent->v->ammo_rockets);
- MSG_WriteByte (msg, ent->v->ammo_cells);
-
+ MSG_WriteByte (msg, stats[STAT_WEAPON]);
+ MSG_WriteShort (msg, stats[STAT_HEALTH]);
+ MSG_WriteByte (msg, stats[STAT_AMMO]);
+ MSG_WriteByte (msg, stats[STAT_SHELLS]);
+ MSG_WriteByte (msg, stats[STAT_NAILS]);
+ MSG_WriteByte (msg, stats[STAT_ROCKETS]);
+ MSG_WriteByte (msg, stats[STAT_CELLS]);
if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE || gamemode == GAME_NEXUIZ)
{
- for(i=0;i<32;i++)
- {
- if ( ((int)ent->v->weapon) & (1<<i) )
- {
- MSG_WriteByte (msg, i);
+ for (i = 0;i < 32;i++)
+ if (stats[STAT_WEAPON] & (1<<i))
break;
- }
- }
+ MSG_WriteByte (msg, i);
}
else
- {
- MSG_WriteByte (msg, ent->v->weapon);
- }
-
+ MSG_WriteByte (msg, stats[STAT_WEAPON]);
if (bits & SU_VIEWZOOM)
{
if (sv.protocol == PROTOCOL_DARKPLACES4)
- {
- viewzoom = min(viewzoom, 255);
- MSG_WriteByte (msg, viewzoom);
- }
- else if (sv.protocol == PROTOCOL_DARKPLACES5)
- MSG_WriteShort (msg, viewzoom);
+ MSG_WriteByte (msg, min(stats[STAT_VIEWZOOM], 255));
+ else if (sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
+ MSG_WriteShort (msg, min(stats[STAT_VIEWZOOM], 65535));
}
}
}
{
int rate, maxrate, maxsize, maxsize2;
sizebuf_t msg;
+ int stats[MAX_CL_STATS];
if (LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP && !sv_ratelimitlocalplayer.integer)
{
maxsize = sizeof(sv_sendclientdatagram_buf);
maxsize2 = sizeof(sv_sendclientdatagram_buf);
}
- else if (sv.protocol == PROTOCOL_DARKPLACES5)
+ else if (sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
{
// PROTOCOL_DARKPLACES5 supports packet size limiting of updates
maxrate = bound(NET_MINRATE, sv_maxrate.integer, NET_MAXRATE);
MSG_WriteFloat (&msg, sv.time);
// add the client specific data to the datagram
- SV_WriteClientdataToMessage (client->edict, &msg);
-
- SV_WriteEntitiesToClient (client, client->edict, &msg);
+ SV_WriteClientdataToMessage (client, client->edict, &msg, stats);
+ SV_WriteEntitiesToClient (client, client->edict, &msg, stats);
// expand packet size to allow effects to go over the rate limit
// (dropping them is FAR too ugly)
================
*/
-int SV_ModelIndex (const char *name)
+int SV_ModelIndex(char *s, int precachemode)
{
- int i;
-
- if (!name || !name[0])
+ int i, limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_MODELS);
+ char filename[MAX_QPATH];
+ if (!s || !*s)
return 0;
-
- for (i=0 ; i<MAX_MODELS && sv.model_precache[i] ; i++)
- if (!strcmp(sv.model_precache[i], name))
+ // testing
+ //if (precachemode == 2)
+ // return 0;
+ strlcpy(filename, s, sizeof(filename));
+ for (i = 2;i < limit;i++)
+ {
+ if (!sv.model_precache[i][0])
+ {
+ if (precachemode)
+ {
+ if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ {
+ // not able to precache during game
+ if (precachemode == 2 && sv.state != ss_loading)
+ {
+ Con_Printf("SV_ModelIndex(\"%s\"): precache_model can only be done in spawn functions\n", filename);
+ return 0;
+ }
+ }
+ else
+ {
+ // able to precache during game
+ if (precachemode == 1)
+ Con_Printf("SV_ModelIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename);
+ strlcpy(sv.model_precache[i], filename, sizeof(sv.model_precache[i]));
+ sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, false);
+ if (sv.state != ss_loading)
+ {
+ MSG_WriteByte(&sv.reliable_datagram, svc_precache);
+ MSG_WriteShort(&sv.reliable_datagram, i);
+ MSG_WriteString(&sv.reliable_datagram, filename);
+ }
+ return i;
+ }
+ }
+ Con_Printf("SV_ModelIndex(\"%s\"): not precached\n", filename);
+ return 0;
+ }
+ if (!strcmp(sv.model_precache[i], filename))
return i;
- if (i==MAX_MODELS || !sv.model_precache[i])
+ }
+ if (precachemode)
+ Con_Printf("SV_ModelIndex(\"%s\"): i == MAX_MODELS\n", filename);
+ else
+ Con_Printf("SV_ModelIndex(\"%s\"): not precached\n", filename);
+ return 0;
+}
+
+/*
+================
+SV_SoundIndex
+
+================
+*/
+int SV_SoundIndex(char *s, int precachemode)
+{
+ int i, limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_SOUNDS);
+ char filename[MAX_QPATH];
+ if (!s || !*s)
+ return 0;
+ strlcpy(filename, s, sizeof(filename));
+ for (i = 1;i < limit;i++)
{
- Con_DPrintf ("SV_ModelIndex: model %s not precached", name);
- return -1;
+ if (!sv.sound_precache[i][0])
+ {
+ if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ {
+ // not able to precache during game
+ if (precachemode == 2 && sv.state != ss_loading)
+ {
+ Con_Printf("SV_SoundIndex(\"%s\"): precache_sound can only be done in spawn functions\n", filename);
+ return 0;
+ }
+ }
+ else
+ {
+ // able to precache during game
+ if (precachemode)
+ {
+ if (precachemode == 1)
+ Con_Printf("SV_SoundIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename);
+ strlcpy(sv.sound_precache[i], filename, sizeof(sv.sound_precache[i]));
+ MSG_WriteByte(&sv.reliable_datagram, svc_precache);
+ MSG_WriteShort(&sv.reliable_datagram, i + 32768);
+ MSG_WriteString(&sv.reliable_datagram, filename);
+ return i;
+ }
+ }
+ Con_Printf("SV_SoundIndex(\"%s\"): not precached\n", filename);
+ return 0;
+ }
+ if (!strcmp(sv.sound_precache[i], filename))
+ return i;
}
- return i;
+ if (precachemode)
+ Con_Printf("SV_SoundIndex(\"%s\"): i == MAX_SOUNDS\n", filename);
+ else
+ Con_Printf("SV_SoundIndex(\"%s\"): not precached\n", filename);
+ return 0;
}
/*
if (entnum > 0 && entnum <= svs.maxclients)
{
svent->e->baseline.colormap = entnum;
- i = SV_ModelIndex("progs/player.mdl");
- if (i < 0)
- i = 0;
- svent->e->baseline.modelindex = i;
+ svent->e->baseline.modelindex = SV_ModelIndex("progs/player.mdl", 1);
}
else
{
strlcpy (sv.name, server, sizeof (sv.name));
- // FIXME: cvar
+ sv.netquakecompatible = false;
if (!strcasecmp(sv_protocolname.string, "QUAKE"))
{
sv.protocol = PROTOCOL_QUAKE;
sv.netquakecompatible = true;
}
else if (!strcasecmp(sv_protocolname.string, "QUAKEDP"))
- {
sv.protocol = PROTOCOL_QUAKE;
- sv.netquakecompatible = false;
- }
else if (!strcasecmp(sv_protocolname.string, "DARKPLACES1"))
- {
sv.protocol = PROTOCOL_DARKPLACES1;
- sv.netquakecompatible = false;
- }
else if (!strcasecmp(sv_protocolname.string, "DARKPLACES2"))
- {
sv.protocol = PROTOCOL_DARKPLACES2;
- sv.netquakecompatible = false;
- }
else if (!strcasecmp(sv_protocolname.string, "DARKPLACES3"))
- {
sv.protocol = PROTOCOL_DARKPLACES3;
- sv.netquakecompatible = false;
- }
else if (!strcasecmp(sv_protocolname.string, "DARKPLACES4"))
- {
sv.protocol = PROTOCOL_DARKPLACES4;
- sv.netquakecompatible = false;
- }
else if (!strcasecmp(sv_protocolname.string, "DARKPLACES5"))
- {
sv.protocol = PROTOCOL_DARKPLACES5;
- sv.netquakecompatible = false;
- }
+ else if (!strcasecmp(sv_protocolname.string, "DARKPLACES6"))
+ sv.protocol = PROTOCOL_DARKPLACES6;
else
{
- sv.protocol = PROTOCOL_DARKPLACES5;
- sv.netquakecompatible = false;
- Con_Printf("Unknown sv_protocolname \"%s\", valid values are QUAKE, QUAKEDP, DARKPLACES1, DARKPLACES2, DARKPLACES3, DARKPLACES4, DARKPLACES5, falling back to DARKPLACES5 protocol\n", sv_protocolname.string);
+ sv.protocol = PROTOCOL_DARKPLACES6;
+ Con_Printf("Unknown sv_protocolname \"%s\", valid values are QUAKE, QUAKEDP, DARKPLACES1, DARKPLACES2, DARKPLACES3, DARKPLACES4, DARKPLACES5, DARKPLACES6, falling back to DARKPLACES6 protocol\n", sv_protocolname.string);
}
// load progs to get entity field count
//
SV_ClearWorld ();
- sv.sound_precache[0] = "";
+ strlcpy(sv.sound_precache[0], "", sizeof(sv.sound_precache[0]));
- sv.model_precache[0] = "";
- sv.model_precache[1] = sv.modelname;
+ strlcpy(sv.model_precache[0], "", sizeof(sv.model_precache[0]));
+ strlcpy(sv.model_precache[1], sv.modelname, sizeof(sv.model_precache[1]));
for (i = 1;i < sv.worldmodel->brush.numsubmodels;i++)
{
- sv.model_precache[i+1] = localmodels[i];
- sv.models[i+1] = Mod_ForName (localmodels[i], false, false, false);
+ snprintf(sv.model_precache[i+1], sizeof(sv.model_precache[i+1]), "*%i", i);
+ sv.models[i+1] = Mod_ForName (sv.model_precache[i+1], false, false, false);
}
//
angle[i] = MSG_ReadAngle8i();
else if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3)
angle[i] = MSG_ReadAngle32f();
- else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
+ else if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6)
angle[i] = MSG_ReadAngle16i();
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
}
}
// read buttons
- bits = MSG_ReadByte ();
+ if (sv.protocol == PROTOCOL_DARKPLACES6)
+ bits = MSG_ReadLong ();
+ else
+ bits = MSG_ReadByte ();
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
host_client->edict->v->button0 = bits & 1;
host_client->edict->v->button2 = (bits & 2)>>1;
if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((bits >> 5) & 1);
if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((bits >> 6) & 1);
if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((bits >> 7) & 1);
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonuse))) val->_float = ((bits >> 8) & 1);
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonchat))) val->_float = ((bits >> 9) & 1);
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_active))) val->_float = ((bits >> 10) & 1);
i = MSG_ReadByte ();
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
if (i)
host_client->edict->v->impulse = i;
+
+ // PRYDON_CLIENTCURSOR
+ if (sv.protocol == PROTOCOL_DARKPLACES6)
+ {
+ // 30 bytes
+ move->cursor_screen[0] = MSG_ReadShort() * (1.0f / 32767.0f);
+ move->cursor_screen[1] = MSG_ReadShort() * (1.0f / 32767.0f);
+ move->cursor_start[0] = MSG_ReadFloat();
+ move->cursor_start[1] = MSG_ReadFloat();
+ move->cursor_start[2] = MSG_ReadFloat();
+ move->cursor_impact[0] = MSG_ReadFloat();
+ move->cursor_impact[1] = MSG_ReadFloat();
+ move->cursor_impact[2] = MSG_ReadFloat();
+ move->cursor_entitynumber = MSG_ReadShort();
+ if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
+ }
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_screen))) VectorCopy(move->cursor_screen, val->vector);
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_start))) VectorCopy(move->cursor_start, val->vector);
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_ent))) val->edict = EDICT_TO_PROG(EDICT_NUM(move->cursor_entitynumber));
+}
+
+void SV_FrameLost(int framenum)
+{
+ if (host_client->entitydatabase5)
+ EntityFrame5_LostFrame(host_client->entitydatabase5, framenum, host_client - svs.clients + 1);
+}
+
+void SV_FrameAck(int framenum)
+{
+ if (host_client->entitydatabase)
+ EntityFrame_AckFrame(host_client->entitydatabase, framenum);
+ else if (host_client->entitydatabase4)
+ EntityFrame4_AckFrame(host_client->entitydatabase4, framenum, true);
+ else if (host_client->entitydatabase5)
+ EntityFrame5_AckFrame(host_client->entitydatabase5, framenum);
}
/*
SV_ReadClientMove (&host_client->cmd);
break;
- case clc_ackentities:
+ case clc_ackframe:
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
num = MSG_ReadLong();
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
if (developer_networkentities.integer >= 1)
- Con_Printf("recv clc_ackentities %i\n", num);
- if (host_client->entitydatabase)
- EntityFrame_AckFrame(host_client->entitydatabase, num);
- else if (host_client->entitydatabase4)
- EntityFrame4_AckFrame(host_client->entitydatabase4, num, true);
- else if (host_client->entitydatabase5)
- EntityFrame5_AckFrame(host_client->entitydatabase5, num, host_client - svs.clients + 1);
+ Con_Printf("recv clc_ackframe %i\n", num);
+ if (host_client->latestframenum < num)
+ {
+ int i;
+ for (i = host_client->latestframenum + 1;i < num;i++)
+ SV_FrameLost(i);
+ SV_FrameAck(num);
+ host_client->latestframenum = num;
+ }
break;
}
}
{
}
-void IN_Move (usercmd_t *cmd)
+void IN_Move (void)
{
if (mouse_avail)
- IN_Mouse(cmd, mouse_x, mouse_y);
+ IN_Mouse(mouse_x, mouse_y);
mouse_x = 0;
mouse_y = 0;
}
{
}
-void IN_Move(usercmd_t *cmd)
+void IN_Move(void)
{
}
{
}
-static void IN_MouseMove (usercmd_t *cmd)
+static void IN_MouseMove (void)
{
int x, y;
if( !vid_usingmouse ) {
- IN_Mouse( cmd, 0, 0 );
+ IN_Mouse( 0, 0 );
return;
}
SDL_GetRelativeMouseState( &x, &y );
- IN_Mouse( cmd, x, y );
+ IN_Mouse( x, y );
}
-void IN_Move( usercmd_t *cmd )
+void IN_Move( void )
{
- IN_MouseMove( cmd );
+ IN_MouseMove();
}
static void IN_Init( void )
IN_DoMove
===========
*/
-void IN_ProcessMove(usercmd_t *cmd)
+void IN_ProcessMove(void)
{
// get basic movement from keyboard
- CL_BaseMove(cmd);
+ CL_BaseMove();
// OS independent code
IN_PreMove();
// allow mice or other external controllers to add to the move
- IN_Move(cmd);
+ IN_Move();
// OS independent code
IN_PostMove();
}
-void IN_Mouse(usercmd_t *cmd, float mx, float my)
+void IN_Mouse(float mx, float my)
{
int mouselook = (in_mlook.state & 1) || freelook.integer;
float mouse_x, mouse_y;
if(!in_client_mouse)
return;
+ if (cl_prydoncursor.integer)
+ {
+ cl.cmd.cursor_screen[0] += mouse_x / vid.realwidth;
+ cl.cmd.cursor_screen[1] += mouse_y / vid.realheight;
+ V_StopPitchDrift();
+ return;
+ }
+
// LordHavoc: viewzoom affects mouse sensitivity for sniping
mouse_x *= sensitivity.value * cl.viewzoom;
mouse_y *= sensitivity.value * cl.viewzoom;
// Add mouse X/Y movement to cmd
if ((in_strafe.state & 1) || (lookstrafe.integer && mouselook))
- cmd->sidemove += m_side.value * mouse_x;
+ cl.cmd.sidemove += m_side.value * mouse_x;
else
cl.viewangles[YAW] -= m_yaw.value * mouse_x;
else
{
if ((in_strafe.state & 1) && noclip_anglehack)
- cmd->upmove -= m_forward.value * mouse_y;
+ cl.cmd.upmove -= m_forward.value * mouse_y;
else
- cmd->forwardmove -= m_forward.value * mouse_y;
+ cl.cmd.forwardmove -= m_forward.value * mouse_y;
}
}
// forward-referenced functions
void IN_StartupJoystick (void);
void Joy_AdvancedUpdate_f (void);
-void IN_JoyMove (usercmd_t *cmd);
+void IN_JoyMove (void);
void IN_StartupMouse (void);
/*
IN_MouseMove
===========
*/
-void IN_MouseMove (usercmd_t *cmd)
+void IN_MouseMove (void)
{
int i, mx, my;
DIDEVICEOBJECTDATA od;
{
GetCursorPos (¤t_pos);
//ui_mouseupdate(current_pos.x - window_x, current_pos.y - window_y);
- IN_Mouse( cmd, 0, 0 );
+ IN_Mouse( 0, 0 );
return;
}
my = current_pos.y - window_center_y;
}
- IN_Mouse(cmd, mx, my);
+ IN_Mouse(mx, my);
// if the mouse has moved, force it to the center, so there's room to move
if (!dinput && (mx || my))
IN_Move
===========
*/
-void IN_Move (usercmd_t *cmd)
+void IN_Move (void)
{
if (vid_activewindow && !vid_hidden)
{
- IN_MouseMove (cmd);
- IN_JoyMove (cmd);
+ IN_MouseMove ();
+ IN_JoyMove ();
}
}
IN_JoyMove
===========
*/
-void IN_JoyMove (usercmd_t *cmd)
+void IN_JoyMove (void)
{
float speed, aspeed;
float fAxisValue, fTemp;
// user wants forward control to be forward control
if (fabs(fAxisValue) > joy_forwardthreshold.value)
{
- cmd->forwardmove += (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value;
+ cl.cmd.forwardmove += (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value;
}
}
break;
case AxisSide:
if (fabs(fAxisValue) > joy_sidethreshold.value)
{
- cmd->sidemove += (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
+ cl.cmd.sidemove += (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
}
break;
// user wants turn control to become side control
if (fabs(fAxisValue) > joy_sidethreshold.value)
{
- cmd->sidemove -= (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
+ cl.cmd.sidemove -= (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
}
}
else
}
// origin
VectorAdd(vieworg, cl.punchvector, vieworg);
- vieworg[2] += cl.viewheight;
+ vieworg[2] += cl.stats[STAT_VIEWHEIGHT];
if (cl.stats[STAT_HEALTH] > 0 && cl_bob.value && cl_bobcycle.value)
{
double bob, cycle;
if (gamemode != GAME_TRANSFUSION)
{
- if (cl.items & IT_QUAD)
+ if (cl.stats[STAT_ITEMS] & IT_QUAD)
{
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0;
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0;
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255;
cl.cshifts[CSHIFT_POWERUP].percent = 30;
}
- else if (cl.items & IT_SUIT)
+ else if (cl.stats[STAT_ITEMS] & IT_SUIT)
{
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0;
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
cl.cshifts[CSHIFT_POWERUP].percent = 20;
}
- else if (cl.items & IT_INVISIBILITY)
+ else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
{
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100;
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100;
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100;
cl.cshifts[CSHIFT_POWERUP].percent = 100;
}
- else if (cl.items & IT_INVULNERABILITY)
+ else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
{
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;