1cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
2cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichCopyright (C) 1996-1997 Id Software, Inc.
3cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
4cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichThis program is free software; you can redistribute it and/or
5cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichmodify it under the terms of the GNU General Public License
6cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichas published by the Free Software Foundation; either version 2
7cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichof the License, or (at your option) any later version.
8cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
9cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichThis program is distributed in the hope that it will be useful,
10cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichbut WITHOUT ANY WARRANTY; without even the implied warranty of
11cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
13cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSee the GNU General Public License for more details.
14cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
15cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichYou should have received a copy of the GNU General Public License
16cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichalong with this program; if not, write to the Free Software
17cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
19cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
20cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// sv_user.c -- server code for moving users
21cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
22cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#include "quakedef.h"
23cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
24cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichedict_t	*sv_player;
25cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
26cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichextern	cvar_t	sv_friction;
27cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichcvar_t	sv_edgefriction = CVAR2("edgefriction", "2");
28cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichextern	cvar_t	sv_stopspeed;
29cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
30cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichstatic	vec3_t		forward, right, up;
31cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
32cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvec3_t	wishdir;
33cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichfloat	wishspeed;
34cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
35cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// world
36cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichfloat	*angles;
37cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichfloat	*origin;
38cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichfloat	*velocity;
39cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
40cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichqboolean	onground;
41cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
42cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichusercmd_t	cmd;
43cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
44cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichcvar_t	sv_idealpitchscale = CVAR2("sv_idealpitchscale","0.8");
45cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
46cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
47cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
48cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===============
49cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_SetIdealPitch
50cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===============
51cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
52cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#define	MAX_FORWARD	6
53cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_SetIdealPitch (void)
54cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
55cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	angleval, sinval, cosval;
56cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	trace_t	tr;
57cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t	top, bottom;
58cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	z[MAX_FORWARD];
59cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		i, j;
60cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		step, dir, steps;
61cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
62cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!((int)sv_player->u.v.flags & FL_ONGROUND))
63cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
64cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
65cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	angleval = sv_player->u.v.angles[YAW] * M_PI*2 / 360;
66cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	sinval = sin(angleval);
67cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	cosval = cos(angleval);
68cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
69cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<MAX_FORWARD ; i++)
70cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
71cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		top[0] = sv_player->u.v.origin[0] + cosval*(i+3)*12;
72cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		top[1] = sv_player->u.v.origin[1] + sinval*(i+3)*12;
73cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		top[2] = sv_player->u.v.origin[2] + sv_player->u.v.view_ofs[2];
74cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
75cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		bottom[0] = top[0];
76cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		bottom[1] = top[1];
77cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		bottom[2] = top[2] - 160;
78cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
79cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		tr = SV_Move (top, vec3_origin, vec3_origin, bottom, 1, sv_player);
80cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (tr.allsolid)
81cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			return;	// looking at a wall, leave ideal the way is was
82cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
83cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (tr.fraction == 1)
84cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			return;	// near a dropoff
85cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
86cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		z[i] = top[2] + tr.fraction*(bottom[2]-top[2]);
87cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
88cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
89cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	dir = 0;
90cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	steps = 0;
91cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (j=1 ; j<i ; j++)
92cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
93cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		step = (int) (z[j] - z[j-1]);
94cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (step > -ON_EPSILON && step < ON_EPSILON)
95cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
96cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
97cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ) )
98cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			return;		// mixed changes
99cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
100cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		steps++;
101cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		dir = step;
102cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
103cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
104cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!dir)
105cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
106cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		sv_player->u.v.idealpitch = 0;
107cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
108cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
109cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
110cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (steps < 2)
111cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
112cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	sv_player->u.v.idealpitch = -dir * sv_idealpitchscale.value;
113cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
114cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
115cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
116cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
117cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==================
118cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_UserFriction
119cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
120cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==================
121cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
122cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_UserFriction (void)
123cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
124cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	*vel;
125cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	speed, newspeed, control;
126cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t	start, stop;
127cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	friction;
128cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	trace_t	trace;
129cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
130cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vel = velocity;
131cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
132cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
133cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!speed)
134cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
135cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
136cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// if the leading edge is over a dropoff, increase friction
137cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	start[0] = stop[0] = origin[0] + vel[0]/speed*16;
138cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	start[1] = stop[1] = origin[1] + vel[1]/speed*16;
139cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	start[2] = origin[2] + sv_player->u.v.mins[2];
140cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	stop[2] = start[2] - 34;
141cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
142cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player);
143cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
144cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (trace.fraction == 1.0)
145cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		friction = sv_friction.value*sv_edgefriction.value;
146cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	else
147cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		friction = sv_friction.value;
148cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
149cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// apply friction
150cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
151cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	newspeed = speed - host_frametime*control*friction;
152cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
153cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (newspeed < 0)
154cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		newspeed = 0;
155cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	newspeed /= speed;
156cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
157cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vel[0] = vel[0] * newspeed;
158cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vel[1] = vel[1] * newspeed;
159cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vel[2] = vel[2] * newspeed;
160cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
161cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
162cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
163cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==============
164cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_Accelerate
165cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==============
166cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
167cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichcvar_t	sv_maxspeed = CVAR4("sv_maxspeed", "320", false, true);
168cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichcvar_t	sv_accelerate = CVAR2("sv_accelerate", "10");
169cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#if 0
170cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_Accelerate (vec3_t wishvel)
171cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
172cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i;
173cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float		addspeed, accelspeed;
174cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t		pushvec;
175cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
176cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (wishspeed == 0)
177cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
178cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
179cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	VectorSubtract (wishvel, velocity, pushvec);
180cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	addspeed = VectorNormalize (pushvec);
181cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
182cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	accelspeed = sv_accelerate.value*host_frametime*addspeed;
183cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (accelspeed > addspeed)
184cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		accelspeed = addspeed;
185cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
186cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
187cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		velocity[i] += accelspeed*pushvec[i];
188cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
189cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#endif
190cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_Accelerate (void)
191cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
192cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i;
193cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float		addspeed, accelspeed, currentspeed;
194cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
195cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	currentspeed = DotProduct (velocity, wishdir);
196cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	addspeed = wishspeed - currentspeed;
197cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (addspeed <= 0)
198cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
199cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	accelspeed = sv_accelerate.value*host_frametime*wishspeed;
200cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (accelspeed > addspeed)
201cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		accelspeed = addspeed;
202cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
203cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
204cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		velocity[i] += accelspeed*wishdir[i];
205cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
206cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
207cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_AirAccelerate (vec3_t wishveloc)
208cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
209cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i;
210cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float		addspeed, wishspd, accelspeed, currentspeed;
211cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
212cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	wishspd = VectorNormalize (wishveloc);
213cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (wishspd > 30)
214cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishspd = 30;
215cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	currentspeed = DotProduct (velocity, wishveloc);
216cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	addspeed = wishspd - currentspeed;
217cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (addspeed <= 0)
218cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
219cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//	accelspeed = sv_accelerate.value * host_frametime;
220cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	accelspeed = sv_accelerate.value*wishspeed * host_frametime;
221cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (accelspeed > addspeed)
222cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		accelspeed = addspeed;
223cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
224cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
225cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		velocity[i] += accelspeed*wishveloc[i];
226cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
227cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
228cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
229cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid DropPunchAngle (void)
230cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
231cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	len;
232cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
233cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	len = VectorNormalize (sv_player->u.v.punchangle);
234cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
235cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	len -= 10*host_frametime;
236cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (len < 0)
237cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		len = 0;
238cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	VectorScale (sv_player->u.v.punchangle, len, sv_player->u.v.punchangle);
239cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
240cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
241cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
242cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
243cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_WaterMove
244cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
245cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
246cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
247cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_WaterMove (void)
248cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
249cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		i;
250cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t	wishvel;
251cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float	speed, newspeed, wishspeed, addspeed, accelspeed;
252cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
253cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
254cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// user intentions
255cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
256cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	AngleVectors (sv_player->u.v.v_angle, forward, right, up);
257cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
258cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
259cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove;
260cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
261cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove)
262cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishvel[2] -= 60;		// drift towards bottom
263cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	else
264cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishvel[2] += cmd.upmove;
265cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
266cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	wishspeed = Length(wishvel);
267cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (wishspeed > sv_maxspeed.value)
268cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
269cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
270cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishspeed = sv_maxspeed.value;
271cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
272cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	wishspeed *= 0.7;
273cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
274cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
275cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// water friction
276cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
277cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	speed = Length (velocity);
278cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (speed)
279cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
280cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		newspeed = speed - host_frametime * speed * sv_friction.value;
281cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (newspeed < 0)
282cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			newspeed = 0;
283cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		VectorScale (velocity, newspeed/speed, velocity);
284cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
285cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	else
286cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		newspeed = 0;
287cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
288cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
289cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// water acceleration
290cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
291cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!wishspeed)
292cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
293cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
294cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	addspeed = wishspeed - newspeed;
295cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (addspeed <= 0)
296cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
297cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
298cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	VectorNormalize (wishvel);
299cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	accelspeed = sv_accelerate.value * wishspeed * host_frametime;
300cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (accelspeed > addspeed)
301cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		accelspeed = addspeed;
302cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
303cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
304cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		velocity[i] += accelspeed * wishvel[i];
305cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
306cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
307cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_WaterJump (void)
308cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
309cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (sv.time > sv_player->u.v.teleport_time
310cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	|| !sv_player->u.v.waterlevel)
311cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
312cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		sv_player->u.v.flags = (int)sv_player->u.v.flags & ~FL_WATERJUMP;
313cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		sv_player->u.v.teleport_time = 0;
314cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
315cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	sv_player->u.v.velocity[0] = sv_player->u.v.movedir[0];
316cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	sv_player->u.v.velocity[1] = sv_player->u.v.movedir[1];
317cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
318cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
319cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
320cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
321cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
322cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_AirMove
323cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
324cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
325cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
326cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_AirMove (void)
327cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
328cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int			i;
329cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t		wishvel;
330cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	float		fmove, smove;
331cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
332cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	AngleVectors (sv_player->u.v.angles, forward, right, up);
333cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
334cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	fmove = cmd.forwardmove;
335cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	smove = cmd.sidemove;
336cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
337cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// hack to not let you back into teleporter
338cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (sv.time < sv_player->u.v.teleport_time && fmove < 0)
339cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		fmove = 0;
340cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
341cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
342cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishvel[i] = forward[i]*fmove + right[i]*smove;
343cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
344cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if ( (int)sv_player->u.v.movetype != MOVETYPE_WALK)
345cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishvel[2] = cmd.upmove;
346cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	else
347cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishvel[2] = 0;
348cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
349cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	VectorCopy (wishvel, wishdir);
350cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	wishspeed = VectorNormalize(wishdir);
351cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (wishspeed > sv_maxspeed.value)
352cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
353cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
354cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		wishspeed = sv_maxspeed.value;
355cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
356cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
357cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if ( sv_player->u.v.movetype == MOVETYPE_NOCLIP)
358cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{	// noclip
359cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		VectorCopy (wishvel, velocity);
360cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
361cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	else if ( onground )
362cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
363cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		SV_UserFriction ();
364cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		SV_Accelerate ();
365cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
366cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	else
367cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{	// not on ground, so little effect on velocity
368cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		SV_AirAccelerate (wishvel);
369cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
370cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
371cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
372cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
373cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
374cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_ClientThink
375cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
376cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichthe move fields specify an intended velocity in pix/sec
377cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichthe angle fields specify an exact angular motion in degrees
378cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
379cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
380cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_ClientThink (void)
381cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
382cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t		v_angle;
383cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
384cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (sv_player->u.v.movetype == MOVETYPE_NONE)
385cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
386cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
387cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	onground = (int)sv_player->u.v.flags & FL_ONGROUND;
388cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
389cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	origin = sv_player->u.v.origin;
390cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	velocity = sv_player->u.v.velocity;
391cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
392cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	DropPunchAngle ();
393cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
394cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
395cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// if dead, behave differently
396cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
397cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (sv_player->u.v.health <= 0)
398cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
399cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
400cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
401cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// angles
402cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// show 1/3 the pitch angle and all the roll angle
403cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	cmd = host_client->cmd;
404cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	angles = sv_player->u.v.angles;
405cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
406cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	VectorAdd (sv_player->u.v.v_angle, sv_player->u.v.punchangle, v_angle);
407cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	angles[ROLL] = V_CalcRoll (sv_player->u.v.angles, sv_player->u.v.velocity)*4;
408cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (!sv_player->u.v.fixangle)
409cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
410cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		angles[PITCH] = -v_angle[PITCH]/3;
411cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		angles[YAW] = v_angle[YAW];
412cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
413cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
414cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if ( (int)sv_player->u.v.flags & FL_WATERJUMP )
415cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
416cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		SV_WaterJump ();
417cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
418cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
419cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
420cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// walk
421cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
422cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if ( (sv_player->u.v.waterlevel >= 2)
423cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	&& (sv_player->u.v.movetype != MOVETYPE_NOCLIP) )
424cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
425cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		SV_WaterMove ();
426cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
427cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
428cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
429cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	SV_AirMove ();
430cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
431cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
432cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
433cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
434cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
435cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_ReadClientMove
436cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
437cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
438cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_ReadClientMove (usercmd_t *move)
439cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
440cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		i;
441cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	vec3_t	angle;
442cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		bits;
443cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
444cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// read ping time
445cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	host_client->ping_times[host_client->num_pings%NUM_PING_TIMES]
446cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		= sv.time - MSG_ReadFloat ();
447cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	host_client->num_pings++;
448cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
449cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// read current angles
450cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0 ; i<3 ; i++)
451cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		angle[i] = MSG_ReadAngle ();
452cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
453cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	VectorCopy (angle, host_client->edict->u.v.v_angle);
454cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
455cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// read movement
456cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	move->forwardmove = MSG_ReadShort ();
457cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	move->sidemove = MSG_ReadShort ();
458cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	move->upmove = MSG_ReadShort ();
459cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
460cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// read buttons
461cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	bits = MSG_ReadByte ();
462cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	host_client->edict->u.v.button0 = bits & 1;
463cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	host_client->edict->u.v.button2 = (bits & 2)>>1;
464cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
465cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	i = MSG_ReadByte ();
466cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (i)
467cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		host_client->edict->u.v.impulse = i;
468cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
469cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#ifdef QUAKE2
470cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// read light level
471cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	host_client->edict->u.v.light_level = MSG_ReadByte ();
472cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#endif
473cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
474cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
475cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
476cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
477cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_ReadClientMessage
478cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
479cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichReturns false if the client should be killed
480cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich===================
481cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
482cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichqboolean SV_ReadClientMessage (void)
483cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
484cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		ret;
485cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int		cmd;
486cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	char		*s;
487cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
488cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	do
489cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
490cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichnextmsg:
491cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		ret = NET_GetMessage (host_client->netconnection);
492cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (ret == -1)
493cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
494cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
495cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			return false;
496cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
497cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!ret)
498cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			return true;
499cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
500cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		MSG_BeginReading ();
501cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
502cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		while (1)
503cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
504cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			if (!host_client->active)
505cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				return false;	// a command caused an error
506cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
507cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			if (msg_badread)
508cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			{
509cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				Sys_Printf ("SV_ReadClientMessage: badread\n");
510cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				return false;
511cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			}
512cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
513cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			cmd = MSG_ReadChar ();
514cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
515cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			switch (cmd)
516cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			{
517cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			case -1:
518cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				goto nextmsg;		// end of message
519cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
520cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			default:
521cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
522cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				return false;
523cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
524cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			case clc_nop:
525cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//				Sys_Printf ("clc_nop\n");
526cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				break;
527cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
528cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			case clc_stringcmd:
529cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				s = MSG_ReadString ();
530cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				if (host_client->privileged)
531cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 2;
532cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else
533cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 0;
534cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				if (Q_strncasecmp(s, "status", 6) == 0)
535cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
536cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "god", 3) == 0)
537cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
538cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "notarget", 8) == 0)
539cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
540cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "fly", 3) == 0)
541cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
542cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "name", 4) == 0)
543cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
544cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "noclip", 6) == 0)
545cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
546cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "say", 3) == 0)
547cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
548cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "say_team", 8) == 0)
549cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
550cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "tell", 4) == 0)
551cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
552cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "color", 5) == 0)
553cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
554cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "kill", 4) == 0)
555cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
556cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "pause", 5) == 0)
557cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
558cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "spawn", 5) == 0)
559cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
560cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "begin", 5) == 0)
561cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
562cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "prespawn", 8) == 0)
563cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
564cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "kick", 4) == 0)
565cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
566cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "ping", 4) == 0)
567cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
568cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "give", 4) == 0)
569cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
570cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (Q_strncasecmp(s, "ban", 3) == 0)
571cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					ret = 1;
572cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				if (ret == 2)
573cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					Cbuf_InsertText (s);
574cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else if (ret == 1)
575cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					Cmd_ExecuteString (s, src_client);
576cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				else
577cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich					Con_DPrintf("%s tried to %s\n", host_client->name, s);
578cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				break;
579cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
580cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			case clc_disconnect:
581cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
582cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				return false;
583cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
584cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			case clc_move:
585cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				SV_ReadClientMove (&host_client->cmd);
586cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich				break;
587cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			}
588cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
589cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	} while (ret == 1);
590cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
591cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	return true;
592cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
593cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
594cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
595cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
596cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==================
597cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSV_RunClients
598cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich==================
599cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
600cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid SV_RunClients (void)
601cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
602cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	int				i;
603cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
604cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
605cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
606cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!host_client->active)
607cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
608cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
609cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		sv_player = host_client->edict;
610cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
611cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!SV_ReadClientMessage ())
612cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
613cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			SV_DropClient (false);	// client misbehaved...
614cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
615cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
616cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
617cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!host_client->spawned)
618cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		{
619cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		// clear client movement until a new packet is received
620cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			memset (&host_client->cmd, 0, sizeof(host_client->cmd));
621cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			continue;
622cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		}
623cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
624cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// always pause in single player if in console or menus
625cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
626cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich			SV_ClientThink ();
627cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
628cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
629cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
630