Xonotic
steerlib.qc
Go to the documentation of this file.
1 #include "steerlib.qh"
2 
4 
8 #define steerlib_pull(ent,point) normalize(point - (ent).origin)
9 /*vector steerlib_pull(entity this, vector point)
10 {
11  return normalize(point - this.origin);
12 }*/
13 
17 #define steerlib_push(ent,point) normalize((ent).origin - point)
18 /*
19 vector steerlib_push(entity this, vector point)
20 {
21  return normalize(this.origin - point);
22 }
23 */
27 vector steerlib_arrive(entity this, vector point, float maximal_distance)
28 {
29  float distance = bound(0.001, vlen(this.origin - point), maximal_distance);
30  vector direction = normalize(point - this.origin);
31  return direction * (distance / maximal_distance);
32 }
33 
37 vector steerlib_attract(entity this, vector point, float maximal_distance)
38 {
39  float distance = bound(0.001, vlen(this.origin - point), maximal_distance);
40  vector direction = normalize(point - this.origin);
41 
42  return direction * (1 - (distance / maximal_distance));
43 }
44 
45 vector steerlib_attract2(entity this, vector point, float min_influense, float max_distance, float max_influense)
46 {
47  float distance = bound(0.00001, vlen(this.origin - point), max_distance);
48  vector direction = normalize(point - this.origin);
49 
50  float influense = 1 - (distance / max_distance);
51  influense = min_influense + (influense * (max_influense - min_influense));
52 
53  return direction * influense;
54 }
55 
56 /*
57 vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
58 {
59  //float distance;
60  vector current_direction;
61  vector target_direction;
62  float i_target,i_current;
63 
64  if(!distance)
65  distance = vlen(this.origin - point);
66 
67  distance = bound(0.001,distance,maximal_distance);
68 
69  target_direction = normalize(point - this.origin);
70  current_direction = normalize(this.velocity);
71 
72  i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
73  i_current = 1 - i_target;
74 
75  // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
76 
77  string s;
78  s = ftos(i_target);
79  bprint("IT: ",s,"\n");
80  s = ftos(i_current);
81  bprint("IC : ",s,"\n");
82 
83  return normalize((target_direction * i_target) + (current_direction * i_current));
84 }
85 */
89 vector steerlib_repel(entity this, vector point, float maximal_distance)
90 {
91  float distance = bound(0.001, vlen(this.origin - point), maximal_distance);
92  vector direction = normalize(this.origin - point);
93 
94  return direction * (1 - (distance / maximal_distance));
95 }
96 
100 vector steerlib_standoff(entity this, vector point, float ideal_distance)
101 {
103  float distance = vlen(this.origin - point);
104 
105  if(distance < ideal_distance)
106  {
107  direction = normalize(this.origin - point);
108  return direction * (distance / ideal_distance);
109  }
110 
111  direction = normalize(point - this.origin);
112  return direction * (ideal_distance / distance);
113 
114 }
115 
125 vector steerlib_wander(entity this, float range, float threshold, vector oldpoint)
126 {
127  vector wander_point = v_forward - oldpoint;
128 
129  if (vdist(wander_point, >, threshold))
130  return oldpoint;
131 
132  range = bound(0, range, 1);
133 
134  wander_point = this.origin + v_forward * 128;
135  wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
136 
137  return normalize(wander_point - this.origin);
138 }
139 
143 vector steerlib_dodge(entity this, vector point, vector dodge_dir, float min_distance)
144 {
145  float distance = max(vlen(this.origin - point), min_distance);
146  if (min_distance < distance)
147  return '0 0 0';
148 
149  return dodge_dir * (min_distance / distance);
150 }
151 
156 .float flock_id;
157 vector steerlib_flock(entity this, float _radius, float standoff, float separation_force, float flock_force)
158 {
159  vector push = '0 0 0', pull = '0 0 0';
160  int ccount = 0;
161 
162  entity flock_member = findradius(this.origin, _radius);
163  while(flock_member)
164  {
165  if(flock_member != this)
166  if(flock_member.flock_id == this.flock_id)
167  {
168  ++ccount;
169  push = push + (steerlib_repel(this, flock_member.origin,standoff) * separation_force);
170  pull = pull + (steerlib_arrive(this, flock_member.origin + flock_member.velocity, _radius) * flock_force);
171  }
172  flock_member = flock_member.chain;
173  }
174  return push + (pull* (1 / ccount));
175 }
176 
182 vector steerlib_flock2d(entity this, float _radius, float standoff, float separation_force, float flock_force)
183 {
184  vector push = '0 0 0', pull = '0 0 0';
185  int ccount = 0;
186 
187  entity flock_member = findradius(this.origin,_radius);
188  while(flock_member)
189  {
190  if(flock_member != this)
191  if(flock_member.flock_id == this.flock_id)
192  {
193  ++ccount;
194  push = push + (steerlib_repel(this, flock_member.origin, standoff) * separation_force);
195  pull = pull + (steerlib_arrive(this, flock_member.origin + flock_member.velocity, _radius) * flock_force);
196  }
197  flock_member = flock_member.chain;
198  }
199 
200  push.z = 0;
201  pull.z = 0;
202 
203  return push + (pull * (1 / ccount));
204 }
205 
212 vector steerlib_swarm(entity this, float _radius, float standoff, float separation_force, float swarm_force)
213 {
214  vector force = '0 0 0', center = '0 0 0';
215  int ccount = 0;
216 
217  entity swarm_member = findradius(this.origin,_radius);
218  while(swarm_member)
219  {
220  if(swarm_member.flock_id == this.flock_id)
221  {
222  ++ccount;
223  center = center + swarm_member.origin;
224  force = force + (steerlib_repel(this, swarm_member.origin,standoff) * separation_force);
225  }
226  swarm_member = swarm_member.chain;
227  }
228 
229  center = center * (1 / ccount);
230  force = force + (steerlib_arrive(this, center,_radius) * swarm_force);
231 
232  return force;
233 }
234 
240 vector steerlib_traceavoid(entity this, float pitch, float length)
241 {
242  vector v_left = v_right * -1;
243  vector v_down = v_up * -1;
244 
245  vector vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
246  traceline(this.origin, this.origin + vup_left, MOVE_NOMONSTERS, this);
247  float fup_left = trace_fraction;
248 
249  //te_lightning1(NULL,this.origin, trace_endpos);
250 
251  vector vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
252  traceline(this.origin, this.origin + vup_right, MOVE_NOMONSTERS, this);
253  float fup_right = trace_fraction;
254 
255  //te_lightning1(NULL,this.origin, trace_endpos);
256 
257  vector vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
258  traceline(this.origin, this.origin + vdown_left, MOVE_NOMONSTERS, this);
259  float fdown_left = trace_fraction;
260 
261  //te_lightning1(NULL,this.origin, trace_endpos);
262 
263  vector vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
264  traceline(this.origin, this.origin + vdown_right, MOVE_NOMONSTERS, this);
265  float fdown_right = trace_fraction;
266 
267  //te_lightning1(NULL,this.origin, trace_endpos);
268  vector upwish = v_up * (fup_left + fup_right);
269  vector downwish = v_down * (fdown_left + fdown_right);
270  vector leftwish = v_left * (fup_left + fdown_left);
271  vector rightwish = v_right * (fup_right + fdown_right);
272 
273  return (upwish + leftwish + downwish + rightwish) * 0.25;
274 
275 }
276 
282 vector steerlib_traceavoid_flat(entity this, float pitch, float length, vector vofs)
283 {
284  vector v_left = v_right * -1;
285 
286  vector vt_front = v_forward * length;
287  traceline(this.origin + vofs, this.origin + vofs + vt_front,MOVE_NOMONSTERS,this);
288  float f_front = trace_fraction;
289 
290  vector vt_left = (v_forward + (v_left * pitch)) * length;
291  traceline(this.origin + vofs, this.origin + vofs + vt_left,MOVE_NOMONSTERS,this);
292  float f_left = trace_fraction;
293 
294  //te_lightning1(NULL,this.origin, trace_endpos);
295 
296  vector vt_right = (v_forward + (v_right * pitch)) * length;
297  traceline(this.origin + vofs, this.origin + vofs + vt_right ,MOVE_NOMONSTERS,this);
298  float f_right = trace_fraction;
299 
300  //te_lightning1(NULL,this.origin, trace_endpos);
301 
302  vector leftwish = v_left * f_left;
303  vector rightwish = v_right * f_right;
304  vector frontwish = v_forward * f_front;
305 
306  return normalize(leftwish + rightwish + frontwish);
307 }
308 
309 //#define BEAMSTEER_VISUAL
310 float beamsweep(entity this, vector from, vector dir, float length, float step, float step_up, float step_down)
311 {
312  vector u = '0 0 1' * step_up;
313  vector d = '0 0 1' * step_down;
314 
315  traceline(from + u, from - d,MOVE_NORMAL,this);
316  if(trace_fraction == 1.0)
317  return 0;
318 
319  if(!location_isok(trace_endpos, false, false))
320  return 0;
321 
322  vector a = trace_endpos;
323  for(int i = 0; i < length; i += step)
324  {
325 
326  vector b = a + dir * step;
327  tracebox(a + u,'-4 -4 -4','4 4 4', b + u,MOVE_NORMAL,this);
328  if(trace_fraction != 1.0)
329  return i / length;
330 
331  traceline(b + u, b - d,MOVE_NORMAL,this);
332  if(trace_fraction == 1.0)
333  return i / length;
334 
335  if(!location_isok(trace_endpos, false, false))
336  return i / length;
337 #ifdef BEAMSTEER_VISUAL
338  te_lightning1(NULL,a+u,b+u);
339  te_lightning1(NULL,b+u,b-d);
340 #endif
341  a = trace_endpos;
342  }
343 
344  return 1;
345 }
346 
347 vector steerlib_beamsteer(entity this, vector dir, float length, float step, float step_up, float step_down)
348 {
349  dir.z *= 0.15;
350  vector vr = vectoangles(dir);
351  //vr.x *= -1;
352 
353  tracebox(this.origin + '0 0 1' * step_up, this.mins, this.maxs, ('0 0 1' * step_up) + this.origin + (dir * length), MOVE_NOMONSTERS, this);
354  if(trace_fraction == 1.0)
355  {
356  //te_lightning1(this,this.origin,this.origin + (dir * length));
357  return dir;
358  }
359 
360  makevectors(vr);
361  float bm_forward = beamsweep(this, this.origin, v_forward, length, step, step_up, step_down);
362 
363  vr = normalize(v_forward + v_right * 0.125);
364  vector vl = normalize(v_forward - v_right * 0.125);
365 
366  float bm_right = beamsweep(this, this.origin, vr, length, step, step_up, step_down);
367  float bm_left = beamsweep(this, this.origin, vl, length, step, step_up, step_down);
368 
369  float p = bm_left + bm_right;
370  if(p == 2)
371  {
372  //te_lightning1(this,this.origin + '0 0 32',this.origin + '0 0 32' + vr * length);
373  //te_lightning1(this.tur_head,this.origin + '0 0 32',this.origin + '0 0 32' + vl * length);
374 
375  return v_forward;
376  }
377 
378  p = 2 - p;
379 
380  vr = normalize(v_forward + v_right * p);
381  vl = normalize(v_forward - v_right * p);
382  bm_right = beamsweep(this, this.origin, vr, length, step, step_up, step_down);
383  bm_left = beamsweep(this, this.origin, vl, length, step, step_up, step_down);
384 
385 
386  if(bm_left + bm_right < 0.15)
387  {
388  vr = normalize((v_forward*-1) + v_right * 0.90);
389  vl = normalize((v_forward*-1) - v_right * 0.90);
390 
391  bm_right = beamsweep(this, this.origin, vr, length, step, step_up, step_down);
392  bm_left = beamsweep(this, this.origin, vl, length, step, step_up, step_down);
393  }
394 
395  //te_lightning1(this,this.origin + '0 0 32',this.origin + '0 0 32' + vr * length);
396  //te_lightning1(this.tur_head,this.origin + '0 0 32',this.origin + '0 0 32' + vl * length);
397 
398  bm_forward *= bm_forward;
399  bm_right *= bm_right;
400  bm_left *= bm_left;
401 
402  vr = vr * bm_right;
403  vl = vl * bm_left;
404 
405  return normalize(vr + vl);
406 }
float flock_id
flocking by .flock_id Group will move towards the unified direction while keeping close to eachother...
Definition: steerlib.qc:156
vector steerlib_repel(entity this, vector point, float maximal_distance)
Move away from a point.
Definition: steerlib.qc:89
bool location_isok(vector point, bool waterok, bool air_isok)
Definition: utility.qc:7
int direction
Definition: strafehud.qc:24
entity() spawn
vector steerlib_attract(entity this, vector point, float maximal_distance)
Pull toward a point increasing the pull the closer we get.
Definition: steerlib.qc:37
const float MOVE_NORMAL
Definition: csprogsdefs.qc:252
vector maxs
Definition: csprogsdefs.qc:113
float pitch
Definition: halflife.qc:5
vector steerlib_flock(entity this, float _radius, float standoff, float separation_force, float flock_force)
Definition: steerlib.qc:157
origin
Definition: ent_cs.qc:114
vector steerlib_traceavoid(entity this, float pitch, float length)
Steer towards the direction least obstructed.
Definition: steerlib.qc:240
const float MOVE_NOMONSTERS
Definition: csprogsdefs.qc:253
vector mins
Definition: csprogsdefs.qc:113
vector v_up
Definition: csprogsdefs.qc:31
#define NULL
Definition: post.qh:17
float beamsweep(entity this, vector from, vector dir, float length, float step, float step_up, float step_down)
Definition: steerlib.qc:310
vector trace_endpos
Definition: csprogsdefs.qc:37
vector steerlib_arrive(entity this, vector point, float maximal_distance)
Pull toward a point, The further away, the stronger the pull.
Definition: steerlib.qc:27
vector(float skel, float bonenum) _skel_get_boneabs_hidden
vector steerlib_beamsteer(entity this, vector dir, float length, float step, float step_up, float step_down)
Definition: steerlib.qc:347
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition: vector.qh:8
vector steerlib_attract2(entity this, vector point, float min_influense, float max_distance, float max_influense)
Definition: steerlib.qc:45
vector v_right
Definition: csprogsdefs.qc:31
vector steerlib_standoff(entity this, vector point, float ideal_distance)
Try to keep at ideal_distance away from point.
Definition: steerlib.qc:100
vector steerlib_traceavoid_flat(entity this, float pitch, float length, vector vofs)
Steer towards the direction least obstructed.
Definition: steerlib.qc:282
int dir
Definition: impulse.qc:89
#define makevectors
Definition: post.qh:21
float trace_fraction
Definition: csprogsdefs.qc:36
vector steerlib_wander(entity this, float range, float threshold, vector oldpoint)
A random heading in a forward semicircle.
Definition: steerlib.qc:125
vector steerlib_swarm(entity this, float _radius, float standoff, float separation_force, float swarm_force)
All members want to be in the center, and keep away from eachother.
Definition: steerlib.qc:212
vector steerlib_dodge(entity this, vector point, vector dodge_dir, float min_distance)
Dodge a point NOTE: doesn&#39;t work well.
Definition: steerlib.qc:143
vector v_forward
Definition: csprogsdefs.qc:31
vector steerlib_flock2d(entity this, float _radius, float standoff, float separation_force, float flock_force)
flocking by .flock_id Group will move towards the unified direction while keeping close to eachother...
Definition: steerlib.qc:182