2 Uniform pull towards a point
\r
4 vector steerlib_pull(vector point)
\r
6 return normalize(point - self.origin);
\r
10 Uniform push from a point
\r
12 vector steerlib_push(vector point)
\r
14 return normalize(self.origin - point);
\r
18 Pull toward a point, The further away, the stronger the pull.
\r
20 vector steerlib_arrive(vector point,float maximal_distance)
\r
25 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
\r
26 direction = normalize(point - self.origin);
\r
27 return direction * (distance / maximal_distance);
\r
31 Pull toward a point increasing the pull the closer we get
\r
33 vector steerlib_attract(vector point, float maximal_distance)
\r
38 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
\r
39 direction = normalize(point - self.origin);
\r
41 return direction * (1-(distance / maximal_distance));
\r
44 vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
\r
50 distance = bound(0.00001,vlen(self.origin - point),max_distance);
\r
51 direction = normalize(point - self.origin);
\r
53 influense = 1 - (distance / max_distance);
\r
54 influense = min_influense + (influense * (max_influense - min_influense));
\r
56 return direction * influense;
\r
60 vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
\r
63 vector current_direction;
\r
64 vector target_direction;
\r
65 float i_target,i_current;
\r
68 distance = vlen(self.origin - point);
\r
70 distance = bound(0.001,distance,maximal_distance);
\r
72 target_direction = normalize(point - self.origin);
\r
73 current_direction = normalize(self.velocity);
\r
75 i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
\r
76 i_current = 1 - i_target;
\r
78 // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
\r
82 bprint("IT: ",s,"\n");
\r
83 s = ftos(i_current);
\r
84 bprint("IC : ",s,"\n");
\r
86 return normalize((target_direction * i_target) + (current_direction * i_current));
\r
90 Move away from a point.
\r
92 vector steerlib_repell(vector point,float maximal_distance)
\r
97 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
\r
98 direction = normalize(self.origin - point);
\r
100 return direction * (1-(distance / maximal_distance));
\r
104 Try to keep at ideal_distance away from point
\r
106 vector steerlib_standoff(vector point,float ideal_distance)
\r
111 distance = vlen(self.origin - point);
\r
114 if(distance < ideal_distance)
\r
116 direction = normalize(self.origin - point);
\r
117 return direction * (distance / ideal_distance);
\r
120 direction = normalize(point - self.origin);
\r
121 return direction * (ideal_distance / distance);
\r
126 A random heading in a forward halfcicrle
\r
129 self.target = steerlib_waner(256,32,self.target)
\r
131 where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
\r
133 vector steerlib_waner(float range,float tresh,vector oldpoint)
\r
135 vector wander_point;
\r
136 wander_point = v_forward - oldpoint;
\r
138 if (vlen(wander_point) > tresh)
\r
141 range = bound(0,range,1);
\r
143 wander_point = self.origin + v_forward * 128;
\r
144 wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
\r
146 return normalize(wander_point - self.origin);
\r
150 Dodge a point. dont work to well.
\r
152 vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
\r
156 distance = max(vlen(self.origin - point),min_distance);
\r
158 return dodge_dir * (min_distance/distance);
\r
162 flocking by .flock_id
\r
163 Group will move towards the unified direction while keeping close to eachother.
\r
166 vector steerlib_flock(float radius, float standoff,float separation_force,float flock_force)
\r
168 entity flock_member;
\r
172 flock_member = findradius(self.origin,radius);
\r
173 while(flock_member)
\r
175 if(flock_member != self)
\r
176 if(flock_member.flock_id == self.flock_id)
\r
179 push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
\r
180 pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity,radius) * flock_force);
\r
182 flock_member = flock_member.chain;
\r
184 return push + (pull* (1 / ccount));
\r
188 All members want to be in the center, and keep away from eachother.
\r
189 The furtehr form the center the more they want to be there.
\r
191 This results in a aligned movement (?!) much like flocking.
\r
193 vector steerlib_swarm(float radius, float standoff,float separation_force,float swarm_force)
\r
195 entity swarm_member;
\r
196 vector force,center;
\r
199 swarm_member = findradius(self.origin,radius);
\r
201 while(swarm_member)
\r
203 if(swarm_member.flock_id == self.flock_id)
\r
206 center = center + swarm_member.origin;
\r
207 force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
\r
209 swarm_member = swarm_member.chain;
\r
212 center = center * (1 / ccount);
\r
213 force = force + (steerlib_arrive(center,radius) * swarm_force);
\r
219 Steer towards the direction least obstructed.
\r
220 Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
\r
222 vector steerlib_traceavoid(float pitch,float length)
\r
224 vector vup_left,vup_right,vdown_left,vdown_right;
\r
225 float fup_left,fup_right,fdown_left,fdown_right;
\r
226 vector upwish,downwish,leftwish,rightwish;
\r
227 vector v_left,v_down;
\r
229 v_left = v_right * -1;
\r
230 v_down = v_up * -1;
\r
232 vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
\r
233 traceline(self.origin, self.origin + vup_left,MOVE_NOMONSTERS,self);
\r
234 fup_left = trace_fraction;
\r
236 //te_lightning1(world,self.origin, trace_endpos);
\r
238 vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
\r
239 traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
\r
240 fup_right = trace_fraction;
\r
242 //te_lightning1(world,self.origin, trace_endpos);
\r
244 vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
\r
245 traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
\r
246 fdown_left = trace_fraction;
\r
248 //te_lightning1(world,self.origin, trace_endpos);
\r
250 vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
\r
251 traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
\r
252 fdown_right = trace_fraction;
\r
254 //te_lightning1(world,self.origin, trace_endpos);
\r
256 upwish = v_up * (fup_left + fup_right);
\r
257 downwish = v_down * (fdown_left + fdown_right);
\r
258 leftwish = v_left * (fup_left + fdown_left);
\r
259 rightwish = v_right * (fup_right + fdown_right);
\r
261 return (upwish+leftwish+downwish+rightwish) * 0.25;
\r
267 //////////////////////////////////////////////
\r
269 // Everything below this point is a mess :D //
\r
270 //////////////////////////////////////////////
\r
271 //#define TLIBS_TETSLIBS
\r
272 #ifdef TLIBS_TETSLIBS
\r
275 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
\r
277 pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
\r
279 self.owner.cnt += 1;
\r
280 self.owner = world;
\r
282 self.nextthink = time;
\r
283 self.think = SUB_Remove;
\r
287 void flocker_think()
\r
289 vector dodgemove,swarmmove;
\r
290 vector reprellmove,wandermove,newmove;
\r
292 self.angles_x = self.angles_x * -1;
\r
293 makevectors(self.angles);
\r
294 self.angles_x = self.angles_x * -1;
\r
296 dodgemove = steerlib_traceavoid(0.35,1000);
\r
297 swarmmove = steerlib_flock(500,75,700,500);
\r
298 reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
\r
300 if(vlen(dodgemove) == 0)
\r
302 self.pos1 = steerlib_waner(0.5,0.1,self.pos1);
\r
303 wandermove = self.pos1 * 50;
\r
306 self.pos1 = normalize(self.velocity);
\r
308 dodgemove = dodgemove * vlen(self.velocity) * 5;
\r
310 newmove = swarmmove + reprellmove + wandermove + dodgemove;
\r
311 self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
\r
312 //self.velocity = movelib_inertmove(dodgemove,0.65);
\r
314 self.velocity = movelib_dragvec(0.01,0.6);
\r
316 self.angles = vectoangles(self.velocity);
\r
318 if(self.health <= 0)
\r
321 self.nextthink = time + 0.1;
\r
325 void spawn_flocker()
\r
329 flocker = spawn ();
\r
331 setorigin(flocker, self.origin + '0 0 32');
\r
332 setmodel (flocker, "models/turrets/rocket.md3");
\r
333 setsize (flocker, '-3 -3 -3', '3 3 3');
\r
335 flocker.flock_id = self.flock_id;
\r
336 flocker.classname = "flocker";
\r
337 flocker.owner = self;
\r
338 flocker.think = flocker_think;
\r
339 flocker.nextthink = time + random() * 5;
\r
340 flocker.solid = SOLID_BBOX;
\r
341 flocker.movetype = MOVETYPE_BOUNCEMISSILE;
\r
342 flocker.effects = EF_LOWPRECISION;
\r
343 flocker.velocity = randomvec() * 300;
\r
344 flocker.angles = vectoangles(flocker.velocity);
\r
345 flocker.health = 10;
\r
346 flocker.pos1 = normalize(flocker.velocity + randomvec() * 0.1);
\r
348 self.cnt = self.cnt -1;
\r
352 void flockerspawn_think()
\r
359 self.nextthink = time + self.delay;
\r
363 void flocker_hunter_think()
\r
365 vector dodgemove,attractmove,newmove;
\r
369 self.angles_x = self.angles_x * -1;
\r
370 makevectors(self.angles);
\r
371 self.angles_x = self.angles_x * -1;
\r
374 if(vlen(self.enemy.origin - self.origin) < 64)
\r
378 self.enemy = world;
\r
384 e = findchainfloat(flock_id,self.flock_id);
\r
387 d = vlen(self.origin - e.origin);
\r
389 if(e != self.owner)
\r
401 attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
\r
403 attractmove = normalize(self.velocity) * 200;
\r
405 dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
\r
407 newmove = dodgemove + attractmove;
\r
408 self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
\r
409 self.velocity = movelib_dragvec(0.01,0.5);
\r
412 self.angles = vectoangles(self.velocity);
\r
413 self.nextthink = time + 0.1;
\r
417 float globflockcnt;
\r
418 void spawnfunc_flockerspawn()
\r
420 precache_model ( "models/turrets/rocket.md3");
\r
421 precache_model("models/turrets/c512.md3");
\r
424 if(!self.cnt) self.cnt = 20;
\r
425 if(!self.delay) self.delay = 0.25;
\r
426 if(!self.flock_id) self.flock_id = globflockcnt;
\r
428 self.think = flockerspawn_think;
\r
429 self.nextthink = time + 0.25;
\r
431 self.enemy = spawn();
\r
433 setmodel(self.enemy, "models/turrets/rocket.md3");
\r
434 setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
\r
436 self.enemy.classname = "FLock Hunter";
\r
437 self.enemy.scale = 3;
\r
438 self.enemy.effects = EF_LOWPRECISION;
\r
439 self.enemy.movetype = MOVETYPE_BOUNCEMISSILE;
\r
440 self.enemy.solid = SOLID_BBOX;
\r
441 self.enemy.think = flocker_hunter_think;
\r
442 self.enemy.nextthink = time + 10;
\r
443 self.enemy.flock_id = self.flock_id;
\r
444 self.enemy.owner = self;
\r