]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/movelib.qc
Merge branch 'master' into terencehill/clear_button
[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 /*
106 .float mass;
107 .float side_friction;
108 .float ground_friction;
109 .float air_friction;
110 .float water_friction;
111 .float buoyancy;
112 float movelib_deltatime;
113
114 void movelib_startupdate()
115 {
116     movelib_deltatime = time - self.movelib_lastupdate;
117
118     if (movelib_deltatime > 0.5)
119         movelib_deltatime = 0;
120
121     self.movelib_lastupdate = time;
122 }
123
124 void movelib_update(vector dir,float force)
125 {
126     vector acceleration;
127     float old_speed;
128     float ffriction,v_z;
129
130     vector breakvec;
131     vector old_dir;
132     vector ggravity;
133     vector old;
134
135     if(!movelib_deltatime)
136         return;
137     v_z = self.velocity_z;
138     old_speed    = vlen(self.velocity);
139     old_dir      = normalize(self.velocity);
140
141     //ggravity      =  (autocvar_sv_gravity / self.mass) * '0 0 100';
142     acceleration =  (force / self.mass) * dir;
143     //acceleration -= old_dir * (old_speed / self.mass);
144     acceleration -= ggravity;
145
146     if(self.waterlevel > 1)
147     {
148         ffriction = self.water_friction;
149         acceleration += self.buoyancy * '0 0 1';
150     }
151     else
152         if(self.flags & FL_ONGROUND)
153             ffriction = self.ground_friction;
154         else
155             ffriction = self.air_friction;
156
157     acceleration *= ffriction;
158     //self.velocity = self.velocity * (ffriction * movelib_deltatime);
159     self.velocity += acceleration * movelib_deltatime;
160     self.velocity_z = v_z;
161
162 }
163 */
164
165 /*
166 void movelib_move_simple(vector newdir,float velo,float blendrate)
167 {
168     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
169 }
170 */
171 #define movelib_move_simple(newdir,velo,blendrate) \
172     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
173
174 void movelib_beak_simple(float force)
175 {
176     float mspeed;
177     vector mdir;
178     float vz;
179
180     mspeed = max(0,vlen(self.velocity) - force);
181     mdir   = normalize(self.velocity);
182     vz = self.velocity_z;
183     self.velocity = mdir * mspeed;
184     self.velocity_z = vz;
185 }
186
187 /**
188 Pitches and rolls the entity to match the gound.
189 Yed need to set v_up and v_forward (generally by calling makevectors) before calling this.
190 **/
191 #endif
192
193 void movelib_groundalign4point(float spring_length, float spring_up, float blendrate, float _max)
194 {
195     vector a, b, c, d, e, r, push_angle, ahead, side;
196
197     push_angle_y = 0;
198     r = (self.absmax + self.absmin) * 0.5 + (v_up * spring_up);
199     e = v_up * spring_length;
200
201     // Put springs slightly inside bbox
202     ahead = v_forward * (self.maxs_x * 0.8);
203     side  = v_right   * (self.maxs_y * 0.8);
204
205     a = r + ahead + side;
206     b = r + ahead - side;
207     c = r - ahead + side;
208     d = r - ahead - side;
209
210     traceline(a, a - e,MOVE_NORMAL,self);
211     a_z =  (1 - trace_fraction);
212     r = trace_endpos;
213
214     traceline(b, b - e,MOVE_NORMAL,self);
215     b_z =  (1 - trace_fraction);
216     r += trace_endpos;
217
218     traceline(c, c - e,MOVE_NORMAL,self);
219     c_z =  (1 - trace_fraction);
220     r += trace_endpos;
221
222     traceline(d, d - e,MOVE_NORMAL,self);
223     d_z =  (1 - trace_fraction);
224     r += trace_endpos;
225
226     a_x = r_z;
227     r = self.origin;
228     r_z = r_z;
229
230     push_angle_x = (a_z - c_z) * _max;
231     push_angle_x += (b_z - d_z) * _max;
232
233     push_angle_z = (b_z - a_z) * _max;
234     push_angle_z += (d_z - c_z) * _max;
235
236     //self.angles_x += push_angle_x * 0.95;
237     //self.angles_z += push_angle_z * 0.95;
238
239     self.angles_x = ((1-blendrate) *  self.angles_x)  + (push_angle_x * blendrate);
240     self.angles_z = ((1-blendrate) *  self.angles_z)  + (push_angle_z * blendrate);
241
242     //a = self.origin;
243     setorigin(self,r);
244 }
245