]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/movelib.qc
#include this
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / movelib.qc
1 #if defined(CSQC)
2     #include "../dpdefs/csprogsdefs.qc"
3 #elif defined(MENUQC)
4 #elif defined(SVQC)
5     #include "../dpdefs/progsdefs.qc"
6     #include "../dpdefs/dpextensions.qc"
7     #include "sys-post.qh"
8     #include "../csqcmodellib/sv_model.qh"
9 #endif
10
11 #ifdef SVQC
12 .vector moveto;
13
14 /**
15     Simulate drag
16     self.velocity = movelib_dragvec(self.velocity,0.02,0.5);
17 **/
18 vector movelib_dragvec(float drag, float exp_)
19 {
20     float lspeed,ldrag;
21
22     lspeed = vlen(self.velocity);
23     ldrag = lspeed * drag;
24     ldrag = ldrag * (drag * exp_);
25     ldrag = 1 - (ldrag / lspeed);
26
27     return self.velocity * ldrag;
28 }
29
30 /**
31     Simulate drag
32     self.velocity *= movelib_dragflt(somespeed,0.01,0.7);
33 **/
34 float movelib_dragflt(float fspeed,float drag,float exp_)
35 {
36     float ldrag;
37
38     ldrag = fspeed * drag;
39     ldrag = ldrag * ldrag * exp_;
40     ldrag = 1 - (ldrag / fspeed);
41
42     return ldrag;
43 }
44
45 /**
46     Do a inertia simulation based on velocity.
47     Basicaly, this allows you to simulate loss of steering with higher speed.
48     self.velocity = movelib_inertmove_byspeed(self.velocity,newvel,1000,0.1,0.9);
49 **/
50 vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
51 {
52     float influense;
53
54     influense = vlen(self.velocity) * (1 / vel_max);
55
56     influense = bound(newmin,influense,oldmax);
57
58     return (vel_new * (1 - influense)) + (self.velocity * influense);
59 }
60
61 vector movelib_inertmove(vector new_vel,float new_bias)
62 {
63     return new_vel * new_bias + self.velocity * (1-new_bias);
64 }
65
66 .float  movelib_lastupdate;
67 void movelib_move(vector force,float max_velocity,float drag,float theMass,float breakforce)
68 {
69     float deltatime;
70     float acceleration;
71     float mspeed;
72     vector breakvec;
73
74     deltatime = time - self.movelib_lastupdate;
75     if (deltatime > 0.15) deltatime = 0;
76     self.movelib_lastupdate = time;
77     if (!deltatime) return;
78
79     mspeed = vlen(self.velocity);
80
81     if (theMass)
82         acceleration = vlen(force) / theMass;
83     else
84         acceleration = vlen(force);
85
86     if (self.flags & FL_ONGROUND)
87     {
88         if (breakforce)
89         {
90             breakvec = (normalize(self.velocity) * (breakforce / theMass) * deltatime);
91             self.velocity = self.velocity - breakvec;
92         }
93
94         self.velocity = self.velocity + force * (acceleration * deltatime);
95     }
96
97     if (drag)
98         self.velocity = movelib_dragvec(drag, 1);
99
100     if (self.waterlevel > 1)
101     {
102         self.velocity = self.velocity + force * (acceleration * deltatime);
103         self.velocity = self.velocity + '0 0 0.05' * autocvar_sv_gravity * deltatime;
104     }
105     else
106         self.velocity = self.velocity + '0 0 -1' * autocvar_sv_gravity * deltatime;
107
108     mspeed = vlen(self.velocity);
109
110     if (max_velocity)
111         if (mspeed > max_velocity)
112             self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
113 }
114
115 /*
116 .float mass;
117 .float side_friction;
118 .float ground_friction;
119 .float air_friction;
120 .float water_friction;
121 .float buoyancy;
122 float movelib_deltatime;
123
124 void movelib_startupdate()
125 {
126     movelib_deltatime = time - self.movelib_lastupdate;
127
128     if (movelib_deltatime > 0.5)
129         movelib_deltatime = 0;
130
131     self.movelib_lastupdate = time;
132 }
133
134 void movelib_update(vector dir,float force)
135 {
136     vector acceleration;
137     float old_speed;
138     float ffriction,v_z;
139
140     vector breakvec;
141     vector old_dir;
142     vector ggravity;
143     vector old;
144
145     if(!movelib_deltatime)
146         return;
147     v_z = self.velocity_z;
148     old_speed    = vlen(self.velocity);
149     old_dir      = normalize(self.velocity);
150
151     //ggravity      =  (autocvar_sv_gravity / self.mass) * '0 0 100';
152     acceleration =  (force / self.mass) * dir;
153     //acceleration -= old_dir * (old_speed / self.mass);
154     acceleration -= ggravity;
155
156     if(self.waterlevel > 1)
157     {
158         ffriction = self.water_friction;
159         acceleration += self.buoyancy * '0 0 1';
160     }
161     else
162         if(self.flags & FL_ONGROUND)
163             ffriction = self.ground_friction;
164         else
165             ffriction = self.air_friction;
166
167     acceleration *= ffriction;
168     //self.velocity = self.velocity * (ffriction * movelib_deltatime);
169     self.velocity += acceleration * movelib_deltatime;
170     self.velocity_z = v_z;
171
172 }
173 */
174
175 /*
176 void movelib_move_simple(vector newdir,float velo,float blendrate)
177 {
178     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
179 }
180 */
181 #define movelib_move_simple(newdir,velo,blendrate) \
182     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
183
184 #define movelib_move_simple_gravity(newdir,velo,blendrate) \
185     if(self.flags & FL_ONGROUND) movelib_move_simple(newdir,velo,blendrate)
186
187 void movelib_beak_simple(float force)
188 {
189     float mspeed;
190     vector mdir;
191     float vz;
192
193     mspeed = max(0,vlen(self.velocity) - force);
194     mdir   = normalize(self.velocity);
195     vz = self.velocity.z;
196     self.velocity = mdir * mspeed;
197     self.velocity_z = vz;
198 }
199
200 /**
201 Pitches and rolls the entity to match the gound.
202 Yed need to set v_up and v_forward (generally by calling makevectors) before calling this.
203 **/
204 #endif
205
206 void movelib_groundalign4point(float spring_length, float spring_up, float blendrate, float _max)
207 {
208     vector a, b, c, d, e, r, push_angle, ahead, side;
209
210     push_angle_y = 0;
211     r = (self.absmax + self.absmin) * 0.5 + (v_up * spring_up);
212     e = v_up * spring_length;
213
214     // Put springs slightly inside bbox
215     ahead = v_forward * (self.maxs.x * 0.8);
216     side  = v_right   * (self.maxs.y * 0.8);
217
218     a = r + ahead + side;
219     b = r + ahead - side;
220     c = r - ahead + side;
221     d = r - ahead - side;
222
223     traceline(a, a - e,MOVE_NORMAL,self);
224     a_z =  (1 - trace_fraction);
225     r = trace_endpos;
226
227     traceline(b, b - e,MOVE_NORMAL,self);
228     b_z =  (1 - trace_fraction);
229     r += trace_endpos;
230
231     traceline(c, c - e,MOVE_NORMAL,self);
232     c_z =  (1 - trace_fraction);
233     r += trace_endpos;
234
235     traceline(d, d - e,MOVE_NORMAL,self);
236     d_z =  (1 - trace_fraction);
237     r += trace_endpos;
238
239     a_x = r.z;
240     r = self.origin;
241     r_z = r.z;
242
243     push_angle_x = (a.z - c.z) * _max;
244     push_angle.x += (b.z - d.z) * _max;
245
246     push_angle_z = (b.z - a.z) * _max;
247     push_angle.z += (d.z - c.z) * _max;
248
249     //self.angles_x += push_angle_x * 0.95;
250     //self.angles_z += push_angle_z * 0.95;
251
252     self.angles_x = ((1-blendrate) *  self.angles.x)  + (push_angle.x * blendrate);
253     self.angles_z = ((1-blendrate) *  self.angles.z)  + (push_angle.z * blendrate);
254
255     //a = self.origin;
256     setorigin(self,r);
257 }
258