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