mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Apply Seth Galbraith's <sgalbrai@linknet.kitsap.lib.wa.us> chasecam patch
This commit is contained in:
parent
e892131af5
commit
c78edb3a36
7 changed files with 567 additions and 27 deletions
|
@ -37,6 +37,22 @@ static const char rcsid[] =
|
|||
#include "client.h"
|
||||
#include "world.h"
|
||||
|
||||
#include "QF/keys.h"
|
||||
#include "QF/input.h"
|
||||
|
||||
float CL_KeyState (kbutton_t *key);
|
||||
|
||||
vec3_t camera_origin = {0,0,0};
|
||||
vec3_t camera_angles = {0,0,0};
|
||||
vec3_t player_origin = {0,0,0};
|
||||
vec3_t player_angles = {0,0,0};
|
||||
|
||||
extern kbutton_t in_mlook, in_klook;
|
||||
extern kbutton_t in_left, in_right, in_forward, in_back;
|
||||
extern kbutton_t in_lookup, in_lookdown;
|
||||
extern kbutton_t in_moveleft, in_moveright;
|
||||
extern kbutton_t in_strafe, in_speed;
|
||||
|
||||
qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
||||
vec3_t p1, vec3_t p2, trace_t *trace);
|
||||
|
||||
|
@ -78,38 +94,167 @@ TraceLine (vec3_t start, vec3_t end, vec3_t impact)
|
|||
VectorCopy (trace.endpos, impact);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Chase_Update
|
||||
==================
|
||||
*/
|
||||
void
|
||||
Chase_Update (void)
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
vec3_t forward, up, right;
|
||||
vec3_t dest, stop;
|
||||
vec3_t forward, up, right, stop, dir;
|
||||
float pitch, yaw, fwd;
|
||||
usercmd_t cmd; // movement direction
|
||||
int i;
|
||||
|
||||
// lazy camera, look toward player entity
|
||||
|
||||
if (chase_active->int_val == 2 || chase_active->int_val == 3)
|
||||
{
|
||||
// control camera angles with key/mouse/joy-look
|
||||
|
||||
camera_angles[PITCH] += cl.viewangles[PITCH] - player_angles[PITCH];
|
||||
camera_angles[YAW] += cl.viewangles[YAW] - player_angles[YAW];
|
||||
camera_angles[ROLL] += cl.viewangles[ROLL] - player_angles[ROLL];
|
||||
|
||||
if (chase_active->int_val == 2)
|
||||
{
|
||||
if (camera_angles[PITCH] < -60) camera_angles[PITCH] = -60;
|
||||
if (camera_angles[PITCH] > 60) camera_angles[PITCH] = 60;
|
||||
}
|
||||
|
||||
// move camera, it's not enough to just change the angles because
|
||||
// the angles are automatically changed to look toward the player
|
||||
|
||||
if (chase_active->int_val == 3)
|
||||
VectorCopy (r_refdef.vieworg, player_origin);
|
||||
|
||||
AngleVectors (camera_angles, forward, right, up);
|
||||
VectorScale (forward, chase_back->value, forward);
|
||||
VectorSubtract (player_origin, forward, camera_origin);
|
||||
|
||||
if (chase_active->int_val == 2)
|
||||
{
|
||||
VectorCopy (r_refdef.vieworg, player_origin);
|
||||
|
||||
// don't let camera get too low
|
||||
if (camera_origin[2] < player_origin[2] + chase_up->value)
|
||||
camera_origin[2] = player_origin[2] + chase_up->value;
|
||||
}
|
||||
|
||||
// don't let camera get too far from player
|
||||
|
||||
VectorSubtract (camera_origin, player_origin, dir);
|
||||
VectorCopy (dir, forward);
|
||||
VectorNormalize (forward);
|
||||
|
||||
if (Length (dir) > chase_back->value)
|
||||
{
|
||||
VectorScale (forward, chase_back->value, dir);
|
||||
VectorAdd (player_origin, dir, camera_origin);
|
||||
}
|
||||
|
||||
// check for walls between player and camera
|
||||
|
||||
VectorScale (forward, 8, forward);
|
||||
VectorAdd (camera_origin, forward, camera_origin);
|
||||
TraceLine (player_origin, camera_origin, stop);
|
||||
if (Length (stop) != 0)
|
||||
VectorSubtract (stop, forward, camera_origin);
|
||||
|
||||
VectorSubtract (camera_origin, r_refdef.vieworg, dir);
|
||||
VectorCopy (dir, forward);
|
||||
VectorNormalize (forward);
|
||||
|
||||
if (chase_active->int_val == 2)
|
||||
{
|
||||
if (dir[1] == 0 && dir[0] == 0)
|
||||
{
|
||||
// look straight up or down
|
||||
// camera_angles[YAW] = r_refdef.viewangles[YAW];
|
||||
if (dir[2] > 0) camera_angles[PITCH] = 90;
|
||||
else camera_angles[PITCH] = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = (atan2 (dir[1], dir[0]) * 180 / M_PI);
|
||||
if (yaw < 0) yaw += 360;
|
||||
if (yaw < 180) yaw += 180;
|
||||
else yaw -= 180;
|
||||
camera_angles[YAW] = yaw;
|
||||
|
||||
fwd = sqrt (dir[0] * dir[0] + dir[1] * dir[1]);
|
||||
pitch = (atan2 (dir[2], fwd) * 180 / M_PI);
|
||||
if (pitch < 0) pitch += 360;
|
||||
camera_angles[PITCH] = pitch;
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy (camera_angles, r_refdef.viewangles); // rotate camera
|
||||
VectorCopy (camera_origin, r_refdef.vieworg); // move camera
|
||||
|
||||
// get basic movement from keyboard
|
||||
|
||||
memset (&cmd, 0, sizeof (cmd));
|
||||
// VectorCopy (cl.viewangles, cmd.angles);
|
||||
|
||||
if (in_strafe.state & 1) {
|
||||
cmd.sidemove += cl_sidespeed->value * CL_KeyState (&in_right);
|
||||
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);
|
||||
|
||||
if (!(in_klook.state & 1)) {
|
||||
cmd.forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward);
|
||||
cmd.forwardmove -= cl_backspeed->value * CL_KeyState (&in_back);
|
||||
}
|
||||
if (in_speed.state & 1) {
|
||||
cmd.forwardmove *= cl_movespeedkey->value;
|
||||
cmd.sidemove *= cl_movespeedkey->value;
|
||||
}
|
||||
|
||||
// mouse and joystick controllers add to movement
|
||||
// IN_Move (&cmd); // problem - mouse strafe movement is weird
|
||||
|
||||
dir[1] = camera_angles[1]; dir[0] = 0; dir[2] = 0;
|
||||
AngleVectors (dir, forward, right, up);
|
||||
|
||||
VectorScale (forward, cmd.forwardmove, forward);
|
||||
VectorScale (right, cmd.sidemove, right);
|
||||
VectorAdd (forward, right, dir);
|
||||
|
||||
if (dir[1] || dir[0])
|
||||
{
|
||||
cl.viewangles[YAW] = (atan2 (dir[1], dir[0]) * 180 / M_PI);
|
||||
if (cl.viewangles[YAW] < 0) cl.viewangles[YAW] += 360;
|
||||
// if (cl.viewangles[YAW] < 180) cl.viewangles[YAW] += 180;
|
||||
// else cl.viewangles[YAW] -= 180;
|
||||
}
|
||||
|
||||
cl.viewangles[PITCH] = 0;
|
||||
|
||||
// remember the new angle to calculate the difference next frame
|
||||
VectorCopy (cl.viewangles, player_angles);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// regular camera, faces same direction as player
|
||||
|
||||
// if can't see player, reset
|
||||
AngleVectors (cl.viewangles, forward, right, up);
|
||||
|
||||
// calc exact destination
|
||||
for (i = 0; i < 3; i++)
|
||||
chase_dest[i] = r_refdef.vieworg[i]
|
||||
camera_origin[i] = r_refdef.vieworg[i]
|
||||
- forward[i] * chase_back->value - right[i] * chase_right->value;
|
||||
chase_dest[2] = r_refdef.vieworg[2] + chase_up->value;
|
||||
camera_origin[2] = r_refdef.vieworg[2] + chase_up->value;
|
||||
|
||||
// find the spot the player is looking at
|
||||
VectorMA (r_refdef.vieworg, 4096, forward, dest);
|
||||
TraceLine (r_refdef.vieworg, dest, stop);
|
||||
|
||||
// calculate pitch to look at the same spot from camera
|
||||
VectorSubtract (stop, r_refdef.vieworg, stop);
|
||||
dist = DotProduct (stop, forward);
|
||||
if (dist < 1)
|
||||
dist = 1;
|
||||
r_refdef.viewangles[PITCH] = -atan (stop[2] / dist) / M_PI * 180;
|
||||
|
||||
TraceLine (r_refdef.vieworg, chase_dest, stop);
|
||||
// check for walls between player and camera
|
||||
TraceLine (r_refdef.vieworg, camera_origin, stop);
|
||||
if (Length (stop) != 0)
|
||||
VectorCopy (stop, chase_dest);
|
||||
for (i = 0; i < 3; i++)
|
||||
camera_origin[i] = stop[i] + forward[i] * 8;
|
||||
|
||||
// move towards destination
|
||||
VectorCopy (chase_dest, r_refdef.vieworg);
|
||||
VectorCopy (camera_origin, r_refdef.vieworg);
|
||||
}
|
||||
|
|
|
@ -459,6 +459,8 @@ CL_AdjustAngles (void)
|
|||
|
||||
}
|
||||
|
||||
extern cvar_t *chase_active;
|
||||
|
||||
/*
|
||||
CL_BaseMove
|
||||
|
||||
|
@ -505,6 +507,21 @@ CL_BaseMove (usercmd_t *cmd)
|
|||
|
||||
IN_Move ();
|
||||
|
||||
// adjust for chase camera angles
|
||||
if (chase_active->int_val == 2 || chase_active->int_val == 3)
|
||||
{
|
||||
vec3_t dir = {0,0,0}, forward, right, up;
|
||||
dir[1] = r_refdef.viewangles[1] - cl.viewangles[1];
|
||||
AngleVectors (dir, forward, right, up);
|
||||
|
||||
VectorScale (forward, cmd->forwardmove, forward);
|
||||
VectorScale (right, cmd->sidemove, right);
|
||||
VectorAdd (forward, right, dir);
|
||||
|
||||
cmd->forwardmove = dir[0];
|
||||
cmd->sidemove = dir[1];
|
||||
}
|
||||
|
||||
cmd->forwardmove += viewdelta.position[2] * m_forward->value;
|
||||
cmd->sidemove += viewdelta.position[0] * m_side->value;
|
||||
cmd->upmove += viewdelta.position[1];
|
||||
|
|
|
@ -52,4 +52,6 @@ void CL_Cam_Init_Cvars(void);
|
|||
|
||||
void CL_ParseEntityLump(const char *entdata);
|
||||
|
||||
void Chase_Update (void);
|
||||
|
||||
#endif // _CL_CAM_H
|
||||
|
|
|
@ -61,6 +61,33 @@ static const char rcsid[] =
|
|||
#define BUTTON_ATTACK 1
|
||||
#define MAX_ANGLE_TURN 10
|
||||
|
||||
#include "QF/sys.h"
|
||||
#include "QF/keys.h"
|
||||
#include "QF/input.h"
|
||||
#include "QF/mathlib.h"
|
||||
#include "world.h"
|
||||
|
||||
float CL_KeyState (kbutton_t *key);
|
||||
|
||||
vec3_t camera_origin = {0,0,0};
|
||||
vec3_t camera_angles = {0,0,0};
|
||||
vec3_t player_origin = {0,0,0};
|
||||
vec3_t player_angles = {0,0,0};
|
||||
|
||||
extern kbutton_t in_mlook, in_klook;
|
||||
extern kbutton_t in_left, in_right, in_forward, in_back;
|
||||
extern kbutton_t in_lookup, in_lookdown;
|
||||
extern kbutton_t in_moveleft, in_moveright;
|
||||
extern kbutton_t in_strafe, in_speed;
|
||||
|
||||
qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
||||
vec3_t p1, vec3_t p2, trace_t *trace);
|
||||
|
||||
cvar_t *chase_back;
|
||||
cvar_t *chase_up;
|
||||
cvar_t *chase_right;
|
||||
cvar_t *chase_active;
|
||||
|
||||
static vec3_t desired_position; // where the camera wants to be
|
||||
static qboolean locked = false;
|
||||
static int oldbuttons;
|
||||
|
@ -119,6 +146,10 @@ vlen (vec3_t v)
|
|||
qboolean
|
||||
Cam_DrawViewModel (void)
|
||||
{
|
||||
if (atoi (Info_ValueForKey (cl.serverinfo, "chase"))
|
||||
&& chase_active->int_val)
|
||||
return false;
|
||||
|
||||
if (!cl.spectator)
|
||||
return true;
|
||||
|
||||
|
@ -131,6 +162,10 @@ Cam_DrawViewModel (void)
|
|||
qboolean
|
||||
Cam_DrawPlayer (int playernum)
|
||||
{
|
||||
if (atoi (Info_ValueForKey (cl.serverinfo, "chase")) == 0
|
||||
|| chase_active->int_val == 0)
|
||||
return false;
|
||||
|
||||
if (cl.spectator && autocam && locked && cl_chasecam->int_val &&
|
||||
spec_track == playernum)
|
||||
return false;
|
||||
|
@ -616,4 +651,312 @@ CL_Cam_Init_Cvars (void)
|
|||
cl_hightrack = Cvar_Get ("cl_hightrack", "0", CVAR_NONE, NULL, "view the "
|
||||
"player who has the most frags while you are in "
|
||||
"spectator mode.");
|
||||
|
||||
chase_back = Cvar_Get ("chase_back", "100", CVAR_NONE, NULL, "None");
|
||||
chase_up = Cvar_Get ("chase_up", "16", CVAR_NONE, NULL, "None");
|
||||
chase_right = Cvar_Get ("chase_right", "0", CVAR_NONE, NULL, "None");
|
||||
chase_active = Cvar_Get ("chase_active", "0", CVAR_NONE, NULL, "None");
|
||||
}
|
||||
|
||||
// 1/32 epsilon to keep floating point happy
|
||||
#define DIST_EPSILON (0.03125)
|
||||
|
||||
qboolean
|
||||
SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1,
|
||||
vec3_t p2, trace_t *trace)
|
||||
{
|
||||
dclipnode_t *node;
|
||||
mplane_t *plane;
|
||||
float t1, t2;
|
||||
float frac;
|
||||
int i;
|
||||
vec3_t mid;
|
||||
int side;
|
||||
float midf;
|
||||
|
||||
// check for empty
|
||||
if (num < 0) {
|
||||
if (num != CONTENTS_SOLID) {
|
||||
trace->allsolid = false;
|
||||
if (num == CONTENTS_EMPTY)
|
||||
trace->inopen = true;
|
||||
else
|
||||
trace->inwater = true;
|
||||
} else
|
||||
trace->startsolid = true;
|
||||
return true; // empty
|
||||
}
|
||||
|
||||
if (num < hull->firstclipnode || num > hull->lastclipnode)
|
||||
Sys_Error ("SV_RecursiveHullCheck: bad node number");
|
||||
|
||||
// find the point distances
|
||||
node = hull->clipnodes + num;
|
||||
plane = hull->planes + node->planenum;
|
||||
|
||||
if (plane->type < 3) {
|
||||
t1 = p1[plane->type] - plane->dist;
|
||||
t2 = p2[plane->type] - plane->dist;
|
||||
} else {
|
||||
t1 = DotProduct (plane->normal, p1) - plane->dist;
|
||||
t2 = DotProduct (plane->normal, p2) - plane->dist;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (t1 >= 0 && t2 >= 0)
|
||||
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
|
||||
p2, trace);
|
||||
if (t1 < 0 && t2 < 0)
|
||||
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
|
||||
p2, trace);
|
||||
#else
|
||||
if ((t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0))
|
||||
return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1,
|
||||
p2, trace);
|
||||
if ((t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0))
|
||||
return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1,
|
||||
p2, trace);
|
||||
#endif
|
||||
|
||||
// put the crosspoint DIST_EPSILON pixels on the near side
|
||||
if (t1 < 0)
|
||||
frac = (t1 + DIST_EPSILON) / (t1 - t2);
|
||||
else
|
||||
frac = (t1 - DIST_EPSILON) / (t1 - t2);
|
||||
if (frac < 0)
|
||||
frac = 0;
|
||||
if (frac > 1)
|
||||
frac = 1;
|
||||
|
||||
midf = p1f + (p2f - p1f) * frac;
|
||||
for (i = 0; i < 3; i++)
|
||||
mid[i] = p1[i] + frac * (p2[i] - p1[i]);
|
||||
|
||||
side = (t1 < 0);
|
||||
|
||||
// move up to the node
|
||||
if (!SV_RecursiveHullCheck
|
||||
(hull, node->children[side], p1f, midf, p1, mid, trace)) return false;
|
||||
|
||||
#ifdef PARANOID
|
||||
if (SV_HullPointContents (sv_hullmodel, mid, node->children[side])
|
||||
== CONTENTS_SOLID) {
|
||||
Sys_Printf ("mid PointInHullSolid\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SV_HullPointContents (hull, node->children[side ^ 1], mid)
|
||||
!= CONTENTS_SOLID)
|
||||
// go past the node
|
||||
return SV_RecursiveHullCheck (hull, node->children[side ^ 1], midf,
|
||||
p2f, mid, p2, trace);
|
||||
|
||||
if (trace->allsolid)
|
||||
return false; // never got out of the solid area
|
||||
|
||||
// the other side of the node is solid, this is the impact point
|
||||
if (!side) {
|
||||
VectorCopy (plane->normal, trace->plane.normal);
|
||||
trace->plane.dist = plane->dist;
|
||||
} else {
|
||||
VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
|
||||
trace->plane.dist = -plane->dist;
|
||||
}
|
||||
|
||||
while (SV_HullPointContents (hull, hull->firstclipnode, mid)
|
||||
== CONTENTS_SOLID) { // shouldn't really happen, but does
|
||||
// occasionally
|
||||
frac -= 0.1;
|
||||
if (frac < 0) {
|
||||
trace->fraction = midf;
|
||||
VectorCopy (mid, trace->endpos);
|
||||
Sys_Printf ("backup past 0\n");
|
||||
return false;
|
||||
}
|
||||
midf = p1f + (p2f - p1f) * frac;
|
||||
for (i = 0; i < 3; i++)
|
||||
mid[i] = p1[i] + frac * (p2[i] - p1[i]);
|
||||
}
|
||||
|
||||
trace->fraction = midf;
|
||||
VectorCopy (mid, trace->endpos);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TraceLine (vec3_t start, vec3_t end, vec3_t impact)
|
||||
{
|
||||
trace_t trace;
|
||||
|
||||
memset (&trace, 0, sizeof (trace));
|
||||
SV_RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &trace);
|
||||
|
||||
VectorCopy (trace.endpos, impact);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Chase_Update
|
||||
==================
|
||||
*/
|
||||
void
|
||||
Chase_Update (void)
|
||||
{
|
||||
vec3_t forward, up, right, stop, dir;
|
||||
float pitch, yaw, fwd;
|
||||
usercmd_t cmd; // movement direction
|
||||
int i;
|
||||
|
||||
// lazy camera, look toward player entity
|
||||
|
||||
if (chase_active->int_val == 2 || chase_active->int_val == 3)
|
||||
{
|
||||
// control camera angles with key/mouse/joy-look
|
||||
|
||||
camera_angles[PITCH] += cl.viewangles[PITCH] - player_angles[PITCH];
|
||||
camera_angles[YAW] += cl.viewangles[YAW] - player_angles[YAW];
|
||||
camera_angles[ROLL] += cl.viewangles[ROLL] - player_angles[ROLL];
|
||||
|
||||
if (chase_active->int_val == 2)
|
||||
{
|
||||
if (camera_angles[PITCH] < -60) camera_angles[PITCH] = -60;
|
||||
if (camera_angles[PITCH] > 60) camera_angles[PITCH] = 60;
|
||||
}
|
||||
|
||||
// move camera, it's not enough to just change the angles because
|
||||
// the angles are automatically changed to look toward the player
|
||||
|
||||
if (chase_active->int_val == 3)
|
||||
VectorCopy (r_refdef.vieworg, player_origin);
|
||||
|
||||
AngleVectors (camera_angles, forward, right, up);
|
||||
VectorScale (forward, chase_back->value, forward);
|
||||
VectorSubtract (player_origin, forward, camera_origin);
|
||||
|
||||
if (chase_active->int_val == 2)
|
||||
{
|
||||
VectorCopy (r_refdef.vieworg, player_origin);
|
||||
|
||||
// don't let camera get too low
|
||||
if (camera_origin[2] < player_origin[2] + chase_up->value)
|
||||
camera_origin[2] = player_origin[2] + chase_up->value;
|
||||
}
|
||||
|
||||
// don't let camera get too far from player
|
||||
|
||||
VectorSubtract (camera_origin, player_origin, dir);
|
||||
VectorCopy (dir, forward);
|
||||
VectorNormalize (forward);
|
||||
|
||||
if (Length (dir) > chase_back->value)
|
||||
{
|
||||
VectorScale (forward, chase_back->value, dir);
|
||||
VectorAdd (player_origin, dir, camera_origin);
|
||||
}
|
||||
|
||||
// check for walls between player and camera
|
||||
|
||||
VectorScale (forward, 8, forward);
|
||||
VectorAdd (camera_origin, forward, camera_origin);
|
||||
TraceLine (player_origin, camera_origin, stop);
|
||||
if (Length (stop) != 0)
|
||||
VectorSubtract (stop, forward, camera_origin);
|
||||
|
||||
VectorSubtract (camera_origin, r_refdef.vieworg, dir);
|
||||
VectorCopy (dir, forward);
|
||||
VectorNormalize (forward);
|
||||
|
||||
if (chase_active->int_val == 2)
|
||||
{
|
||||
if (dir[1] == 0 && dir[0] == 0)
|
||||
{
|
||||
// look straight up or down
|
||||
// camera_angles[YAW] = r_refdef.viewangles[YAW];
|
||||
if (dir[2] > 0) camera_angles[PITCH] = 90;
|
||||
else camera_angles[PITCH] = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = (atan2 (dir[1], dir[0]) * 180 / M_PI);
|
||||
if (yaw < 0) yaw += 360;
|
||||
if (yaw < 180) yaw += 180;
|
||||
else yaw -= 180;
|
||||
camera_angles[YAW] = yaw;
|
||||
|
||||
fwd = sqrt (dir[0] * dir[0] + dir[1] * dir[1]);
|
||||
pitch = (atan2 (dir[2], fwd) * 180 / M_PI);
|
||||
if (pitch < 0) pitch += 360;
|
||||
camera_angles[PITCH] = pitch;
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy (camera_angles, r_refdef.viewangles); // rotate camera
|
||||
VectorCopy (camera_origin, r_refdef.vieworg); // move camera
|
||||
|
||||
// get basic movement from keyboard
|
||||
|
||||
memset (&cmd, 0, sizeof (cmd));
|
||||
// VectorCopy (cl.viewangles, cmd.angles);
|
||||
|
||||
if (in_strafe.state & 1) {
|
||||
cmd.sidemove += cl_sidespeed->value * CL_KeyState (&in_right);
|
||||
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);
|
||||
|
||||
if (!(in_klook.state & 1)) {
|
||||
cmd.forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward);
|
||||
cmd.forwardmove -= cl_backspeed->value * CL_KeyState (&in_back);
|
||||
}
|
||||
if (in_speed.state & 1) {
|
||||
cmd.forwardmove *= cl_movespeedkey->value;
|
||||
cmd.sidemove *= cl_movespeedkey->value;
|
||||
}
|
||||
|
||||
// mouse and joystick controllers add to movement
|
||||
// IN_Move (&cmd); // problem - mouse strafe movement is weird
|
||||
|
||||
dir[1] = camera_angles[1]; dir[0] = 0; dir[2] = 0;
|
||||
AngleVectors (dir, forward, right, up);
|
||||
|
||||
VectorScale (forward, cmd.forwardmove, forward);
|
||||
VectorScale (right, cmd.sidemove, right);
|
||||
VectorAdd (forward, right, dir);
|
||||
|
||||
if (dir[1] || dir[0])
|
||||
{
|
||||
cl.viewangles[YAW] = (atan2 (dir[1], dir[0]) * 180 / M_PI);
|
||||
if (cl.viewangles[YAW] < 0) cl.viewangles[YAW] += 360;
|
||||
// if (cl.viewangles[YAW] < 180) cl.viewangles[YAW] += 180;
|
||||
// else cl.viewangles[YAW] -= 180;
|
||||
}
|
||||
|
||||
cl.viewangles[PITCH] = 0;
|
||||
|
||||
// remember the new angle to calculate the difference next frame
|
||||
VectorCopy (cl.viewangles, player_angles);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// regular camera, faces same direction as player
|
||||
|
||||
AngleVectors (cl.viewangles, forward, right, up);
|
||||
|
||||
// calc exact destination
|
||||
for (i = 0; i < 3; i++)
|
||||
camera_origin[i] = r_refdef.vieworg[i]
|
||||
- forward[i] * chase_back->value - right[i] * chase_right->value;
|
||||
camera_origin[2] = r_refdef.vieworg[2] + chase_up->value;
|
||||
|
||||
// check for walls between player and camera
|
||||
TraceLine (r_refdef.vieworg, camera_origin, stop);
|
||||
if (Length (stop) != 0)
|
||||
for (i = 0; i < 3; i++)
|
||||
camera_origin[i] = stop[i] + forward[i] * 8;
|
||||
|
||||
VectorCopy (camera_origin, r_refdef.vieworg);
|
||||
}
|
||||
|
|
|
@ -805,7 +805,7 @@ CL_LinkPlayers (void)
|
|||
// things (due to lack of lights?), so I'm leaving this as is for now.
|
||||
|
||||
// the player object never gets added
|
||||
if (j == cl.playernum) {
|
||||
if (j == cl.playernum && !Cam_DrawPlayer (j)) {
|
||||
r_player_entity = &cl_player_ents[state - frame->playerstate];
|
||||
continue;
|
||||
}
|
||||
|
@ -858,11 +858,18 @@ CL_LinkPlayers (void)
|
|||
(*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1;
|
||||
|
||||
// angles
|
||||
(*ent)->angles[PITCH] = -state->viewangles[PITCH] / 3;
|
||||
(*ent)->angles[YAW] = state->viewangles[YAW];
|
||||
if (j == cl.playernum)
|
||||
{
|
||||
(*ent)->angles[PITCH] = -cl.viewangles[PITCH] / 3;
|
||||
(*ent)->angles[YAW] = cl.viewangles[YAW];
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ent)->angles[PITCH] = -state->viewangles[PITCH] / 3;
|
||||
(*ent)->angles[YAW] = state->viewangles[YAW];
|
||||
}
|
||||
(*ent)->angles[ROLL] = 0;
|
||||
(*ent)->angles[ROLL] =
|
||||
V_CalcRoll ((*ent)->angles, state->velocity) * 4;
|
||||
(*ent)->angles[ROLL] = V_CalcRoll ((*ent)->angles, state->velocity) * 4;
|
||||
|
||||
// only predict half the move to minimize overruns
|
||||
msec = 500 * (playertime - state->state_time);
|
||||
|
|
|
@ -475,6 +475,8 @@ CL_AdjustAngles (void)
|
|||
|
||||
}
|
||||
|
||||
extern cvar_t *chase_active;
|
||||
|
||||
/*
|
||||
CL_BaseMove
|
||||
|
||||
|
@ -519,6 +521,22 @@ CL_BaseMove (usercmd_t *cmd)
|
|||
|
||||
IN_Move ();
|
||||
|
||||
// adjust for chase camera angles
|
||||
if (atoi (Info_ValueForKey (cl.serverinfo, "chase"))
|
||||
&& (chase_active->int_val == 2 || chase_active->int_val == 3))
|
||||
{
|
||||
vec3_t dir = {0,0,0}, forward, right, up;
|
||||
dir[1] = r_refdef.viewangles[1] - cl.viewangles[1];
|
||||
AngleVectors (dir, forward, right, up);
|
||||
|
||||
VectorScale (forward, cmd->forwardmove, forward);
|
||||
VectorScale (right, cmd->sidemove, right);
|
||||
VectorAdd (forward, right, dir);
|
||||
|
||||
cmd->forwardmove = dir[0];
|
||||
cmd->sidemove = dir[1];
|
||||
}
|
||||
|
||||
cmd->forwardmove += viewdelta.position[2] * m_forward->value;
|
||||
cmd->sidemove += viewdelta.position[0] * m_side->value;
|
||||
cmd->upmove += viewdelta.position[1];
|
||||
|
|
|
@ -619,6 +619,10 @@ V_CalcIntermissionRefdef (void)
|
|||
Cvar_SetValue (v_idlescale, old);
|
||||
}
|
||||
|
||||
#include "cl_cam.h"
|
||||
|
||||
extern cvar_t *chase_active;
|
||||
|
||||
void
|
||||
V_CalcRefdef (void)
|
||||
{
|
||||
|
@ -724,6 +728,10 @@ V_CalcRefdef (void)
|
|||
view->origin[2] += oldz - cl.simorg[2];
|
||||
} else
|
||||
oldz = cl.simorg[2];
|
||||
|
||||
if (atoi (Info_ValueForKey (cl.serverinfo, "chase"))
|
||||
&& chase_active->int_val)
|
||||
Chase_Update ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue