mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-19 07:20:50 +00:00
[nq,qw] Clean up cl_view's use of the client struct
This is a huge step towards merging cl_view.
This commit is contained in:
parent
f04459f03f
commit
aac9069d9f
16 changed files with 452 additions and 452 deletions
|
@ -57,8 +57,11 @@ typedef struct movestate_s {
|
|||
|
||||
#define freelook (in_mlook.state & 1 || in_freelook->int_val)
|
||||
|
||||
struct viewstate_s;
|
||||
|
||||
void CL_OnFocusChange (void (*func) (int game));
|
||||
void CL_Input_BuildMove (float frametime, movestate_t *state);
|
||||
void CL_Input_BuildMove (float frametime, movestate_t *state,
|
||||
struct viewstate_s *vs);
|
||||
void CL_Input_Init (struct cbuf_s *cbuf);
|
||||
void CL_Input_Init_Cvars (void);
|
||||
void CL_Input_Activate (int in_game);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define __client_view_h_
|
||||
|
||||
#include "QF/mathlib.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
#define INFO_CSHIFT_BONUS (1 << 0)
|
||||
|
@ -41,12 +42,38 @@ typedef struct viewstate_s {
|
|||
vec4f_t movecmd;
|
||||
vec4f_t velocity;
|
||||
vec4f_t origin;
|
||||
vec4f_t punchangle;
|
||||
vec3_t angles;
|
||||
float frametime;
|
||||
double time;
|
||||
float height;
|
||||
int weaponframe;
|
||||
int onground; // -1 when in air
|
||||
int active:1;
|
||||
int drift_enabled:1;
|
||||
int voffs_enabled:1;
|
||||
int bob_enabled:1;
|
||||
int intermission:1;
|
||||
int force_cshifts; // bitfield of server enforced cshifts
|
||||
uint32_t flags;
|
||||
float frametime;
|
||||
vec4f_t punchangle;
|
||||
|
||||
int powerup_index;
|
||||
cshift_t cshifts[NUM_CSHIFTS]; // Color shifts for damage, powerups
|
||||
cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types
|
||||
|
||||
// pitch drifting vars
|
||||
float idealpitch;
|
||||
float pitchvel;
|
||||
qboolean nodrift;
|
||||
float driftmove;
|
||||
double laststop;
|
||||
|
||||
struct model_s *weapon_model;
|
||||
struct entity_s *weapon_entity;
|
||||
struct entity_s *player_entity;
|
||||
|
||||
struct chasestate_s *chasestate;
|
||||
int chase;
|
||||
} viewstate_t;
|
||||
|
||||
#define VF_DEAD 1
|
||||
|
@ -54,11 +81,11 @@ typedef struct viewstate_s {
|
|||
|
||||
void V_Init (void);
|
||||
void V_Init_Cvars (void);
|
||||
void V_RenderView (void);
|
||||
void V_RenderView (viewstate_t *vs);
|
||||
float V_CalcRoll (const vec3_t angles, vec4f_t velocity);
|
||||
void V_StartPitchDrift (void);
|
||||
void V_StopPitchDrift (void);
|
||||
void V_StartPitchDrift (viewstate_t *vs);
|
||||
void V_StopPitchDrift (viewstate_t *vs);
|
||||
|
||||
void V_SetContentsColor (int contents);
|
||||
void V_SetContentsColor (viewstate_t *vs, int contents);
|
||||
|
||||
#endif // __client_view_h_
|
||||
|
|
|
@ -213,7 +213,7 @@ cvar_t *m_forward;
|
|||
cvar_t *m_side;
|
||||
|
||||
static void
|
||||
CL_AdjustAngles (float frametime, movestate_t *ms)
|
||||
CL_AdjustAngles (float frametime, movestate_t *ms, viewstate_t *vs)
|
||||
{
|
||||
float down, up;
|
||||
float pitchspeed, yawspeed;
|
||||
|
@ -235,7 +235,7 @@ CL_AdjustAngles (float frametime, movestate_t *ms)
|
|||
delta[YAW] += yawspeed * IN_ButtonState (&in_left);
|
||||
}
|
||||
if (in_klook.state & inb_down) {
|
||||
V_StopPitchDrift ();
|
||||
V_StopPitchDrift (vs);
|
||||
delta[PITCH] -= pitchspeed * IN_ButtonState (&in_forward);
|
||||
delta[PITCH] += pitchspeed * IN_ButtonState (&in_back);
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ CL_AdjustAngles (float frametime, movestate_t *ms)
|
|||
ms->angles += delta;
|
||||
|
||||
if (delta[PITCH]) {
|
||||
V_StopPitchDrift ();
|
||||
V_StopPitchDrift (vs);
|
||||
ms->angles[PITCH] = bound (-70, ms->angles[PITCH], 80);
|
||||
}
|
||||
if (delta[ROLL]) {
|
||||
|
@ -340,13 +340,13 @@ CL_Legacy_Init (void)
|
|||
}
|
||||
|
||||
void
|
||||
CL_Input_BuildMove (float frametime, movestate_t *state)
|
||||
CL_Input_BuildMove (float frametime, movestate_t *state, viewstate_t *vs)
|
||||
{
|
||||
if (IN_ButtonReleased (&in_mlook) && !freelook && lookspring->int_val) {
|
||||
V_StartPitchDrift ();
|
||||
V_StartPitchDrift (vs);
|
||||
}
|
||||
|
||||
CL_AdjustAngles (frametime, state);
|
||||
CL_AdjustAngles (frametime, state, vs);
|
||||
|
||||
vec4f_t move = {};
|
||||
|
||||
|
@ -376,7 +376,7 @@ CL_Input_BuildMove (float frametime, movestate_t *state)
|
|||
move[UP] -= IN_UpdateAxis (&viewdelta_position_up);
|
||||
|
||||
if (freelook)
|
||||
V_StopPitchDrift ();
|
||||
V_StopPitchDrift (vs);
|
||||
|
||||
//if (cl.chase
|
||||
// && (chase_active->int_val == 2 || chase_active->int_val == 3)) {
|
||||
|
|
|
@ -148,9 +148,6 @@ typedef struct client_state_s {
|
|||
float item_gettime[32]; // cl.time of aquiring item, for blinking
|
||||
float faceanimtime; // Use anim frame if cl.time < this
|
||||
|
||||
cshift_t cshifts[NUM_CSHIFTS]; // Color shifts for damage, powerups
|
||||
cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types
|
||||
|
||||
// The client maintains its own idea of view angles, which are sent to the
|
||||
// server each frame. The server sets punchangle when the view is temporarily
|
||||
// offset, and an angle reset commands at the start of each level and after
|
||||
|
@ -164,15 +161,7 @@ typedef struct client_state_s {
|
|||
movestate_t movestate;
|
||||
chasestate_t chasestate;
|
||||
|
||||
// pitch drifting vars
|
||||
float idealpitch;
|
||||
float pitchvel;
|
||||
qboolean nodrift;
|
||||
float driftmove;
|
||||
double laststop;
|
||||
|
||||
qboolean paused; // Sent over by server
|
||||
float viewheight;
|
||||
float crouch; // Local amount for smoothing stepups
|
||||
qboolean inwater;
|
||||
|
||||
|
@ -208,7 +197,6 @@ typedef struct client_state_s {
|
|||
int gametype;
|
||||
int maxclients;
|
||||
// serverinfo mirrors
|
||||
int chase;
|
||||
int sv_cshifts;
|
||||
int no_pogo_stick;
|
||||
int teamplay;
|
||||
|
@ -312,9 +300,8 @@ void CL_NewTranslation (int slot, struct skin_s *skin);
|
|||
// view
|
||||
void V_UpdatePalette (void);
|
||||
void V_Register (void);
|
||||
void V_ParseDamage (void);
|
||||
void V_SetContentsColor (int contents);
|
||||
void V_PrepBlend (void);
|
||||
void V_ParseDamage (viewstate_t *vs);
|
||||
void V_PrepBlend (viewstate_t *vs);
|
||||
|
||||
// cl_tent
|
||||
void CL_SignonReply (void);
|
||||
|
|
|
@ -75,7 +75,7 @@ CL_BaseMove (usercmd_t *cmd)
|
|||
return;
|
||||
}
|
||||
VectorCopy (cl.viewstate.angles, cl.movestate.angles);//FIXME
|
||||
CL_Input_BuildMove (host_frametime, &cl.movestate);
|
||||
CL_Input_BuildMove (host_frametime, &cl.movestate, &cl.viewstate);
|
||||
VectorCopy (cl.movestate.angles, cl.viewstate.angles);//FIXME
|
||||
|
||||
memset (cmd, 0, sizeof (*cmd));
|
||||
|
|
|
@ -213,12 +213,14 @@ CL_ClearState (void)
|
|||
|
||||
// wipe the entire cl structure
|
||||
memset (&cl, 0, sizeof (cl));
|
||||
cl.chase = 1;
|
||||
cl.viewstate.chase = 1;
|
||||
cl.viewstate.chasestate = &cl.chasestate;
|
||||
cl.watervis = 1;
|
||||
r_data->force_fullscreen = 0;
|
||||
r_data->lightstyle = cl.lightstyle;
|
||||
|
||||
CL_Init_Entity (&cl.viewent);
|
||||
cl.viewstate.weapon_entity = &cl.viewent;
|
||||
r_data->view_model = &cl.viewent;
|
||||
|
||||
SZ_Clear (&cls.message);
|
||||
|
@ -241,7 +243,7 @@ CL_StopCshifts (void)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CSHIFTS; i++)
|
||||
cl.cshifts[i].percent = 0;
|
||||
cl.viewstate.cshifts[i].percent = 0;
|
||||
for (i = 0; i < MAX_CL_STATS; i++)
|
||||
cl.stats[i] = 0;
|
||||
}
|
||||
|
@ -285,6 +287,7 @@ CL_Disconnect (void)
|
|||
|
||||
cl.worldmodel = NULL;
|
||||
cl.intermission = 0;
|
||||
cl.viewstate.intermission = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -435,6 +438,7 @@ CL_ReadFromServer (void)
|
|||
cl.oldtime = cl.time;
|
||||
cl.time += host_frametime;
|
||||
cl.viewstate.frametime = host_frametime;
|
||||
cl.viewstate.time = cl.time;
|
||||
|
||||
do {
|
||||
ret = CL_GetMessage ();
|
||||
|
@ -496,6 +500,8 @@ CL_SetState (cactive_t state)
|
|||
{
|
||||
cactive_t old_state = cls.state;
|
||||
cls.state = state;
|
||||
cl.viewstate.active = cls.state == ca_active;
|
||||
cl.viewstate.drift_enabled = !cls.demoplayback;
|
||||
Sys_MaskPrintf (SYS_net, "CL_SetState: %d -> %d\n", old_state, state);
|
||||
if (old_state != state) {
|
||||
if (old_state == ca_active) {
|
||||
|
|
|
@ -367,6 +367,8 @@ CL_ParseServerInfo (void)
|
|||
}
|
||||
cl.players = Hunk_AllocName (0, cl.maxclients * sizeof (*cl.players),
|
||||
"players");
|
||||
cl.viewstate.voffs_enabled = cl.maxclients == 1;
|
||||
cl.viewstate.bob_enabled = 1;
|
||||
for (i = 0; i < cl.maxclients; i++) {
|
||||
cl.players[i].userinfo = Info_ParseString ("name\\", 0, 0);
|
||||
cl.players[i].name = Info_Key (cl.players[i].userinfo, "name");
|
||||
|
@ -653,14 +655,14 @@ CL_ParseClientdata (void)
|
|||
bits |= MSG_ReadByte (net_message) << 24;
|
||||
|
||||
if (bits & SU_VIEWHEIGHT)
|
||||
cl.viewheight = ((signed char) MSG_ReadByte (net_message));
|
||||
cl.viewstate.height = ((signed char) MSG_ReadByte (net_message));
|
||||
else
|
||||
cl.viewheight = DEFAULT_VIEWHEIGHT;
|
||||
cl.viewstate.height = DEFAULT_VIEWHEIGHT;
|
||||
|
||||
if (bits & SU_IDEALPITCH)
|
||||
cl.idealpitch = ((signed char) MSG_ReadByte (net_message));
|
||||
cl.viewstate.idealpitch = ((signed char) MSG_ReadByte (net_message));
|
||||
else
|
||||
cl.idealpitch = 0;
|
||||
cl.viewstate.idealpitch = 0;
|
||||
|
||||
cl.frameVelocity[1] = cl.frameVelocity[0];
|
||||
vec3_t punchangle = { };
|
||||
|
@ -691,6 +693,8 @@ CL_ParseClientdata (void)
|
|||
if ((i & (1 << j)) && !(cl.stats[STAT_ITEMS] & (1 << j)))
|
||||
cl.item_gettime[j] = cl.time;
|
||||
cl.stats[STAT_ITEMS] = i;
|
||||
#define IT_POWER (IT_QUAD | IT_SUIT | IT_INVULNERABILITY | IT_INVISIBILITY)
|
||||
cl.viewstate.powerup_index = (cl.stats[STAT_ITEMS] & IT_POWER) >> 19;
|
||||
}
|
||||
|
||||
cl.viewstate.onground = (bits & SU_ONGROUND) ? 0 : -1;
|
||||
|
@ -700,6 +704,7 @@ CL_ParseClientdata (void)
|
|||
cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte (net_message);
|
||||
else
|
||||
cl.stats[STAT_WEAPONFRAME] = 0;
|
||||
cl.viewstate.weaponframe = cl.stats[STAT_WEAPONFRAME];
|
||||
|
||||
if (bits & SU_ARMOR)
|
||||
i = MSG_ReadByte (net_message);
|
||||
|
@ -717,6 +722,7 @@ CL_ParseClientdata (void)
|
|||
if (cl.stats[STAT_WEAPON] != i) {
|
||||
cl.stats[STAT_WEAPON] = i;
|
||||
Sbar_Changed ();
|
||||
cl.viewstate.weapon_model = cl.model_precache[cl.stats[STAT_WEAPON]];
|
||||
}
|
||||
|
||||
i = (short) MSG_ReadShort (net_message);
|
||||
|
@ -914,6 +920,7 @@ CL_ParseServerMessage (void)
|
|||
|
||||
case svc_setview:
|
||||
cl.viewentity = MSG_ReadShort (net_message);
|
||||
cl.viewstate.player_entity = &cl_entities[cl.viewentity];
|
||||
break;
|
||||
|
||||
case svc_sound:
|
||||
|
@ -1047,7 +1054,9 @@ CL_ParseServerMessage (void)
|
|||
break;
|
||||
|
||||
case svc_damage:
|
||||
V_ParseDamage ();
|
||||
V_ParseDamage (&cl.viewstate);
|
||||
// put sbar face into pain frame
|
||||
cl.faceanimtime = cl.time + 0.2;
|
||||
break;
|
||||
|
||||
case svc_spawnstatic:
|
||||
|
|
|
@ -80,7 +80,7 @@ SCR_CShift (void)
|
|||
cl.worldmodel);
|
||||
contents = leaf->contents;
|
||||
}
|
||||
V_SetContentsColor (contents);
|
||||
V_SetContentsColor (&cl.viewstate, contents);
|
||||
r_funcs->Draw_BlendScreen (r_data->vid->cshift_color);
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,8 @@ CL_UpdateScreen (double realtime)
|
|||
scr_funcs_normal[2] = r_funcs->SCR_DrawTurtle;
|
||||
scr_funcs_normal[3] = r_funcs->SCR_DrawPause;
|
||||
|
||||
V_PrepBlend ();
|
||||
V_RenderView ();
|
||||
cl.viewstate.intermission = cl.intermission != 0;
|
||||
V_PrepBlend (&cl.viewstate);
|
||||
V_RenderView (&cl.viewstate);
|
||||
SCR_UpdateScreen (realtime, scr_funcs[index]);
|
||||
}
|
||||
|
|
|
@ -85,11 +85,37 @@ vec4f_t v_idle_yaw;
|
|||
vec4f_t v_idle_roll;
|
||||
vec4f_t v_idle_pitch;
|
||||
|
||||
cshift_t cshift_empty = { {130, 80, 50}, 0};
|
||||
cshift_t cshift_water = { {130, 80, 50}, 128};
|
||||
cshift_t cshift_slime = { {0, 25, 5}, 150};
|
||||
cshift_t cshift_lava = { {255, 80, 0}, 150};
|
||||
cshift_t cshift_bonus = { {215, 186, 60}, 50};
|
||||
static cshift_t cshift_empty = { {130, 80, 50}, 0};
|
||||
static cshift_t cshift_water = { {130, 80, 50}, 128};
|
||||
static cshift_t cshift_slime = { { 0, 25, 5}, 150};
|
||||
static cshift_t cshift_lava = { {255, 80, 0}, 150};
|
||||
static cshift_t cshift_bonus = { {215, 186, 60}, 50};
|
||||
|
||||
static cshift_t armor_blood[] = {
|
||||
{ {255, 0, 0} }, // blood
|
||||
{ {220, 50, 50} }, // armor + blood
|
||||
{ {200, 100, 100} }, // armor > blood need two for logic
|
||||
{ {200, 100, 100} }, // armor > blood need two for logic
|
||||
};
|
||||
|
||||
static cshift_t powerup[] = {
|
||||
{ { 0, 0, 0}, 0},
|
||||
{ {100, 100, 100}, 100}, // IT_INVISIBILITY
|
||||
{ {255, 255, 0}, 30}, // IT_INVULNERABILITY
|
||||
{ {255, 255, 0}, 30}, // IT_INVULNERABILITY
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 0, 255}, 30}, // IT_QUAD
|
||||
{ { 0, 0, 255}, 30}, // IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
};
|
||||
|
||||
#define sqr(x) ((x) * (x))
|
||||
|
||||
|
@ -115,20 +141,20 @@ V_CalcRoll (const vec3_t angles, vec4f_t velocity)
|
|||
}
|
||||
|
||||
static float
|
||||
V_CalcBob (void)
|
||||
V_CalcBob (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t velocity = cl.viewstate.velocity;
|
||||
vec4f_t velocity = vs->velocity;
|
||||
float cycle;
|
||||
static double bobtime;
|
||||
static float bob;
|
||||
|
||||
if (cl.spectator)
|
||||
if (!vs->bob_enabled)
|
||||
return 0;
|
||||
|
||||
if (cl.viewstate.onground == -1)
|
||||
if (vs->onground == -1)
|
||||
return bob; // just use old value
|
||||
|
||||
bobtime += cl.viewstate.frametime;
|
||||
bobtime += vs->frametime;
|
||||
cycle = bobtime - (int) (bobtime / cl_bobcycle->value) *
|
||||
cl_bobcycle->value;
|
||||
cycle /= cl_bobcycle->value;
|
||||
|
@ -150,31 +176,37 @@ V_CalcBob (void)
|
|||
}
|
||||
|
||||
void
|
||||
V_StartPitchDrift (void)
|
||||
V_StartPitchDrift (viewstate_t *vs)
|
||||
{
|
||||
if (cl.laststop == cl.time) {
|
||||
if (vs->laststop == vs->time) {
|
||||
return; // something else is keeping it from drifting
|
||||
}
|
||||
|
||||
if (cl.nodrift || !cl.pitchvel) {
|
||||
cl.pitchvel = v_centerspeed->value;
|
||||
cl.nodrift = false;
|
||||
cl.driftmove = 0;
|
||||
if (vs->nodrift || !vs->pitchvel) {
|
||||
vs->pitchvel = v_centerspeed->value;
|
||||
vs->nodrift = false;
|
||||
vs->driftmove = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
V_StopPitchDrift (void)
|
||||
static void
|
||||
V_StartPitchDrift_f (void *data)
|
||||
{
|
||||
cl.laststop = cl.time;
|
||||
cl.nodrift = true;
|
||||
cl.pitchvel = 0;
|
||||
V_StartPitchDrift (data);
|
||||
}
|
||||
|
||||
void
|
||||
V_StopPitchDrift (viewstate_t *vs)
|
||||
{
|
||||
vs->laststop = vs->time;
|
||||
vs->nodrift = true;
|
||||
vs->pitchvel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
V_DriftPitch
|
||||
|
||||
Moves the client pitch angle towards cl.idealpitch sent by the server.
|
||||
Moves the client pitch angle towards vs->idealpitch sent by the server.
|
||||
|
||||
If the user is adjusting pitch manually, either with lookup/lookdown,
|
||||
mlook and mouse, or klook and keyboard, pitch drifting is constantly
|
||||
|
@ -184,64 +216,64 @@ V_StopPitchDrift (void)
|
|||
and lookspring is non 0, or when
|
||||
*/
|
||||
static void
|
||||
V_DriftPitch (void)
|
||||
V_DriftPitch (viewstate_t *vs)
|
||||
{
|
||||
float delta, move;
|
||||
float forwardmove = cl.viewstate.movecmd[0];
|
||||
float forwardmove = vs->movecmd[0];
|
||||
|
||||
if (noclip_anglehack || cl.viewstate.onground == -1 || cls.demoplayback) {
|
||||
cl.driftmove = 0;
|
||||
cl.pitchvel = 0;
|
||||
if (noclip_anglehack || vs->onground == -1 || !vs->drift_enabled) {
|
||||
vs->driftmove = 0;
|
||||
vs->pitchvel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// don't count small mouse motion
|
||||
if (cl.nodrift) {
|
||||
if (vs->nodrift) {
|
||||
if (fabs (forwardmove) < cl_forwardspeed->value)
|
||||
cl.driftmove = 0;
|
||||
vs->driftmove = 0;
|
||||
else
|
||||
cl.driftmove += cl.viewstate.frametime;
|
||||
vs->driftmove += vs->frametime;
|
||||
|
||||
if (cl.driftmove > v_centermove->value) {
|
||||
V_StartPitchDrift ();
|
||||
if (vs->driftmove > v_centermove->value) {
|
||||
V_StartPitchDrift (vs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
delta = cl.idealpitch - cl.viewstate.angles[PITCH];
|
||||
delta = vs->idealpitch - vs->angles[PITCH];
|
||||
|
||||
if (!delta) {
|
||||
cl.pitchvel = 0;
|
||||
vs->pitchvel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
move = cl.viewstate.frametime * cl.pitchvel;
|
||||
cl.pitchvel += cl.viewstate.frametime * v_centerspeed->value;
|
||||
move = vs->frametime * vs->pitchvel;
|
||||
vs->pitchvel += vs->frametime * v_centerspeed->value;
|
||||
|
||||
if (delta > 0) {
|
||||
if (move > delta) {
|
||||
cl.pitchvel = 0;
|
||||
vs->pitchvel = 0;
|
||||
move = delta;
|
||||
}
|
||||
cl.viewstate.angles[PITCH] += move;
|
||||
vs->angles[PITCH] += move;
|
||||
} else if (delta < 0) {
|
||||
if (move > -delta) {
|
||||
cl.pitchvel = 0;
|
||||
vs->pitchvel = 0;
|
||||
move = -delta;
|
||||
}
|
||||
cl.viewstate.angles[PITCH] -= move;
|
||||
vs->angles[PITCH] -= move;
|
||||
}
|
||||
}
|
||||
|
||||
/* PALETTE FLASHES */
|
||||
|
||||
void
|
||||
V_ParseDamage (void)
|
||||
V_ParseDamage (viewstate_t *vs)
|
||||
{
|
||||
float count, side;
|
||||
int armor, blood;
|
||||
vec4f_t origin = cl.viewstate.origin;
|
||||
vec_t *angles = cl.viewstate.angles;
|
||||
vec4f_t origin = vs->origin;
|
||||
vec_t *angles = vs->angles;
|
||||
vec3_t from, forward, right, up;
|
||||
|
||||
armor = MSG_ReadByte (net_message);
|
||||
|
@ -252,31 +284,15 @@ V_ParseDamage (void)
|
|||
if (count < 10)
|
||||
count = 10;
|
||||
|
||||
cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame
|
||||
|
||||
if (cl_cshift_damage->int_val
|
||||
|| (cl.sv_cshifts & INFO_CSHIFT_DAMAGE)) {
|
||||
cshift_t *cshift = &cl.cshifts[CSHIFT_DAMAGE];
|
||||
|
||||
cshift->percent += 3 * count;
|
||||
cshift->percent =
|
||||
bound (0, cshift->percent, 150);
|
||||
|
||||
if (armor > blood) {
|
||||
cshift->destcolor[0] = 200;
|
||||
cshift->destcolor[1] = 100;
|
||||
cshift->destcolor[2] = 100;
|
||||
} else if (armor) {
|
||||
cshift->destcolor[0] = 220;
|
||||
cshift->destcolor[1] = 50;
|
||||
cshift->destcolor[2] = 50;
|
||||
} else {
|
||||
cshift->destcolor[0] = 255;
|
||||
cshift->destcolor[1] = 0;
|
||||
cshift->destcolor[2] = 0;
|
||||
}
|
||||
|| (vs->force_cshifts & INFO_CSHIFT_DAMAGE)) {
|
||||
cshift_t *cshift = &vs->cshifts[CSHIFT_DAMAGE];
|
||||
int percent = cshift->percent;
|
||||
*cshift = armor_blood[(2 * (armor > blood)) + (armor > 0)];
|
||||
cshift->percent = percent + 3 * count;
|
||||
cshift->percent = bound (0, cshift->percent, 150);
|
||||
cshift->initialpct = cshift->percent;
|
||||
cshift->time = cl.time;
|
||||
cshift->time = vs->time;
|
||||
}
|
||||
|
||||
// calculate view angle kicks
|
||||
|
@ -309,15 +325,16 @@ V_cshift_f (void)
|
|||
When you run over an item, the server sends this command
|
||||
*/
|
||||
static void
|
||||
V_BonusFlash_f (void)
|
||||
V_BonusFlash_f (void *data)
|
||||
{
|
||||
viewstate_t *vs = data;
|
||||
if (!cl_cshift_bonus->int_val
|
||||
&& !(cl.sv_cshifts & INFO_CSHIFT_BONUS))
|
||||
&& !(vs->force_cshifts & INFO_CSHIFT_BONUS))
|
||||
return;
|
||||
|
||||
cl.cshifts[CSHIFT_BONUS] = cshift_bonus;
|
||||
cl.cshifts[CSHIFT_BONUS].initialpct = cl.cshifts[CSHIFT_BONUS].percent;
|
||||
cl.cshifts[CSHIFT_BONUS].time = cl.time;
|
||||
vs->cshifts[CSHIFT_BONUS] = cshift_bonus;
|
||||
vs->cshifts[CSHIFT_BONUS].initialpct = vs->cshifts[CSHIFT_BONUS].percent;
|
||||
vs->cshifts[CSHIFT_BONUS].time = vs->time;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -326,69 +343,34 @@ V_BonusFlash_f (void)
|
|||
Underwater, lava, etc each has a color shift
|
||||
*/
|
||||
void
|
||||
V_SetContentsColor (int contents)
|
||||
V_SetContentsColor (viewstate_t *vs, int contents)
|
||||
{
|
||||
if (!cl_cshift_contents->int_val
|
||||
&& !(cl.sv_cshifts & INFO_CSHIFT_CONTENTS)) {
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
&& !(vs->force_cshifts & INFO_CSHIFT_CONTENTS)) {
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (contents) {
|
||||
case CONTENTS_EMPTY:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
break;
|
||||
case CONTENTS_LAVA:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_lava;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_lava;
|
||||
break;
|
||||
case CONTENTS_SOLID:
|
||||
case CONTENTS_SLIME:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_slime;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_slime;
|
||||
break;
|
||||
default:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_water;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_water;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
V_CalcPowerupCshift (void)
|
||||
V_CalcPowerupCshift (viewstate_t *vs)
|
||||
{
|
||||
if (!cl.stats[STAT_ITEMS] & (IT_SUIT || IT_INVISIBILITY || IT_QUAD
|
||||
|| IT_INVULNERABILITY))
|
||||
{
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY &&
|
||||
cl.stats[STAT_ITEMS] & IT_QUAD) {
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 30;
|
||||
} else 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.stats[STAT_ITEMS] & IT_INVULNERABILITY) {
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 30;
|
||||
} 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.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 {
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 0;
|
||||
}
|
||||
vs->cshifts[CSHIFT_POWERUP] = powerup[vs->powerup_index];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,22 +380,22 @@ V_CalcPowerupCshift (void)
|
|||
a bit, but otherwise this is his code. --KB
|
||||
*/
|
||||
static void
|
||||
V_CalcBlend (void)
|
||||
V_CalcBlend (viewstate_t *vs)
|
||||
{
|
||||
float a2, a3;
|
||||
float r = 0, g = 0, b = 0, a = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CSHIFTS; i++) {
|
||||
a2 = cl.cshifts[i].percent / 255.0;
|
||||
a2 = vs->cshifts[i].percent / 255.0;
|
||||
|
||||
if (!a2)
|
||||
continue;
|
||||
|
||||
a2 = min (a2, 1.0);
|
||||
r += (cl.cshifts[i].destcolor[0] - r) * a2;
|
||||
g += (cl.cshifts[i].destcolor[1] - g) * a2;
|
||||
b += (cl.cshifts[i].destcolor[2] - b) * a2;
|
||||
r += (vs->cshifts[i].destcolor[0] - r) * a2;
|
||||
g += (vs->cshifts[i].destcolor[1] - g) * a2;
|
||||
b += (vs->cshifts[i].destcolor[2] - b) * a2;
|
||||
|
||||
a3 = (1.0 - a) * (1.0 - a2);
|
||||
a = 1.0 - a3;
|
||||
|
@ -434,12 +416,12 @@ V_CalcBlend (void)
|
|||
}
|
||||
|
||||
static void
|
||||
V_DropCShift (cshift_t *cs, float droprate)
|
||||
V_DropCShift (cshift_t *cs, double time, float droprate)
|
||||
{
|
||||
if (cs->time < 0) {
|
||||
cs->percent = 0;
|
||||
} else {
|
||||
cs->percent = cs->initialpct - (cl.time - cs->time) * droprate;
|
||||
cs->percent = cs->initialpct - (time - cs->time) * droprate;
|
||||
if (cs->percent <= 0) {
|
||||
cs->percent = 0;
|
||||
cs->time = -1;
|
||||
|
@ -448,56 +430,55 @@ V_DropCShift (cshift_t *cs, float droprate)
|
|||
}
|
||||
|
||||
void
|
||||
V_PrepBlend (void)
|
||||
V_PrepBlend (viewstate_t *vs)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (cl_cshift_powerup->int_val
|
||||
|| (cl.sv_cshifts & INFO_CSHIFT_POWERUP))
|
||||
V_CalcPowerupCshift ();
|
||||
|| (vs->force_cshifts & INFO_CSHIFT_POWERUP))
|
||||
V_CalcPowerupCshift (vs);
|
||||
|
||||
r_data->vid->cshift_changed = false;
|
||||
|
||||
for (i = 0; i < NUM_CSHIFTS; i++) {
|
||||
if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent) {
|
||||
if (vs->cshifts[i].percent != vs->prev_cshifts[i].percent) {
|
||||
r_data->vid->cshift_changed = true;
|
||||
cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
|
||||
vs->prev_cshifts[i].percent = vs->cshifts[i].percent;
|
||||
}
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
|
||||
if (vs->cshifts[i].destcolor[j] != vs->prev_cshifts[i].destcolor[j])
|
||||
{
|
||||
r_data->vid->cshift_changed = true;
|
||||
cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
|
||||
vs->prev_cshifts[i].destcolor[j] = vs->cshifts[i].destcolor[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drop the damage value
|
||||
V_DropCShift (&cl.cshifts[CSHIFT_DAMAGE], 150);
|
||||
V_DropCShift (&vs->cshifts[CSHIFT_DAMAGE], vs->time, 150);
|
||||
// drop the bonus value
|
||||
V_DropCShift (&cl.cshifts[CSHIFT_BONUS], 100);
|
||||
V_DropCShift (&vs->cshifts[CSHIFT_BONUS], vs->time, 100);
|
||||
|
||||
if (!r_data->vid->cshift_changed && !r_data->vid->recalc_refdef)
|
||||
return;
|
||||
|
||||
V_CalcBlend ();
|
||||
V_CalcBlend (vs);
|
||||
}
|
||||
|
||||
/* VIEW RENDERING */
|
||||
|
||||
static void
|
||||
CalcGunAngle (void)
|
||||
CalcGunAngle (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t rotation = r_data->refdef->viewrotation;
|
||||
//FIXME make child of camera
|
||||
Transform_SetWorldRotation (cl.viewent.transform, rotation);
|
||||
Transform_SetWorldRotation (vs->weapon_entity->transform, rotation);
|
||||
}
|
||||
|
||||
static void
|
||||
V_BoundOffsets (void)
|
||||
V_BoundOffsets (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t offset = r_data->refdef->viewposition
|
||||
- cl.viewstate.origin;
|
||||
vec4f_t offset = r_data->refdef->viewposition - vs->origin;
|
||||
|
||||
// absolutely bound refresh reletive to entity clipping hull
|
||||
// so the view can never be inside a solid wall
|
||||
|
@ -505,17 +486,17 @@ V_BoundOffsets (void)
|
|||
offset[0] = bound (-14, offset[0], 14);
|
||||
offset[1] = bound (-14, offset[1], 14);
|
||||
offset[2] = bound (-22, offset[2], 30);
|
||||
r_data->refdef->viewposition = cl.viewstate.origin + offset;
|
||||
r_data->refdef->viewposition = vs->origin + offset;
|
||||
}
|
||||
|
||||
static vec4f_t
|
||||
idle_quat (vec4f_t axis, cvar_t *cycle, cvar_t *level)
|
||||
idle_quat (vec4f_t axis, cvar_t *cycle, cvar_t *level, double time)
|
||||
{
|
||||
vec4f_t identity = { 0, 0, 0, 1 };
|
||||
if (!level || !cycle) {
|
||||
return identity;
|
||||
}
|
||||
float scale = sin (cl.time * cycle->value);
|
||||
float scale = sin (time * cycle->value);
|
||||
float ang = scale * level->value * v_idlescale->value;
|
||||
float c = cos (ang * M_PI / 360);
|
||||
float s = sin (ang * M_PI / 360);
|
||||
|
@ -528,14 +509,14 @@ idle_quat (vec4f_t axis, cvar_t *cycle, cvar_t *level)
|
|||
Idle swaying
|
||||
*/
|
||||
static void
|
||||
V_AddIdle (void)
|
||||
V_AddIdle (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t roll = idle_quat ((vec4f_t) { 1, 0, 0, 0},
|
||||
v_iroll_cycle, v_iroll_level);
|
||||
v_iroll_cycle, v_iroll_level, vs->time);
|
||||
vec4f_t pitch = idle_quat ((vec4f_t) { 0, 1, 0, 0},
|
||||
v_ipitch_cycle, v_ipitch_level);
|
||||
v_ipitch_cycle, v_ipitch_level, vs->time);
|
||||
vec4f_t yaw = idle_quat ((vec4f_t) { 0, 0, 1, 0},
|
||||
v_iyaw_cycle, v_iyaw_level);
|
||||
v_iyaw_cycle, v_iyaw_level, vs->time);
|
||||
vec4f_t rot = normalf (qmulf (yaw, qmulf (pitch, roll)));
|
||||
|
||||
// rotate the view
|
||||
|
@ -543,8 +524,8 @@ V_AddIdle (void)
|
|||
|
||||
// counter-rotate the weapon
|
||||
rot = qmulf (qconjf (rot),
|
||||
Transform_GetWorldRotation (cl.viewent.transform));
|
||||
Transform_SetWorldRotation (cl.viewent.transform, rot);
|
||||
Transform_GetWorldRotation (vs->weapon_entity->transform));
|
||||
Transform_SetWorldRotation (vs->weapon_entity->transform, rot);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -553,10 +534,10 @@ V_AddIdle (void)
|
|||
Roll is induced by movement and damage
|
||||
*/
|
||||
static void
|
||||
V_CalcViewRoll (void)
|
||||
V_CalcViewRoll (viewstate_t *vs)
|
||||
{
|
||||
vec_t *angles = cl.viewstate.angles;
|
||||
vec4f_t velocity = cl.viewstate.velocity;
|
||||
vec_t *angles = vs->angles;
|
||||
vec4f_t velocity = vs->velocity;
|
||||
vec3_t ang = { };
|
||||
|
||||
ang[ROLL] = V_CalcRoll (angles, velocity);
|
||||
|
@ -564,10 +545,10 @@ V_CalcViewRoll (void)
|
|||
if (v_dmg_time > 0) {
|
||||
ang[ROLL] += v_dmg_time / v_kicktime->value * v_dmg_roll;
|
||||
ang[PITCH] += v_dmg_time / v_kicktime->value * v_dmg_pitch;
|
||||
v_dmg_time -= cl.viewstate.frametime;
|
||||
v_dmg_time -= vs->frametime;
|
||||
}
|
||||
|
||||
if (cl.viewstate.flags & VF_DEAD) { // VF_GIB will also set VF_DEAD
|
||||
if (vs->flags & VF_DEAD) { // VF_GIB will also set VF_DEAD
|
||||
ang[ROLL] = 80; // dead view angle
|
||||
}
|
||||
|
||||
|
@ -577,17 +558,17 @@ V_CalcViewRoll (void)
|
|||
}
|
||||
|
||||
static void
|
||||
V_CalcIntermissionRefdef (void)
|
||||
V_CalcIntermissionRefdef (viewstate_t *vs)
|
||||
{
|
||||
// ent is the player model (visible when out of body)
|
||||
entity_t *ent = &cl_entities[cl.viewentity];
|
||||
// vs->player_entity is the player model (visible when out of body)
|
||||
entity_t *ent = vs->player_entity;
|
||||
entity_t *view;
|
||||
float old;
|
||||
vec4f_t origin = Transform_GetWorldPosition (ent->transform);
|
||||
vec4f_t rotation = Transform_GetWorldRotation (ent->transform);
|
||||
|
||||
// view is the weapon model (visible only from inside body)
|
||||
view = &cl.viewent;
|
||||
view = vs->weapon_entity;
|
||||
|
||||
r_data->refdef->viewposition = origin;
|
||||
r_data->refdef->viewrotation = rotation;
|
||||
|
@ -596,37 +577,37 @@ V_CalcIntermissionRefdef (void)
|
|||
// always idle in intermission
|
||||
old = v_idlescale->value;
|
||||
Cvar_SetValue (v_idlescale, 1);
|
||||
V_AddIdle ();
|
||||
V_AddIdle (vs);
|
||||
Cvar_SetValue (v_idlescale, old);
|
||||
}
|
||||
|
||||
static void
|
||||
V_CalcRefdef (void)
|
||||
V_CalcRefdef (viewstate_t *vs)
|
||||
{
|
||||
// view is the weapon model (visible only from inside body)
|
||||
entity_t *view = &cl.viewent;
|
||||
entity_t *view = vs->weapon_entity;
|
||||
float bob;
|
||||
static float oldz = 0;
|
||||
vec4f_t forward = {}, right = {}, up = {};
|
||||
vec4f_t origin = cl.viewstate.origin;
|
||||
vec_t *viewangles = cl.viewstate.angles;
|
||||
vec4f_t origin = vs->origin;
|
||||
vec_t *viewangles = vs->angles;
|
||||
|
||||
V_DriftPitch ();
|
||||
V_DriftPitch (vs);
|
||||
|
||||
bob = V_CalcBob ();
|
||||
bob = V_CalcBob (vs);
|
||||
|
||||
// refresh position
|
||||
r_data->refdef->viewposition = origin;
|
||||
r_data->refdef->viewposition[2] += cl.viewheight + bob;
|
||||
r_data->refdef->viewposition[2] += vs->height + bob;
|
||||
|
||||
// never let it sit exactly on a node line, because a water plane can
|
||||
// disappear when viewed with the eye exactly on it.
|
||||
// server protocol specifies to only 1/8 pixel, so add 1/16 in each axis
|
||||
r_data->refdef->viewposition += (vec4f_t) { 1.0/16, 1.0/16, 1.0/16, 0};
|
||||
|
||||
AngleQuat (cl.viewstate.angles, &r_data->refdef->viewrotation[0]);//FIXME
|
||||
V_CalcViewRoll ();
|
||||
V_AddIdle ();
|
||||
AngleQuat (vs->angles, &r_data->refdef->viewrotation[0]);//FIXME
|
||||
V_CalcViewRoll (vs);
|
||||
V_AddIdle (vs);
|
||||
|
||||
// offsets
|
||||
//FIXME semi-duplicates AngleQuat (also, vec3_t vs vec4f_t)
|
||||
|
@ -634,18 +615,18 @@ V_CalcRefdef (void)
|
|||
|
||||
// don't allow cheats in multiplayer
|
||||
// FIXME check for dead
|
||||
if (cl.maxclients == 1) {
|
||||
if (vs->voffs_enabled) {
|
||||
r_data->refdef->viewposition += scr_ofsx->value * forward
|
||||
+ scr_ofsy->value * right
|
||||
+ scr_ofsz->value * up;
|
||||
}
|
||||
|
||||
V_BoundOffsets ();
|
||||
V_BoundOffsets (vs);
|
||||
|
||||
// set up gun position
|
||||
CalcGunAngle ();
|
||||
CalcGunAngle (vs);
|
||||
|
||||
origin += (vec4f_t) { 0, 0, cl.viewheight, 0 };
|
||||
origin += (vec4f_t) { 0, 0, vs->height, 0 };
|
||||
origin += forward * bob * 0.4f + (vec4f_t) { 0, 0, bob, 0 };
|
||||
|
||||
// fudge position around to keep amount of weapon visible
|
||||
|
@ -662,23 +643,23 @@ V_CalcRefdef (void)
|
|||
origin += (vec4f_t) { 0, 0, 0.5, 0};
|
||||
}
|
||||
|
||||
model_t *model = cl.model_precache[cl.stats[STAT_WEAPON]];
|
||||
model_t *model = vs->weapon_model;
|
||||
if (view->renderer.model != model) {
|
||||
view->animation.pose2 = -1;
|
||||
}
|
||||
view->renderer.model = model;
|
||||
view->animation.frame = cl.stats[STAT_WEAPONFRAME];
|
||||
view->animation.frame = vs->weaponframe;
|
||||
view->renderer.skin = 0;
|
||||
|
||||
// set up the refresh position
|
||||
r_data->refdef->viewrotation = qmulf (cl.viewstate.punchangle,
|
||||
r_data->refdef->viewrotation = qmulf (vs->punchangle,
|
||||
r_data->refdef->viewrotation);
|
||||
|
||||
// smooth out stair step ups
|
||||
if ((cl.viewstate.onground != -1) && (origin[2] - oldz > 0)) {
|
||||
if ((vs->onground != -1) && (origin[2] - oldz > 0)) {
|
||||
float steptime;
|
||||
|
||||
steptime = cl.viewstate.frametime;
|
||||
steptime = vs->frametime;
|
||||
|
||||
oldz += steptime * 80;
|
||||
if (oldz > origin[2])
|
||||
|
@ -696,8 +677,8 @@ V_CalcRefdef (void)
|
|||
CL_TransformEntity (view, 1, ang, origin);
|
||||
}
|
||||
|
||||
if (cl.chase && chase_active->int_val) {
|
||||
Chase_Update (&cl.chasestate);
|
||||
if (vs->chase && chase_active->int_val) {
|
||||
Chase_Update (vs->chasestate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,27 +689,28 @@ V_CalcRefdef (void)
|
|||
the entity origin, so any view position inside that will be valid
|
||||
*/
|
||||
void
|
||||
V_RenderView (void)
|
||||
V_RenderView (viewstate_t *vs)
|
||||
{
|
||||
if (cls.state != ca_active) {
|
||||
if (!vs->active) {
|
||||
r_data->refdef->viewposition = (vec4f_t) { 0, 0, 0, 1 };
|
||||
r_data->refdef->viewrotation = (vec4f_t) { 0, 0, 0, 1 };
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.intermission) { // intermission / finale rendering
|
||||
V_CalcIntermissionRefdef ();
|
||||
if (vs->intermission) { // intermission / finale rendering
|
||||
V_CalcIntermissionRefdef (vs);
|
||||
} else {
|
||||
V_CalcRefdef ();
|
||||
V_CalcRefdef (vs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
V_Init (void)
|
||||
{
|
||||
Cmd_AddCommand ("bf", V_BonusFlash_f, "Background flash, used when you "
|
||||
"pick up an item");
|
||||
Cmd_AddCommand ("centerview", V_StartPitchDrift, "Centers the player's "
|
||||
Cmd_AddDataCommand ("bf", V_BonusFlash_f, &cl.viewstate,
|
||||
"Background flash, used when you pick up an item");
|
||||
Cmd_AddDataCommand ("centerview", V_StartPitchDrift_f, &cl.viewstate,
|
||||
"Centers the player's "
|
||||
"view ahead after +lookup or +lookdown\n"
|
||||
"Will not work while mlook is active or freelook is 1.");
|
||||
Cmd_AddCommand ("v_cshift", V_cshift_f, "This adjusts all of the colors "
|
||||
|
|
|
@ -191,9 +191,6 @@ typedef struct client_state_s {
|
|||
float item_gettime[32]; // cl.time of aquiring item, for blinking
|
||||
float faceanimtime; // Use anim frame if cl.time < this
|
||||
|
||||
cshift_t cshifts[NUM_CSHIFTS]; // Color shifts for damage, powerups
|
||||
cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types
|
||||
|
||||
// the client simulates or interpolates movement to get these values
|
||||
double time; // this is the time value that the client
|
||||
// is rendering at. always <= realtime
|
||||
|
@ -202,15 +199,8 @@ typedef struct client_state_s {
|
|||
viewstate_t viewstate;
|
||||
movestate_t movestate;
|
||||
chasestate_t chasestate;
|
||||
// pitch drifting vars
|
||||
float idealpitch;
|
||||
float pitchvel;
|
||||
qboolean nodrift;
|
||||
float driftmove;
|
||||
double laststop;
|
||||
|
||||
qboolean paused; // Sent over by server
|
||||
float viewheight;
|
||||
float crouch; // Local amount for smoothing stepups
|
||||
qboolean inwater;
|
||||
|
||||
|
@ -249,7 +239,6 @@ typedef struct client_state_s {
|
|||
int gametype;
|
||||
int maxclients;
|
||||
// serverinfo mirrors
|
||||
int chase;
|
||||
int sv_cshifts;
|
||||
int no_pogo_stick;
|
||||
int teamplay;
|
||||
|
@ -327,9 +316,9 @@ void CL_UpdateScreen (double realtime);
|
|||
|
||||
void CL_SetState (cactive_t state);
|
||||
|
||||
void V_ParseDamage (void);
|
||||
void V_ParseDamage (viewstate_t *vs);
|
||||
|
||||
void V_PrepBlend (void);
|
||||
void V_PrepBlend (viewstate_t *vs);
|
||||
|
||||
void CL_Cmd_ForwardToServer (void);
|
||||
void CL_Cmd_Init (void);
|
||||
|
|
|
@ -116,7 +116,7 @@ vectoangles (vec3_t vec, vec3_t ang)
|
|||
qboolean
|
||||
Cam_DrawViewModel (void)
|
||||
{
|
||||
if (cl.chase && chase_active->int_val)
|
||||
if (cl.viewstate.chase && chase_active->int_val)
|
||||
return false;
|
||||
|
||||
if (!cl.spectator)
|
||||
|
@ -132,7 +132,7 @@ qboolean
|
|||
Cam_DrawPlayer (int playernum)
|
||||
{
|
||||
if (playernum == cl.playernum) { // client player
|
||||
if (cl.chase == 0 || chase_active->int_val == 0)
|
||||
if (cl.viewstate.chase == 0 || chase_active->int_val == 0)
|
||||
return false;
|
||||
if (!cl.spectator)
|
||||
return true;
|
||||
|
@ -141,7 +141,7 @@ Cam_DrawPlayer (int playernum)
|
|||
return true;
|
||||
if (cl.spectator && autocam && locked && spec_track == playernum)
|
||||
return false;
|
||||
if (cl.chase == 0 || chase_active->int_val == 0)
|
||||
if (cl.viewstate.chase == 0 || chase_active->int_val == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -91,7 +91,7 @@ CL_BaseMove (usercmd_t *cmd)
|
|||
return;
|
||||
}
|
||||
VectorCopy (cl.viewstate.angles, cl.movestate.angles);//FIXME
|
||||
CL_Input_BuildMove (host_frametime, &cl.movestate);
|
||||
CL_Input_BuildMove (host_frametime, &cl.movestate, &cl.viewstate);
|
||||
VectorCopy (cl.movestate.angles, cl.viewstate.angles);//FIXME
|
||||
|
||||
memset (cmd, 0, sizeof (*cmd));
|
||||
|
|
|
@ -399,6 +399,8 @@ CL_ClearState (void)
|
|||
r_data->force_fullscreen = 0;
|
||||
|
||||
cl.maxclients = MAX_CLIENTS;
|
||||
cl.viewstate.voffs_enabled = 0;
|
||||
cl.viewstate.chasestate = &cl.chasestate;
|
||||
|
||||
// Note: we should probably hack around this and give diff values for
|
||||
// diff gamedirs
|
||||
|
@ -410,6 +412,7 @@ CL_ClearState (void)
|
|||
cl.serverinfo = Info_ParseString ("", MAX_INFO_STRING, 0);
|
||||
|
||||
CL_Init_Entity (&cl.viewent);
|
||||
cl.viewstate.weapon_entity = &cl.viewent;
|
||||
|
||||
Sys_MaskPrintf (SYS_dev, "Clearing memory\n");
|
||||
VID_ClearMemory ();
|
||||
|
@ -439,7 +442,7 @@ CL_StopCshifts (void)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CSHIFTS; i++)
|
||||
cl.cshifts[i].percent = 0;
|
||||
cl.viewstate.cshifts[i].percent = 0;
|
||||
for (i = 0; i < MAX_CL_STATS; i++)
|
||||
cl.stats[i] = 0;
|
||||
}
|
||||
|
@ -618,9 +621,9 @@ CL_FullServerinfo_f (void)
|
|||
Sys_Printf ("Invalid QSG Protocol number: %s", p);
|
||||
}
|
||||
|
||||
cl.chase = cl.sv_cshifts = cl.no_pogo_stick = cl.teamplay = 0;
|
||||
cl.viewstate.chase = cl.sv_cshifts = cl.no_pogo_stick = cl.teamplay = 0;
|
||||
if ((p = Info_ValueForKey (cl.serverinfo, "chase")) && *p) {
|
||||
cl.chase = atoi (p);
|
||||
cl.viewstate.chase = atoi (p);
|
||||
}
|
||||
if ((p = Info_ValueForKey (cl.serverinfo, "cshifts")) && *p) {
|
||||
cl.sv_cshifts = atoi (p);
|
||||
|
@ -801,6 +804,7 @@ CL_Changing_f (void)
|
|||
|
||||
S_StopAllSounds ();
|
||||
cl.intermission = 0;
|
||||
cl.viewstate.intermission = 0;
|
||||
r_data->force_fullscreen = 0;
|
||||
CL_SetState (ca_connected); // not active anymore, but not
|
||||
// disconnected
|
||||
|
@ -1141,6 +1145,8 @@ CL_SetState (cactive_t state)
|
|||
|
||||
Sys_MaskPrintf (SYS_dev, "CL_SetState (%s)\n", state_names[state]);
|
||||
cls.state = state;
|
||||
cl.viewstate.active = cls.state == ca_active;
|
||||
cl.viewstate.drift_enabled = !cls.demoplayback;
|
||||
if (old_state != state) {
|
||||
if (old_state == ca_active) {
|
||||
// leaving active state
|
||||
|
|
|
@ -831,6 +831,8 @@ CL_ParseServerData (void)
|
|||
}
|
||||
|
||||
cl.viewentity = cl.playernum + 1;
|
||||
cl.viewstate.player_entity = &cl_entities[cl.viewentity];
|
||||
cl.viewstate.bob_enabled = !cl.spectator;
|
||||
|
||||
// get the full level name
|
||||
str = MSG_ReadString (net_message);
|
||||
|
@ -1216,7 +1218,7 @@ CL_ServerInfo (void)
|
|||
|
||||
Info_SetValueForKey (cl.serverinfo, key, value, 0);
|
||||
if (strequal (key, "chase")) {
|
||||
cl.chase = atoi (value);
|
||||
cl.viewstate.chase = atoi (value);
|
||||
} else if (strequal (key, "cshifts")) {
|
||||
cl.sv_cshifts = atoi (value);
|
||||
} else if (strequal (key, "no_pogo_stick")) {
|
||||
|
@ -1260,6 +1262,8 @@ CL_SetStat (int stat, int value)
|
|||
switch (stat) {
|
||||
case STAT_ITEMS:
|
||||
Sbar_Changed ();
|
||||
#define IT_POWER (IT_QUAD | IT_SUIT | IT_INVULNERABILITY | IT_INVISIBILITY)
|
||||
cl.viewstate.powerup_index = (cl.stats[STAT_ITEMS]&IT_POWER) >> 19;
|
||||
break;
|
||||
case STAT_HEALTH:
|
||||
if (cl_player_health_e->func)
|
||||
|
@ -1270,6 +1274,7 @@ CL_SetStat (int stat, int value)
|
|||
break;
|
||||
}
|
||||
cl.stats[stat] = value;
|
||||
cl.viewstate.weapon_model = cl.model_precache[cl.stats[STAT_WEAPON]];
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1501,7 +1506,9 @@ CL_ParseServerMessage (void)
|
|||
// svc_particle
|
||||
|
||||
case svc_damage:
|
||||
V_ParseDamage ();
|
||||
V_ParseDamage (&cl.viewstate);
|
||||
// put sbar face into pain frame
|
||||
cl.faceanimtime = cl.time + 0.2;
|
||||
break;
|
||||
|
||||
case svc_spawnstatic:
|
||||
|
|
|
@ -81,7 +81,7 @@ SCR_CShift (void)
|
|||
cl.worldmodel);
|
||||
contents = leaf->contents;
|
||||
}
|
||||
V_SetContentsColor (contents);
|
||||
V_SetContentsColor (&cl.viewstate, contents);
|
||||
r_funcs->Draw_BlendScreen (r_data->vid->cshift_color);
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,18 @@ CL_UpdateScreen (double realtime)
|
|||
scr_funcs_normal[2] = r_funcs->SCR_DrawTurtle;
|
||||
scr_funcs_normal[3] = r_funcs->SCR_DrawPause;
|
||||
|
||||
V_PrepBlend ();
|
||||
V_RenderView ();
|
||||
if (cl.viewstate.flags & VF_GIB) {
|
||||
cl.viewstate.height = 8; // gib view height
|
||||
} else if (cl.viewstate.flags & VF_DEAD) {
|
||||
cl.viewstate.height = -16; // corpse view height
|
||||
} else {
|
||||
cl.viewstate.height = DEFAULT_VIEWHEIGHT; // view height
|
||||
if (cl.stdver)
|
||||
cl.viewstate.height = cl.stats[STAT_VIEWHEIGHT];
|
||||
}
|
||||
|
||||
cl.viewstate.intermission = cl.intermission != 0;
|
||||
V_PrepBlend (&cl.viewstate);
|
||||
V_RenderView (&cl.viewstate);
|
||||
SCR_UpdateScreen (realtime, scr_funcs[index]);
|
||||
}
|
||||
|
|
|
@ -86,11 +86,37 @@ vec4f_t v_idle_yaw;
|
|||
vec4f_t v_idle_roll;
|
||||
vec4f_t v_idle_pitch;
|
||||
|
||||
cshift_t cshift_empty = { {130, 80, 50}, 0};
|
||||
cshift_t cshift_water = { {130, 80, 50}, 128};
|
||||
cshift_t cshift_slime = { {0, 25, 5}, 150};
|
||||
cshift_t cshift_lava = { {255, 80, 0}, 150};
|
||||
cshift_t cshift_bonus = { {215, 186, 60}, 50};
|
||||
static cshift_t cshift_empty = { {130, 80, 50}, 0};
|
||||
static cshift_t cshift_water = { {130, 80, 50}, 128};
|
||||
static cshift_t cshift_slime = { { 0, 25, 5}, 150};
|
||||
static cshift_t cshift_lava = { {255, 80, 0}, 150};
|
||||
static cshift_t cshift_bonus = { {215, 186, 60}, 50};
|
||||
|
||||
static cshift_t armor_blood[] = {
|
||||
{ {255, 0, 0} }, // blood
|
||||
{ {220, 50, 50} }, // armor + blood
|
||||
{ {200, 100, 100} }, // armor > blood need two for logic
|
||||
{ {200, 100, 100} }, // armor > blood need two for logic
|
||||
};
|
||||
|
||||
static cshift_t powerup[] = {
|
||||
{ { 0, 0, 0}, 0},
|
||||
{ {100, 100, 100}, 100}, // IT_INVISIBILITY
|
||||
{ {255, 255, 0}, 30}, // IT_INVULNERABILITY
|
||||
{ {255, 255, 0}, 30}, // IT_INVULNERABILITY
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 255, 0}, 20}, // IT_SUIT
|
||||
{ { 0, 0, 255}, 30}, // IT_QUAD
|
||||
{ { 0, 0, 255}, 30}, // IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
{ {255, 0, 255}, 30}, // IT_INVULNERABILITY | IT_QUAD
|
||||
};
|
||||
|
||||
#define sqr(x) ((x) * (x))
|
||||
|
||||
|
@ -116,20 +142,20 @@ V_CalcRoll (const vec3_t angles, vec4f_t velocity)
|
|||
}
|
||||
|
||||
static float
|
||||
V_CalcBob (void)
|
||||
V_CalcBob (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t velocity = cl.viewstate.velocity;
|
||||
vec4f_t velocity = vs->velocity;
|
||||
float cycle;
|
||||
static double bobtime;
|
||||
static float bob;
|
||||
|
||||
if (cl.spectator)
|
||||
if (!vs->bob_enabled)
|
||||
return 0;
|
||||
|
||||
if (cl.viewstate.onground == -1)
|
||||
if (vs->onground == -1)
|
||||
return bob; // just use old value
|
||||
|
||||
bobtime += cl.viewstate.frametime;
|
||||
bobtime += vs->frametime;
|
||||
cycle = bobtime - (int) (bobtime / cl_bobcycle->value) *
|
||||
cl_bobcycle->value;
|
||||
cycle /= cl_bobcycle->value;
|
||||
|
@ -151,31 +177,37 @@ V_CalcBob (void)
|
|||
}
|
||||
|
||||
void
|
||||
V_StartPitchDrift (void)
|
||||
V_StartPitchDrift (viewstate_t *vs)
|
||||
{
|
||||
if (cl.laststop == cl.time) {
|
||||
if (vs->laststop == vs->time) {
|
||||
return; // something else is keeping it from drifting
|
||||
}
|
||||
|
||||
if (cl.nodrift || !cl.pitchvel) {
|
||||
cl.pitchvel = v_centerspeed->value;
|
||||
cl.nodrift = false;
|
||||
cl.driftmove = 0;
|
||||
if (vs->nodrift || !vs->pitchvel) {
|
||||
vs->pitchvel = v_centerspeed->value;
|
||||
vs->nodrift = false;
|
||||
vs->driftmove = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
V_StopPitchDrift (void)
|
||||
static void
|
||||
V_StartPitchDrift_f (void *data)
|
||||
{
|
||||
cl.laststop = cl.time;
|
||||
cl.nodrift = true;
|
||||
cl.pitchvel = 0;
|
||||
V_StartPitchDrift (data);
|
||||
}
|
||||
|
||||
void
|
||||
V_StopPitchDrift (viewstate_t *vs)
|
||||
{
|
||||
vs->laststop = vs->time;
|
||||
vs->nodrift = true;
|
||||
vs->pitchvel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
V_DriftPitch
|
||||
|
||||
Moves the client pitch angle towards cl.idealpitch sent by the server.
|
||||
Moves the client pitch angle towards vs->idealpitch sent by the server.
|
||||
|
||||
If the user is adjusting pitch manually, either with lookup/lookdown,
|
||||
mlook and mouse, or klook and keyboard, pitch drifting is constantly
|
||||
|
@ -185,64 +217,64 @@ V_StopPitchDrift (void)
|
|||
and lookspring is non 0, or when
|
||||
*/
|
||||
static void
|
||||
V_DriftPitch (void)
|
||||
V_DriftPitch (viewstate_t *vs)
|
||||
{
|
||||
float delta, move;
|
||||
float forwardmove = cl.viewstate.movecmd[0];
|
||||
float forwardmove = vs->movecmd[0];
|
||||
|
||||
if (noclip_anglehack || cl.viewstate.onground == -1 || cls.demoplayback) {
|
||||
cl.driftmove = 0;
|
||||
cl.pitchvel = 0;
|
||||
if (noclip_anglehack || vs->onground == -1 || !vs->drift_enabled) {
|
||||
vs->driftmove = 0;
|
||||
vs->pitchvel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// don't count small mouse motion
|
||||
if (cl.nodrift) {
|
||||
if (vs->nodrift) {
|
||||
if (fabs (forwardmove) < cl_forwardspeed->value)
|
||||
cl.driftmove = 0;
|
||||
vs->driftmove = 0;
|
||||
else
|
||||
cl.driftmove += cl.viewstate.frametime;
|
||||
vs->driftmove += vs->frametime;
|
||||
|
||||
if (cl.driftmove > v_centermove->value) {
|
||||
V_StartPitchDrift ();
|
||||
if (vs->driftmove > v_centermove->value) {
|
||||
V_StartPitchDrift (vs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
delta = cl.idealpitch - cl.viewstate.angles[PITCH];
|
||||
delta = vs->idealpitch - vs->angles[PITCH];
|
||||
|
||||
if (!delta) {
|
||||
cl.pitchvel = 0;
|
||||
vs->pitchvel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
move = cl.viewstate.frametime * cl.pitchvel;
|
||||
cl.pitchvel += cl.viewstate.frametime * v_centerspeed->value;
|
||||
move = vs->frametime * vs->pitchvel;
|
||||
vs->pitchvel += vs->frametime * v_centerspeed->value;
|
||||
|
||||
if (delta > 0) {
|
||||
if (move > delta) {
|
||||
cl.pitchvel = 0;
|
||||
vs->pitchvel = 0;
|
||||
move = delta;
|
||||
}
|
||||
cl.viewstate.angles[PITCH] += move;
|
||||
vs->angles[PITCH] += move;
|
||||
} else if (delta < 0) {
|
||||
if (move > -delta) {
|
||||
cl.pitchvel = 0;
|
||||
vs->pitchvel = 0;
|
||||
move = -delta;
|
||||
}
|
||||
cl.viewstate.angles[PITCH] -= move;
|
||||
vs->angles[PITCH] -= move;
|
||||
}
|
||||
}
|
||||
|
||||
/* PALETTE FLASHES */
|
||||
|
||||
void
|
||||
V_ParseDamage (void)
|
||||
V_ParseDamage (viewstate_t *vs)
|
||||
{
|
||||
float count, side;
|
||||
int armor, blood;
|
||||
vec4f_t origin = cl.viewstate.origin;
|
||||
vec_t *angles = cl.viewstate.angles;
|
||||
vec4f_t origin = vs->origin;
|
||||
vec_t *angles = vs->angles;
|
||||
vec3_t from, forward, right, up;
|
||||
|
||||
armor = MSG_ReadByte (net_message);
|
||||
|
@ -253,31 +285,15 @@ V_ParseDamage (void)
|
|||
if (count < 10)
|
||||
count = 10;
|
||||
|
||||
cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame
|
||||
|
||||
if (cl_cshift_damage->int_val
|
||||
|| (cl.sv_cshifts & INFO_CSHIFT_DAMAGE)) {
|
||||
cshift_t *cshift = &cl.cshifts[CSHIFT_DAMAGE];
|
||||
|
||||
cshift->percent += 3 * count;
|
||||
cshift->percent =
|
||||
bound (0, cshift->percent, 150);
|
||||
|
||||
if (armor > blood) {
|
||||
cshift->destcolor[0] = 200;
|
||||
cshift->destcolor[1] = 100;
|
||||
cshift->destcolor[2] = 100;
|
||||
} else if (armor) {
|
||||
cshift->destcolor[0] = 220;
|
||||
cshift->destcolor[1] = 50;
|
||||
cshift->destcolor[2] = 50;
|
||||
} else {
|
||||
cshift->destcolor[0] = 255;
|
||||
cshift->destcolor[1] = 0;
|
||||
cshift->destcolor[2] = 0;
|
||||
}
|
||||
|| (vs->force_cshifts & INFO_CSHIFT_DAMAGE)) {
|
||||
cshift_t *cshift = &vs->cshifts[CSHIFT_DAMAGE];
|
||||
int percent = cshift->percent;
|
||||
*cshift = armor_blood[(2 * (armor > blood)) + (armor > 0)];
|
||||
cshift->percent = percent + 3 * count;
|
||||
cshift->percent = bound (0, cshift->percent, 150);
|
||||
cshift->initialpct = cshift->percent;
|
||||
cshift->time = cl.time;
|
||||
cshift->time = vs->time;
|
||||
}
|
||||
|
||||
// calculate view angle kicks
|
||||
|
@ -310,15 +326,16 @@ V_cshift_f (void)
|
|||
When you run over an item, the server sends this command
|
||||
*/
|
||||
static void
|
||||
V_BonusFlash_f (void)
|
||||
V_BonusFlash_f (void *data)
|
||||
{
|
||||
viewstate_t *vs = data;
|
||||
if (!cl_cshift_bonus->int_val
|
||||
&& !(cl.sv_cshifts & INFO_CSHIFT_BONUS))
|
||||
&& !(vs->force_cshifts & INFO_CSHIFT_BONUS))
|
||||
return;
|
||||
|
||||
cl.cshifts[CSHIFT_BONUS] = cshift_bonus;
|
||||
cl.cshifts[CSHIFT_BONUS].initialpct = cl.cshifts[CSHIFT_BONUS].percent;
|
||||
cl.cshifts[CSHIFT_BONUS].time = cl.time;
|
||||
vs->cshifts[CSHIFT_BONUS] = cshift_bonus;
|
||||
vs->cshifts[CSHIFT_BONUS].initialpct = vs->cshifts[CSHIFT_BONUS].percent;
|
||||
vs->cshifts[CSHIFT_BONUS].time = vs->time;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -327,69 +344,34 @@ V_BonusFlash_f (void)
|
|||
Underwater, lava, etc each has a color shift
|
||||
*/
|
||||
void
|
||||
V_SetContentsColor (int contents)
|
||||
V_SetContentsColor (viewstate_t *vs, int contents)
|
||||
{
|
||||
if (!cl_cshift_contents->int_val
|
||||
&& !(cl.sv_cshifts & INFO_CSHIFT_CONTENTS)) {
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
&& !(vs->force_cshifts & INFO_CSHIFT_CONTENTS)) {
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (contents) {
|
||||
case CONTENTS_EMPTY:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_empty;
|
||||
break;
|
||||
case CONTENTS_LAVA:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_lava;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_lava;
|
||||
break;
|
||||
case CONTENTS_SOLID:
|
||||
case CONTENTS_SLIME:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_slime;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_slime;
|
||||
break;
|
||||
default:
|
||||
cl.cshifts[CSHIFT_CONTENTS] = cshift_water;
|
||||
vs->cshifts[CSHIFT_CONTENTS] = cshift_water;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
V_CalcPowerupCshift (void)
|
||||
V_CalcPowerupCshift (viewstate_t *vs)
|
||||
{
|
||||
if (!cl.stats[STAT_ITEMS] & (IT_SUIT || IT_INVISIBILITY || IT_QUAD
|
||||
|| IT_INVULNERABILITY))
|
||||
{
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY &&
|
||||
cl.stats[STAT_ITEMS] & IT_QUAD) {
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 30;
|
||||
} else 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.stats[STAT_ITEMS] & IT_INVULNERABILITY) {
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255;
|
||||
cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0;
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 30;
|
||||
} 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.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 {
|
||||
cl.cshifts[CSHIFT_POWERUP].percent = 0;
|
||||
}
|
||||
vs->cshifts[CSHIFT_POWERUP] = powerup[vs->powerup_index];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -399,22 +381,22 @@ V_CalcPowerupCshift (void)
|
|||
a bit, but otherwise this is his code. --KB
|
||||
*/
|
||||
static void
|
||||
V_CalcBlend (void)
|
||||
V_CalcBlend (viewstate_t *vs)
|
||||
{
|
||||
float a2, a3;
|
||||
float r = 0, g = 0, b = 0, a = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CSHIFTS; i++) {
|
||||
a2 = cl.cshifts[i].percent / 255.0;
|
||||
a2 = vs->cshifts[i].percent / 255.0;
|
||||
|
||||
if (!a2)
|
||||
continue;
|
||||
|
||||
a2 = min (a2, 1.0);
|
||||
r += (cl.cshifts[i].destcolor[0] - r) * a2;
|
||||
g += (cl.cshifts[i].destcolor[1] - g) * a2;
|
||||
b += (cl.cshifts[i].destcolor[2] - b) * a2;
|
||||
r += (vs->cshifts[i].destcolor[0] - r) * a2;
|
||||
g += (vs->cshifts[i].destcolor[1] - g) * a2;
|
||||
b += (vs->cshifts[i].destcolor[2] - b) * a2;
|
||||
|
||||
a3 = (1.0 - a) * (1.0 - a2);
|
||||
a = 1.0 - a3;
|
||||
|
@ -435,12 +417,12 @@ V_CalcBlend (void)
|
|||
}
|
||||
|
||||
static void
|
||||
V_DropCShift (cshift_t *cs, float droprate)
|
||||
V_DropCShift (cshift_t *cs, double time, float droprate)
|
||||
{
|
||||
if (cs->time < 0) {
|
||||
cs->percent = 0;
|
||||
} else {
|
||||
cs->percent = cs->initialpct - (cl.time - cs->time) * droprate;
|
||||
cs->percent = cs->initialpct - (time - cs->time) * droprate;
|
||||
if (cs->percent <= 0) {
|
||||
cs->percent = 0;
|
||||
cs->time = -1;
|
||||
|
@ -449,56 +431,55 @@ V_DropCShift (cshift_t *cs, float droprate)
|
|||
}
|
||||
|
||||
void
|
||||
V_PrepBlend (void)
|
||||
V_PrepBlend (viewstate_t *vs)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (cl_cshift_powerup->int_val
|
||||
|| (cl.sv_cshifts & INFO_CSHIFT_POWERUP))
|
||||
V_CalcPowerupCshift ();
|
||||
|| (vs->force_cshifts & INFO_CSHIFT_POWERUP))
|
||||
V_CalcPowerupCshift (vs);
|
||||
|
||||
r_data->vid->cshift_changed = false;
|
||||
|
||||
for (i = 0; i < NUM_CSHIFTS; i++) {
|
||||
if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent) {
|
||||
if (vs->cshifts[i].percent != vs->prev_cshifts[i].percent) {
|
||||
r_data->vid->cshift_changed = true;
|
||||
cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
|
||||
vs->prev_cshifts[i].percent = vs->cshifts[i].percent;
|
||||
}
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
|
||||
if (vs->cshifts[i].destcolor[j] != vs->prev_cshifts[i].destcolor[j])
|
||||
{
|
||||
r_data->vid->cshift_changed = true;
|
||||
cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
|
||||
vs->prev_cshifts[i].destcolor[j] = vs->cshifts[i].destcolor[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drop the damage value
|
||||
V_DropCShift (&cl.cshifts[CSHIFT_DAMAGE], 150);
|
||||
V_DropCShift (&vs->cshifts[CSHIFT_DAMAGE], vs->time, 150);
|
||||
// drop the bonus value
|
||||
V_DropCShift (&cl.cshifts[CSHIFT_BONUS], 100);
|
||||
V_DropCShift (&vs->cshifts[CSHIFT_BONUS], vs->time, 100);
|
||||
|
||||
if (!r_data->vid->cshift_changed && !r_data->vid->recalc_refdef)
|
||||
return;
|
||||
|
||||
V_CalcBlend ();
|
||||
V_CalcBlend (vs);
|
||||
}
|
||||
|
||||
/* VIEW RENDERING */
|
||||
|
||||
static void
|
||||
CalcGunAngle (void)
|
||||
CalcGunAngle (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t rotation = r_data->refdef->viewrotation;
|
||||
//FIXME make child of camera
|
||||
Transform_SetWorldRotation (cl.viewent.transform, rotation);
|
||||
Transform_SetWorldRotation (vs->weapon_entity->transform, rotation);
|
||||
}
|
||||
|
||||
static void
|
||||
V_BoundOffsets (void)
|
||||
V_BoundOffsets (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t offset = r_data->refdef->viewposition
|
||||
- cl.viewstate.origin;
|
||||
vec4f_t offset = r_data->refdef->viewposition - vs->origin;
|
||||
|
||||
// absolutely bound refresh reletive to entity clipping hull
|
||||
// so the view can never be inside a solid wall
|
||||
|
@ -506,17 +487,17 @@ V_BoundOffsets (void)
|
|||
offset[0] = bound (-14, offset[0], 14);
|
||||
offset[1] = bound (-14, offset[1], 14);
|
||||
offset[2] = bound (-22, offset[2], 30);
|
||||
r_data->refdef->viewposition = cl.viewstate.origin + offset;
|
||||
r_data->refdef->viewposition = vs->origin + offset;
|
||||
}
|
||||
|
||||
static vec4f_t
|
||||
idle_quat (vec4f_t axis, cvar_t *cycle, cvar_t *level)
|
||||
idle_quat (vec4f_t axis, cvar_t *cycle, cvar_t *level, double time)
|
||||
{
|
||||
vec4f_t identity = { 0, 0, 0, 1 };
|
||||
if (!level || !cycle) {
|
||||
return identity;
|
||||
}
|
||||
float scale = sin (cl.time * cycle->value);
|
||||
float scale = sin (time * cycle->value);
|
||||
float ang = scale * level->value * v_idlescale->value;
|
||||
float c = cos (ang * M_PI / 360);
|
||||
float s = sin (ang * M_PI / 360);
|
||||
|
@ -529,14 +510,14 @@ idle_quat (vec4f_t axis, cvar_t *cycle, cvar_t *level)
|
|||
Idle swaying
|
||||
*/
|
||||
static void
|
||||
V_AddIdle (void)
|
||||
V_AddIdle (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t roll = idle_quat ((vec4f_t) { 1, 0, 0, 0},
|
||||
v_iroll_cycle, v_iroll_level);
|
||||
v_iroll_cycle, v_iroll_level, vs->time);
|
||||
vec4f_t pitch = idle_quat ((vec4f_t) { 0, 1, 0, 0},
|
||||
v_ipitch_cycle, v_ipitch_level);
|
||||
v_ipitch_cycle, v_ipitch_level, vs->time);
|
||||
vec4f_t yaw = idle_quat ((vec4f_t) { 0, 0, 1, 0},
|
||||
v_iyaw_cycle, v_iyaw_level);
|
||||
v_iyaw_cycle, v_iyaw_level, vs->time);
|
||||
vec4f_t rot = normalf (qmulf (yaw, qmulf (pitch, roll)));
|
||||
|
||||
// rotate the view
|
||||
|
@ -544,8 +525,8 @@ V_AddIdle (void)
|
|||
|
||||
// counter-rotate the weapon
|
||||
rot = qmulf (qconjf (rot),
|
||||
Transform_GetWorldRotation (cl.viewent.transform));
|
||||
Transform_SetWorldRotation (cl.viewent.transform, rot);
|
||||
Transform_GetWorldRotation (vs->weapon_entity->transform));
|
||||
Transform_SetWorldRotation (vs->weapon_entity->transform, rot);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -554,10 +535,10 @@ V_AddIdle (void)
|
|||
Roll is induced by movement and damage
|
||||
*/
|
||||
static void
|
||||
V_CalcViewRoll (void)
|
||||
V_CalcViewRoll (viewstate_t *vs)
|
||||
{
|
||||
vec_t *angles = cl.viewstate.angles;
|
||||
vec4f_t velocity = cl.viewstate.velocity;
|
||||
vec_t *angles = vs->angles;
|
||||
vec4f_t velocity = vs->velocity;
|
||||
vec3_t ang = { };
|
||||
|
||||
ang[ROLL] = V_CalcRoll (angles, velocity);
|
||||
|
@ -565,10 +546,10 @@ V_CalcViewRoll (void)
|
|||
if (v_dmg_time > 0) {
|
||||
ang[ROLL] += v_dmg_time / v_kicktime->value * v_dmg_roll;
|
||||
ang[PITCH] += v_dmg_time / v_kicktime->value * v_dmg_pitch;
|
||||
v_dmg_time -= cl.viewstate.frametime;
|
||||
v_dmg_time -= vs->frametime;
|
||||
}
|
||||
|
||||
if (cl.viewstate.flags & VF_DEAD) { // VF_GIB will also set VF_DEAD
|
||||
if (vs->flags & VF_DEAD) { // VF_GIB will also set VF_DEAD
|
||||
ang[ROLL] = 80; // dead view angle
|
||||
}
|
||||
|
||||
|
@ -578,17 +559,17 @@ V_CalcViewRoll (void)
|
|||
}
|
||||
|
||||
static void
|
||||
V_CalcIntermissionRefdef (void)
|
||||
V_CalcIntermissionRefdef (viewstate_t *vs)
|
||||
{
|
||||
// ent is the player model (visible when out of body)
|
||||
entity_t *ent = &cl_entities[cl.viewentity];
|
||||
// vs->player_entity is the player model (visible when out of body)
|
||||
entity_t *ent = vs->player_entity;
|
||||
entity_t *view;
|
||||
float old;
|
||||
vec4f_t origin = Transform_GetWorldPosition (ent->transform);
|
||||
vec4f_t rotation = Transform_GetWorldRotation (ent->transform);
|
||||
|
||||
// view is the weapon model (visible only from inside body)
|
||||
view = &cl.viewent;
|
||||
view = vs->weapon_entity;
|
||||
|
||||
r_data->refdef->viewposition = origin;
|
||||
r_data->refdef->viewrotation = rotation;
|
||||
|
@ -597,37 +578,37 @@ V_CalcIntermissionRefdef (void)
|
|||
// always idle in intermission
|
||||
old = v_idlescale->value;
|
||||
Cvar_SetValue (v_idlescale, 1);
|
||||
V_AddIdle ();
|
||||
V_AddIdle (vs);
|
||||
Cvar_SetValue (v_idlescale, old);
|
||||
}
|
||||
|
||||
static void
|
||||
V_CalcRefdef (void)
|
||||
V_CalcRefdef (viewstate_t *vs)
|
||||
{
|
||||
// view is the weapon model (visible only from inside body)
|
||||
entity_t *view = &cl.viewent;
|
||||
entity_t *view = vs->weapon_entity;
|
||||
float bob;
|
||||
static float oldz = 0;
|
||||
vec4f_t forward = {}, right = {}, up = {};
|
||||
vec4f_t origin = cl.viewstate.origin;
|
||||
vec_t *viewangles = cl.viewstate.angles;
|
||||
vec4f_t origin = vs->origin;
|
||||
vec_t *viewangles = vs->angles;
|
||||
|
||||
V_DriftPitch ();
|
||||
V_DriftPitch (vs);
|
||||
|
||||
bob = V_CalcBob ();
|
||||
bob = V_CalcBob (vs);
|
||||
|
||||
// refresh position
|
||||
r_data->refdef->viewposition = origin;
|
||||
r_data->refdef->viewposition[2] += cl.viewheight + bob;
|
||||
r_data->refdef->viewposition[2] += vs->height + bob;
|
||||
|
||||
// never let it sit exactly on a node line, because a water plane can
|
||||
// disappear when viewed with the eye exactly on it.
|
||||
// server protocol specifies to only 1/8 pixel, so add 1/16 in each axis
|
||||
r_data->refdef->viewposition += (vec4f_t) { 1.0/16, 1.0/16, 1.0/16, 0};
|
||||
|
||||
AngleQuat (cl.viewstate.angles, &r_data->refdef->viewrotation[0]);//FIXME
|
||||
V_CalcViewRoll ();
|
||||
V_AddIdle ();
|
||||
AngleQuat (vs->angles, &r_data->refdef->viewrotation[0]);//FIXME
|
||||
V_CalcViewRoll (vs);
|
||||
V_AddIdle (vs);
|
||||
|
||||
// offsets
|
||||
//FIXME semi-duplicates AngleQuat (also, vec3_t vs vec4f_t)
|
||||
|
@ -635,18 +616,18 @@ V_CalcRefdef (void)
|
|||
|
||||
// don't allow cheats in multiplayer
|
||||
// FIXME check for dead
|
||||
if (cl.maxclients == 1) {
|
||||
if (vs->voffs_enabled) {
|
||||
r_data->refdef->viewposition += scr_ofsx->value * forward
|
||||
+ scr_ofsy->value * right
|
||||
+ scr_ofsz->value * up;
|
||||
}
|
||||
|
||||
V_BoundOffsets ();
|
||||
V_BoundOffsets (vs);
|
||||
|
||||
// set up gun position
|
||||
CalcGunAngle ();
|
||||
CalcGunAngle (vs);
|
||||
|
||||
origin += (vec4f_t) { 0, 0, cl.viewheight, 0 };
|
||||
origin += (vec4f_t) { 0, 0, vs->height, 0 };
|
||||
origin += forward * bob * 0.4f + (vec4f_t) { 0, 0, bob, 0 };
|
||||
|
||||
// fudge position around to keep amount of weapon visible
|
||||
|
@ -663,26 +644,26 @@ V_CalcRefdef (void)
|
|||
origin += (vec4f_t) { 0, 0, 0.5, 0};
|
||||
}
|
||||
|
||||
model_t *model = cl.model_precache[cl.stats[STAT_WEAPON]];
|
||||
if (cl.viewstate.flags & (VF_GIB | VF_DEAD)) {
|
||||
model_t *model = vs->weapon_model;
|
||||
if (vs->flags & (VF_GIB | VF_DEAD)) {
|
||||
model = NULL;
|
||||
}
|
||||
if (view->renderer.model != model) {
|
||||
view->animation.pose2 = -1;
|
||||
}
|
||||
view->renderer.model = model;
|
||||
view->animation.frame = cl.viewstate.weaponframe;
|
||||
view->animation.frame = vs->weaponframe;
|
||||
view->renderer.skin = 0;
|
||||
|
||||
// set up the refresh position
|
||||
r_data->refdef->viewrotation = qmulf (cl.viewstate.punchangle,
|
||||
r_data->refdef->viewrotation = qmulf (vs->punchangle,
|
||||
r_data->refdef->viewrotation);
|
||||
|
||||
// smooth out stair step ups
|
||||
if ((cl.viewstate.onground != -1) && (origin[2] - oldz > 0)) {
|
||||
if ((vs->onground != -1) && (origin[2] - oldz > 0)) {
|
||||
float steptime;
|
||||
|
||||
steptime = cl.viewstate.frametime;
|
||||
steptime = vs->frametime;
|
||||
|
||||
oldz += steptime * 80;
|
||||
if (oldz > origin[2])
|
||||
|
@ -700,29 +681,29 @@ V_CalcRefdef (void)
|
|||
CL_TransformEntity (view, 1, ang, origin);
|
||||
}
|
||||
|
||||
if (cl.chase && chase_active->int_val) {
|
||||
Chase_Update (&cl.chasestate);
|
||||
if (vs->chase && chase_active->int_val) {
|
||||
Chase_Update (vs->chasestate);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DropPunchAngle (void)
|
||||
DropPunchAngle (viewstate_t *vs)
|
||||
{
|
||||
vec4f_t punch = cl.viewstate.punchangle;
|
||||
vec4f_t punch = vs->punchangle;
|
||||
float ps = magnitude3f (punch)[0];
|
||||
if (ps < 1e-3) {
|
||||
// < 0.2 degree rotation, not worth worrying about
|
||||
//ensure the quaternion is normalized
|
||||
cl.viewstate.punchangle = (vec4f_t) { 0, 0, 0, 1 };
|
||||
vs->punchangle = (vec4f_t) { 0, 0, 0, 1 };
|
||||
return;
|
||||
}
|
||||
float pc = punch[3];
|
||||
float ds = 0.0871557427 * cl.viewstate.frametime;
|
||||
float ds = 0.0871557427 * vs->frametime;
|
||||
float dc = sqrt (1 - ds * ds);
|
||||
float s = ps * dc - pc * ds;
|
||||
float c = pc * dc + ps * ds;
|
||||
if (s <= 0 || c >= 1) {
|
||||
cl.viewstate.punchangle = (vec4f_t) { 0, 0, 0, 1 };
|
||||
vs->punchangle = (vec4f_t) { 0, 0, 0, 1 };
|
||||
} else {
|
||||
punch *= s / ps;
|
||||
punch[3] = c;
|
||||
|
@ -736,38 +717,29 @@ DropPunchAngle (void)
|
|||
the entity origin, so any view position inside that will be valid
|
||||
*/
|
||||
void
|
||||
V_RenderView (void)
|
||||
V_RenderView (viewstate_t *vs)
|
||||
{
|
||||
if (cls.state != ca_active) {
|
||||
if (!vs->active) {
|
||||
r_data->refdef->viewposition = (vec4f_t) { 0, 0, 0, 1 };
|
||||
r_data->refdef->viewrotation = (vec4f_t) { 0, 0, 0, 1 };
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.viewstate.flags & VF_GIB) {
|
||||
cl.viewheight = 8; // gib view height
|
||||
} else if (cl.viewstate.flags & VF_DEAD) {
|
||||
cl.viewheight = -16; // corpse view height
|
||||
DropPunchAngle (vs);
|
||||
if (vs->intermission) { // intermission / finale rendering
|
||||
V_CalcIntermissionRefdef (vs);
|
||||
} else {
|
||||
cl.viewheight = DEFAULT_VIEWHEIGHT; // view height
|
||||
if (cl.stdver)
|
||||
cl.viewheight = cl.stats[STAT_VIEWHEIGHT];
|
||||
}
|
||||
|
||||
DropPunchAngle ();
|
||||
if (cl.intermission) { // intermission / finale rendering
|
||||
V_CalcIntermissionRefdef ();
|
||||
} else {
|
||||
V_CalcRefdef ();
|
||||
V_CalcRefdef (vs);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
V_Init (void)
|
||||
{
|
||||
Cmd_AddCommand ("bf", V_BonusFlash_f, "Background flash, used when you "
|
||||
"pick up an item");
|
||||
Cmd_AddCommand ("centerview", V_StartPitchDrift, "Centers the player's "
|
||||
Cmd_AddDataCommand ("bf", V_BonusFlash_f, &cl.viewstate,
|
||||
"Background flash, used when you pick up an item");
|
||||
Cmd_AddDataCommand ("centerview", V_StartPitchDrift_f, &cl.viewstate,
|
||||
"Centers the player's "
|
||||
"view ahead after +lookup or +lookdown\n"
|
||||
"Will not work while mlook is active or freelook is 1.");
|
||||
Cmd_AddCommand ("v_cshift", V_cshift_f, "This adjusts all of the colors "
|
||||
|
|
Loading…
Reference in a new issue