4 Uniform pull towards a point
6 vector steerlib_pull(vector point)
8 return normalize(point - self.origin);
12 Uniform push from a point
14 vector steerlib_push(vector point)
16 return normalize(self.origin - point);
20 Pull toward a point, The further away, the stronger the pull.
22 vector steerlib_arrive(vector point,float maximal_distance)
27 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
28 direction = normalize(point - self.origin);
29 return direction * (distance / maximal_distance);
33 Pull toward a point increasing the pull the closer we get
35 vector steerlib_attract(vector point, float maximal_distance)
40 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
41 direction = normalize(point - self.origin);
43 return direction * (1-(distance / maximal_distance));
46 vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
52 distance = bound(0.00001,vlen(self.origin - point),max_distance);
53 direction = normalize(point - self.origin);
55 influense = 1 - (distance / max_distance);
56 influense = min_influense + (influense * (max_influense - min_influense));
58 return direction * influense;
62 vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
65 vector current_direction;
66 vector target_direction;
67 float i_target,i_current;
70 distance = vlen(self.origin - point);
72 distance = bound(0.001,distance,maximal_distance);
74 target_direction = normalize(point - self.origin);
75 current_direction = normalize(self.velocity);
77 i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
78 i_current = 1 - i_target;
80 // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
84 bprint("IT: ",s,"\n");
86 bprint("IC : ",s,"\n");
88 return normalize((target_direction * i_target) + (current_direction * i_current));
92 Move away from a point.
94 vector steerlib_repell(vector point,float maximal_distance)
99 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
100 direction = normalize(self.origin - point);
102 return direction * (1-(distance / maximal_distance));
106 Try to keep at ideal_distance away from point
108 vector steerlib_standoff(vector point,float ideal_distance)
113 distance = vlen(self.origin - point);
116 if(distance < ideal_distance)
118 direction = normalize(self.origin - point);
119 return direction * (distance / ideal_distance);
122 direction = normalize(point - self.origin);
123 return direction * (ideal_distance / distance);
128 A random heading in a forward halfcicrle
131 self.target = steerlib_waner(256,32,self.target)
133 where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
135 vector steerlib_waner(float range,float tresh,vector oldpoint)
138 wander_point = v_forward - oldpoint;
140 if (vlen(wander_point) > tresh)
143 range = bound(0,range,1);
145 wander_point = self.origin + v_forward * 128;
146 wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
148 return normalize(wander_point - self.origin);
152 Dodge a point. dont work to well.
154 vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
158 distance = max(vlen(self.origin - point),min_distance);
160 return dodge_dir * (min_distance/distance);
164 flocking by .flock_id
165 Group will move towards the unified direction while keeping close to eachother.
168 vector steerlib_flock(float radius, float standoff,float separation_force,float flock_force)
174 flock_member = findradius(self.origin,radius);
177 if(flock_member != self)
178 if(flock_member.flock_id == self.flock_id)
181 push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
182 pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity,radius) * flock_force);
184 flock_member = flock_member.chain;
186 return push + (pull* (1 / ccount));
190 All members want to be in the center, and keep away from eachother.
191 The furtehr form the center the more they want to be there.
193 This results in a aligned movement (?!) much like flocking.
195 vector steerlib_swarm(float radius, float standoff,float separation_force,float swarm_force)
201 swarm_member = findradius(self.origin,radius);
205 if(swarm_member.flock_id == self.flock_id)
208 center = center + swarm_member.origin;
209 force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
211 swarm_member = swarm_member.chain;
214 center = center * (1 / ccount);
215 force = force + (steerlib_arrive(center,radius) * swarm_force);
221 Steer towards the direction least obstructed.
222 Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
224 vector steerlib_traceavoid(float pitch,float length)
226 vector vup_left,vup_right,vdown_left,vdown_right;
227 float fup_left,fup_right,fdown_left,fdown_right;
228 vector upwish,downwish,leftwish,rightwish;
229 vector v_left,v_down;
231 v_left = v_right * -1;
234 vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
235 traceline(self.origin, self.origin + vup_left,MOVE_NOMONSTERS,self);
236 fup_left = trace_fraction;
238 //te_lightning1(world,self.origin, trace_endpos);
240 vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
241 traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
242 fup_right = trace_fraction;
244 //te_lightning1(world,self.origin, trace_endpos);
246 vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
247 traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
248 fdown_left = trace_fraction;
250 //te_lightning1(world,self.origin, trace_endpos);
252 vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
253 traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
254 fdown_right = trace_fraction;
256 //te_lightning1(world,self.origin, trace_endpos);
258 upwish = v_up * (fup_left + fup_right);
259 downwish = v_down * (fdown_left + fdown_right);
260 leftwish = v_left * (fup_left + fdown_left);
261 rightwish = v_right * (fup_right + fdown_right);
263 return (upwish+leftwish+downwish+rightwish) * 0.25;
268 Steer towards the direction least obstructed.
\r
269 Run two tracelines in a forward trident, bias each diretion negative if something is found there.
\r
271 vector steerlib_traceavoid_flat(float pitch, float length, vector vofs)
\r
273 vector vt_left, vt_right,vt_front;
\r
274 float f_left, f_right,f_front;
\r
275 vector leftwish, rightwish,frontwish, v_left;
\r
277 v_left = v_right * -1;
\r
280 vt_front = v_forward * length;
\r
281 traceline(self.origin + vofs, self.origin + vofs + vt_front,MOVE_NOMONSTERS,self);
\r
282 f_front = trace_fraction;
\r
284 vt_left = (v_forward + (v_left * pitch)) * length;
\r
285 traceline(self.origin + vofs, self.origin + vofs + vt_left,MOVE_NOMONSTERS,self);
\r
286 f_left = trace_fraction;
\r
288 //te_lightning1(world,self.origin, trace_endpos);
\r
290 vt_right = (v_forward + (v_right * pitch)) * length;
\r
291 traceline(self.origin + vofs, self.origin + vofs + vt_right ,MOVE_NOMONSTERS,self);
\r
292 f_right = trace_fraction;
\r
294 //te_lightning1(world,self.origin, trace_endpos);
\r
296 leftwish = v_left * f_left;
\r
297 rightwish = v_right * f_right;
\r
298 frontwish = v_forward * f_front;
\r
300 return normalize(leftwish + rightwish + frontwish);
\r
307 //////////////////////////////////////////////
309 // Everything below this point is a mess :D //
310 //////////////////////////////////////////////
311 //#define TLIBS_TETSLIBS
312 #ifdef TLIBS_TETSLIBS
315 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
317 pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
322 self.nextthink = time;
323 self.think = SUB_Remove;
329 vector dodgemove,swarmmove;
330 vector reprellmove,wandermove,newmove;
332 self.angles_x = self.angles_x * -1;
333 makevectors(self.angles);
334 self.angles_x = self.angles_x * -1;
336 dodgemove = steerlib_traceavoid(0.35,1000);
337 swarmmove = steerlib_flock(500,75,700,500);
338 reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
340 if(vlen(dodgemove) == 0)
342 self.pos1 = steerlib_waner(0.5,0.1,self.pos1);
343 wandermove = self.pos1 * 50;
346 self.pos1 = normalize(self.velocity);
348 dodgemove = dodgemove * vlen(self.velocity) * 5;
350 newmove = swarmmove + reprellmove + wandermove + dodgemove;
351 self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
352 //self.velocity = movelib_inertmove(dodgemove,0.65);
354 self.velocity = movelib_dragvec(0.01,0.6);
356 self.angles = vectoangles(self.velocity);
361 self.nextthink = time + 0.1;
371 setorigin(flocker, self.origin + '0 0 32');
372 setmodel (flocker, "models/turrets/rocket.md3");
373 setsize (flocker, '-3 -3 -3', '3 3 3');
375 flocker.flock_id = self.flock_id;
376 flocker.classname = "flocker";
377 flocker.owner = self;
378 flocker.think = flocker_think;
379 flocker.nextthink = time + random() * 5;
380 flocker.solid = SOLID_BBOX;
381 flocker.movetype = MOVETYPE_BOUNCEMISSILE;
382 flocker.effects = EF_LOWPRECISION;
383 flocker.velocity = randomvec() * 300;
384 flocker.angles = vectoangles(flocker.velocity);
386 flocker.pos1 = normalize(flocker.velocity + randomvec() * 0.1);
388 self.cnt = self.cnt -1;
392 void flockerspawn_think()
399 self.nextthink = time + self.delay;
403 void flocker_hunter_think()
405 vector dodgemove,attractmove,newmove;
409 self.angles_x = self.angles_x * -1;
410 makevectors(self.angles);
411 self.angles_x = self.angles_x * -1;
414 if(vlen(self.enemy.origin - self.origin) < 64)
424 e = findchainfloat(flock_id,self.flock_id);
427 d = vlen(self.origin - e.origin);
441 attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
443 attractmove = normalize(self.velocity) * 200;
445 dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
447 newmove = dodgemove + attractmove;
448 self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
449 self.velocity = movelib_dragvec(0.01,0.5);
452 self.angles = vectoangles(self.velocity);
453 self.nextthink = time + 0.1;
458 void spawnfunc_flockerspawn()
460 precache_model ( "models/turrets/rocket.md3");
461 precache_model("models/turrets/c512.md3");
464 if(!self.cnt) self.cnt = 20;
465 if(!self.delay) self.delay = 0.25;
466 if(!self.flock_id) self.flock_id = globflockcnt;
468 self.think = flockerspawn_think;
469 self.nextthink = time + 0.25;
471 self.enemy = spawn();
473 setmodel(self.enemy, "models/turrets/rocket.md3");
474 setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
476 self.enemy.classname = "FLock Hunter";
477 self.enemy.scale = 3;
478 self.enemy.effects = EF_LOWPRECISION;
479 self.enemy.movetype = MOVETYPE_BOUNCEMISSILE;
480 self.enemy.solid = SOLID_BBOX;
481 self.enemy.think = flocker_hunter_think;
482 self.enemy.nextthink = time + 10;
483 self.enemy.flock_id = self.flock_id;
484 self.enemy.owner = self;