]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/gamec/cl_physics.c
implemented reduced speed movement while crouching (strange that this wasn't already...
[divverent/nexuiz.git] / qcsrc / gamec / cl_physics.c
1 float sv_accelerate;
2 float sv_maxairspeed;
3 float sv_friction;
4 float sv_maxspeed;
5 float sv_stopspeed;
6 float sv_gravity;
7 .float ladder_time;
8 .entity ladder_entity;
9 .float gravity;
10
11 void SV_PlayerPhysics()
12 {
13         local vector wishvel, wishdir, v;
14         local float wishspeed, f;
15
16         if (self.movetype == MOVETYPE_NONE)
17                 return;
18
19         if (self.punchangle != '0 0 0')
20         {
21                 f = vlen(self.punchangle) - 10 * frametime;
22                 if (f > 0)
23                         self.punchangle = normalize(self.punchangle) * f;
24                 else
25                         self.punchangle = '0 0 0';
26         }
27
28         if (self.punchvector != '0 0 0')
29         {
30                 f = vlen(self.punchvector) - 30 * frametime;
31                 if (f > 0)
32                         self.punchvector = normalize(self.punchvector) * f;
33                 else
34                         self.punchvector = '0 0 0';
35         }
36
37         // if dead, behave differently
38         if (self.deadflag)
39                 return;
40
41         if (!self.fixangle)
42         {
43                 self.angles_x = 0;
44                 self.angles_y = self.v_angle_y;
45                 self.angles_z = 0;
46         }
47
48         if (self.flags & FL_WATERJUMP )
49         {
50                 self.velocity_x = self.movedir_x;
51                 self.velocity_y = self.movedir_y;
52                 if (time > self.teleport_time || self.waterlevel == 0)
53                 {
54                         self.flags = self.flags - (self.flags & FL_WATERJUMP);
55                         self.teleport_time = 0;
56                 }
57         }
58         else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY)
59         {
60                 // noclipping or flying
61                 self.velocity = self.velocity * (1 - frametime * sv_friction);
62                 makevectors(self.v_angle);
63                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
64                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
65                 // acceleration
66                 wishdir = normalize(wishvel);
67                 wishspeed = vlen(wishvel);
68                 if (wishspeed > sv_maxspeed)
69                         wishspeed = sv_maxspeed;
70                 if (time >= self.teleport_time)
71                 {
72                         f = wishspeed - (self.velocity * wishdir);
73                         if (f > 0)
74                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
75                 }
76         }
77         else if (self.waterlevel >= 2)
78         {
79                 // swimming
80                 makevectors(self.v_angle);
81                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
82                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
83                 if (wishvel == '0 0 0')
84                         wishvel = '0 0 -60'; // drift towards bottom
85
86                 wishdir = normalize(wishvel);
87                 wishspeed = vlen(wishvel);
88                 if (wishspeed > sv_maxspeed)
89                         wishspeed = sv_maxspeed;
90                 wishspeed = wishspeed * 0.7;
91
92                 // water friction
93                 self.velocity = self.velocity * (1 - frametime * sv_friction);
94
95                 // water acceleration
96                 f = wishspeed - (self.velocity * wishdir);
97                 if (f > 0)
98                         self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
99         }
100         else if (time < self.ladder_time)
101         {
102                 // on a func_ladder or swimming in func_water
103                 self.velocity = self.velocity * (1 - frametime * sv_friction);
104                 makevectors(self.v_angle);
105                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
106                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
107                 if (self.gravity)
108                         self.velocity_z = self.velocity_z + self.gravity * sv_gravity * frametime;
109                 else
110                         self.velocity_z = self.velocity_z + sv_gravity * frametime;
111                 if (self.ladder_entity.classname == "func_water")
112                 {
113                         f = vlen(wishvel);
114                         if (f > self.ladder_entity.speed)
115                                 wishvel = wishvel * (self.ladder_entity.speed / f);
116
117                         self.watertype = self.ladder_entity.skin;
118                         f = self.ladder_entity.origin_z + self.ladder_entity.maxs_z;
119                         if ((self.origin_z + self.view_ofs_z) < f)
120                                 self.waterlevel = 3;
121                         else if ((self.origin_z + (self.mins_z + self.maxs_z) * 0.5) < f)
122                                 self.waterlevel = 2;
123                         else if ((self.origin_z + self.mins_z + 1) < f)
124                                 self.waterlevel = 1;
125                         else
126                         {
127                                 self.waterlevel = 0;
128                                 self.watertype = CONTENT_EMPTY;
129                         }
130                 }
131                 // acceleration
132                 wishdir = normalize(wishvel);
133                 wishspeed = vlen(wishvel);
134                 if (wishspeed > sv_maxspeed)
135                         wishspeed = sv_maxspeed;
136                 if (time >= self.teleport_time)
137                 {
138                         f = wishspeed - (self.velocity * wishdir);
139                         if (f > 0)
140                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
141                 }
142         }
143         else if (self.flags & FL_ONGROUND)
144         {
145                 // walking
146                 makevectors(self.v_angle_y * '0 1 0');
147                 wishvel = v_forward * self.movement_x + v_right * self.movement_y;
148                 // friction
149                 if (self.velocity_x || self.velocity_y)
150                 {
151                         v = self.velocity;
152                         v_z = 0;
153                         f = vlen(v);
154                         if (f < sv_stopspeed)
155                                 f = 1 - frametime * (sv_stopspeed / f) * sv_friction;
156                         else
157                                 f = 1 - frametime * sv_friction;
158                         if (f > 0)
159                                 self.velocity = self.velocity * f;
160                         else
161                                 self.velocity = '0 0 0';
162                 }
163                 // acceleration
164                 wishdir = normalize(wishvel);
165                 wishspeed = vlen(wishvel);
166                 if (wishspeed > sv_maxspeed)
167                         wishspeed = sv_maxspeed;
168                 if (self.button5) // crouch
169                         wishspeed = wishspeed * 0.5;
170                 if (time >= self.teleport_time)
171                 {
172                         f = wishspeed - (self.velocity * wishdir);
173                         if (f > 0)
174                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
175                 }
176         }
177         else
178         {
179                 // airborn
180                 makevectors(self.v_angle_y * '0 1 0');
181                 wishvel = v_forward * self.movement_x + v_right * self.movement_y;
182                 // acceleration
183                 wishdir = normalize(wishvel);
184                 wishspeed = vlen(wishvel);
185                 if (wishspeed > sv_maxairspeed)
186                         wishspeed = sv_maxairspeed;
187                 if (self.button5) // crouch
188                         wishspeed = wishspeed * 0.5;
189                 if (time >= self.teleport_time)
190                 {
191                         f = wishspeed;// - (self.velocity * wishdir);
192                         if (f > 0)
193                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
194                 }
195         }
196 };