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