]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/movelib.qc
Merge branch 'master' into Mario/monsters
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / movelib.qc
1 #ifdef SVQC 
2 .vector moveto;
3
4 /**
5     Simulate drag
6     self.velocity = movelib_dragvec(self.velocity,0.02,0.5);
7 **/
8 vector movelib_dragvec(float drag, float exp_)
9 {
10     float lspeed,ldrag;
11
12     lspeed = vlen(self.velocity);
13     ldrag = lspeed * drag;
14     ldrag = ldrag * (drag * exp_);
15     ldrag = 1 - (ldrag / lspeed);
16
17     return self.velocity * ldrag;
18 }
19
20 /**
21     Simulate drag
22     self.velocity *= movelib_dragflt(somespeed,0.01,0.7);
23 **/
24 float movelib_dragflt(float fspeed,float drag,float exp_)
25 {
26     float ldrag;
27
28     ldrag = fspeed * drag;
29     ldrag = ldrag * ldrag * exp_;
30     ldrag = 1 - (ldrag / fspeed);
31
32     return ldrag;
33 }
34
35 /**
36     Do a inertia simulation based on velocity.
37     Basicaly, this allows you to simulate loss of steering with higher speed.
38     self.velocity = movelib_inertmove_byspeed(self.velocity,newvel,1000,0.1,0.9);
39 **/
40 vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
41 {
42     float influense;
43
44     influense = vlen(self.velocity) * (1 / vel_max);
45
46     influense = bound(newmin,influense,oldmax);
47
48     return (vel_new * (1 - influense)) + (self.velocity * influense);
49 }
50
51 vector movelib_inertmove(vector new_vel,float new_bias)
52 {
53     return new_vel * new_bias + self.velocity * (1-new_bias);
54 }
55
56 .float  movelib_lastupdate;
57 void movelib_move(vector force,float max_velocity,float drag,float theMass,float breakforce)
58 {
59     float deltatime;
60     float acceleration;
61     float mspeed;
62     vector breakvec;
63
64     deltatime = time - self.movelib_lastupdate;
65     if (deltatime > 0.15) deltatime = 0;
66     self.movelib_lastupdate = time;
67     if (!deltatime) return;
68
69     mspeed = vlen(self.velocity);
70
71     if (theMass)
72         acceleration = vlen(force) / theMass;
73     else
74         acceleration = vlen(force);
75
76     if (self.flags & FL_ONGROUND)
77     {
78         if (breakforce)
79         {
80             breakvec = (normalize(self.velocity) * (breakforce / theMass) * deltatime);
81             self.velocity = self.velocity - breakvec;
82         }
83
84         self.velocity = self.velocity + force * (acceleration * deltatime);
85     }
86
87     if (drag)
88         self.velocity = movelib_dragvec(drag, 1);
89
90     if (self.waterlevel > 1)
91     {
92         self.velocity = self.velocity + force * (acceleration * deltatime);
93         self.velocity = self.velocity + '0 0 0.05' * autocvar_sv_gravity * deltatime;
94     }
95     else
96         self.velocity = self.velocity + '0 0 -1' * autocvar_sv_gravity * deltatime;
97
98     mspeed = vlen(self.velocity);
99
100     if (max_velocity)
101         if (mspeed > max_velocity)
102             self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
103 }
104
105 void movelib_move_simple_gravity(vector newdir,float velo,float blendrate)
106 {
107     float z_speed = self.velocity_z;
108     self.movelib_lastupdate = time;
109     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
110     self.velocity_z = z_speed * self.gravity;
111 }
112
113 void movelib_jump_simple(float power){
114     self.velocity_z=power;
115     self.movelib_lastupdate = time;
116 }
117
118 /*
119 .float mass;
120 .float side_friction;
121 .float ground_friction;
122 .float air_friction;
123 .float water_friction;
124 .float buoyancy;
125 float movelib_deltatime;
126
127 void movelib_startupdate()
128 {
129     movelib_deltatime = time - self.movelib_lastupdate;
130
131     if (movelib_deltatime > 0.5)
132         movelib_deltatime = 0;
133
134     self.movelib_lastupdate = time;
135 }
136
137 void movelib_update(vector dir,float force)
138 {
139     vector acceleration;
140     float old_speed;
141     float ffriction,v_z;
142
143     vector breakvec;
144     vector old_dir;
145     vector ggravity;
146     vector old;
147
148     if(!movelib_deltatime)
149         return;
150     v_z = self.velocity_z;
151     old_speed    = vlen(self.velocity);
152     old_dir      = normalize(self.velocity);
153
154     //ggravity      =  (autocvar_sv_gravity / self.mass) * '0 0 100';
155     acceleration =  (force / self.mass) * dir;
156     //acceleration -= old_dir * (old_speed / self.mass);
157     acceleration -= ggravity;
158
159     if(self.waterlevel > 1)
160     {
161         ffriction = self.water_friction;
162         acceleration += self.buoyancy * '0 0 1';
163     }
164     else
165         if(self.flags & FL_ONGROUND)
166             ffriction = self.ground_friction;
167         else
168             ffriction = self.air_friction;
169
170     acceleration *= ffriction;
171     //self.velocity = self.velocity * (ffriction * movelib_deltatime);
172     self.velocity += acceleration * movelib_deltatime;
173     self.velocity_z = v_z;
174
175 }
176 */
177
178 /*
179 void movelib_move_simple(vector newdir,float velo,float blendrate)
180 {
181     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
182 }
183 */
184 #define movelib_move_simple(newdir,velo,blendrate) \
185     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
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