2 Pull toward a point, The further away, the stronger the pull.
\r
4 vector steerlib_arrive(vector point,float maximal_distance)
\r
9 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
\r
10 direction = normalize(point - self.origin);
\r
11 return direction * (distance / maximal_distance);
\r
15 Pull toward a point increasing the pull the closer we get
\r
17 vector steerlib_attract(vector point, float maximal_distance)
\r
22 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
\r
23 direction = normalize(point - self.origin);
\r
25 return direction * (1-(distance / maximal_distance));
\r
29 Move away from a point.
\r
31 vector steerlib_repell(vector point,float maximal_distance)
\r
36 distance = bound(0.001,vlen(self.origin - point),maximal_distance);
\r
37 direction = normalize(self.origin - point);
\r
39 return direction * (1-(distance / maximal_distance));
\r
43 Keep at ideal_distance away from point
\r
45 vector steerlib_standoff(vector point,float ideal_distance)
\r
50 distance = vlen(self.origin - point);
\r
53 if(distance < ideal_distance)
\r
55 direction = normalize(self.origin - point);
\r
56 return direction * (distance / ideal_distance);
\r
59 direction = normalize(point - self.origin);
\r
60 return direction * (ideal_distance / distance);
\r
65 A random heading in a forward halfcicrle
\r
67 vector steerlib_waner(float range,float tresh,vector oldpoint)
\r
69 vector wander_point;
\r
70 wander_point = v_forward - oldpoint;
\r
72 if (vlen(wander_point) > tresh)
\r
75 range = bound(0,range,1);
\r
77 wander_point = self.origin + v_forward * 128;
\r
78 wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
\r
80 return normalize(wander_point - self.origin);
\r
86 vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
\r
90 distance = max(vlen(self.origin - point),min_distance);
\r
92 return dodge_dir * (min_distance/distance);
\r
96 flocking by .flock_id
\r
97 Group will move towards the unified direction while keeping close to eachother.
\r
100 vector steerlib_flock(float radius, float standoff,float separation_force,float flock_force)
\r
102 entity flock_member;
\r
106 flock_member = findradius(self.origin,radius);
\r
107 while(flock_member)
\r
109 if(flock_member != self)
\r
110 if(flock_member.flock_id == self.flock_id)
\r
113 push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
\r
114 pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity,radius) * flock_force);
\r
116 flock_member = flock_member.chain;
\r
118 return push + (pull* (1 / ccount));
\r
122 All members want to be in the center, and keep away from eachother.
\r
123 The furtehr form the center the more they want to be there.
\r
125 vector steerlib_swarm(float radius, float standoff,float separation_force,float swarm_force)
\r
127 entity swarm_member;
\r
128 vector force,center;
\r
131 swarm_member = findradius(self.origin,radius);
\r
133 while(swarm_member)
\r
135 if(swarm_member.flock_id == self.flock_id)
\r
138 center = center + swarm_member.origin;
\r
139 force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
\r
141 swarm_member = swarm_member.chain;
\r
144 center = center * (1 / ccount);
\r
145 force = force + (steerlib_arrive(center,radius) * swarm_force);
\r
151 Steer towards the direction least obstructed.
\r
152 Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
\r
154 vector steerlib_traceavoid(float pitch,float length)
\r
156 vector vup_left,vup_right,vdown_left,vdown_right;
\r
157 float fup_left,fup_right,fdown_left,fdown_right;
\r
158 vector v_left,v_down;
\r
162 traceline(self.origin,self.origin + v_forward * length,MOVE_NOMONSTERS,self);
\r
163 if(trace_fraction == 1)
\r
167 v_left = v_right * -1;
\r
168 v_down = v_up * -1;
\r
170 vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
\r
171 traceline(self.origin, self.origin + vup_left,MOVE_NOMONSTERS,self);
\r
172 //vup_left = trace_endpos;
\r
173 fup_left = trace_fraction;
\r
175 //te_lightning1(world,self.origin, trace_endpos);
\r
177 vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
\r
178 traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
\r
179 //vup_right = trace_endpos;
\r
180 fup_right = trace_fraction;
\r
182 //te_lightning1(world,self.origin, trace_endpos);
\r
184 vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
\r
185 traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
\r
186 //vdown_left = trace_endpos;
\r
187 fdown_left = trace_fraction;
\r
189 //te_lightning1(world,self.origin, trace_endpos);
\r
191 vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
\r
192 traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
\r
193 //vdown_right = trace_endpos;
\r
194 fdown_right = trace_fraction;
\r
196 //te_lightning1(world,self.origin, trace_endpos);
\r
198 //(v_for * f_for) +
\r
200 //point = self.origin + (vup_left * fup_left) + (vup_right * fup_right) +
\r
201 // (vdown_left * fdown_left) + (vdown_right * fdown_right);
\r
203 vector upwish,downwish,leftwish,rightwish;
\r
204 upwish = v_up * (fup_left + fup_right);
\r
205 downwish = v_down * (fdown_left + fdown_right);
\r
206 leftwish = v_left * (fup_left + fdown_left);
\r
207 rightwish = v_right * (fup_right + fdown_right);
\r
209 return (upwish+leftwish+downwish+rightwish) * 0.25;
\r
211 //point = point * 0.2; // /5
\r
213 // return normalize(point - self.origin) * (1- (fup_left+fup_right+fdown_left+fdown_right) * 0.25);
\r
218 //////////////////////////////////////////////
\r
220 // Everything below this point is a mess :D //
\r
221 //////////////////////////////////////////////
\r
222 #define TLIBS_TETSLIBS
\r
223 #ifdef TLIBS_TETSLIBS
\r
226 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
\r
228 pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
\r
230 self.owner.cnt += 1;
\r
231 self.owner = world;
\r
233 self.nextthink = time;
\r
234 self.think = SUB_Remove;
\r
238 void flocker_think()
\r
240 vector dodgemove,swarmmove;
\r
241 vector reprellmove,wandermove,newmove;
\r
243 self.angles_x = self.angles_x * -1;
\r
244 makevectors(self.angles);
\r
245 self.angles_x = self.angles_x * -1;
\r
247 dodgemove = steerlib_traceavoid(0.35,1000);
\r
248 swarmmove = steerlib_swarm(1000,100,150,400);
\r
249 reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,1000) * 700;
\r
251 if(vlen(dodgemove) == 0)
\r
253 self.pos1 = steerlib_waner(0.5,0.1,self.pos1);
\r
254 wandermove = self.pos1 * 50;
\r
257 self.pos1 = normalize(self.velocity);
\r
259 dodgemove = dodgemove * 700;
\r
261 newmove = swarmmove + reprellmove + wandermove + dodgemove;
\r
262 self.velocity = movelib_inertmove_byspeed(newmove,900,0.4,0.8);
\r
263 //self.velocity = movelib_inertmove(dodgemove,0.65);
\r
265 self.velocity = movelib_drag(0.02,0.6);
\r
267 self.angles = vectoangles(self.velocity);
\r
269 if(self.health <= 0)
\r
272 self.nextthink = time + 0.1;
\r
276 void spawn_flocker()
\r
280 flocker = spawn ();
\r
282 setorigin(flocker, self.origin + '0 0 32');
\r
283 setmodel (flocker, "models/turrets/rocket.md3");
\r
284 setsize (flocker, '-3 -3 -3', '3 3 3');
\r
286 flocker.flock_id = self.flock_id;
\r
287 flocker.classname = "flocker";
\r
288 flocker.owner = self;
\r
289 flocker.think = flocker_think;
\r
290 flocker.nextthink = time + random() * 5;
\r
291 flocker.solid = SOLID_BBOX;
\r
292 flocker.movetype = MOVETYPE_BOUNCEMISSILE;
\r
293 flocker.effects = EF_LOWPRECISION;
\r
294 flocker.velocity = randomvec() * 300;
\r
295 flocker.angles = vectoangles(flocker.velocity);
\r
296 flocker.health = 10;
\r
297 flocker.pos1 = normalize(flocker.velocity + randomvec() * 0.1);
\r
299 self.cnt = self.cnt -1;
\r
303 void flockerspawn_think()
\r
310 self.nextthink = time + self.delay;
\r
314 void flocker_hunter_think()
\r
316 vector dodgemove,attractmove,newmove;
\r
320 self.angles_x = self.angles_x * -1;
\r
321 makevectors(self.angles);
\r
322 self.angles_x = self.angles_x * -1;
\r
325 if(vlen(self.enemy.origin - self.origin) < 64)
\r
329 self.enemy = world;
\r
335 e = findchainfloat(flock_id,self.flock_id);
\r
338 d = vlen(self.origin - e.origin);
\r
340 if(e != self.owner)
\r
352 attractmove = steerlib_attract(self.enemy.origin,5000) * 1100;
\r
354 attractmove = normalize(self.velocity) * 200;
\r
356 dodgemove = steerlib_traceavoid(0.35,1500) * 1700;
\r
358 newmove = dodgemove + attractmove;
\r
359 self.velocity = movelib_inertmove_byspeed(newmove,850,0.5,0.9);
\r
360 self.velocity = movelib_drag(0.01,0.5);
\r
363 self.angles = vectoangles(self.velocity);
\r
364 self.nextthink = time + 0.1;
\r
368 float globflockcnt;
\r
369 void spawnfunc_flockerspawn()
\r
371 precache_model ( "models/turrets/rocket.md3");
\r
372 precache_model("models/turrets/c512.md3");
\r
375 if(!self.cnt) self.cnt = 20;
\r
376 if(!self.delay) self.delay = 0.25;
\r
377 if(!self.flock_id) self.flock_id = globflockcnt;
\r
379 self.think = flockerspawn_think;
\r
380 self.nextthink = time + 0.25;
\r
382 self.enemy = spawn();
\r
384 setmodel(self.enemy, "models/turrets/rocket.md3");
\r
385 setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
\r
387 self.enemy.classname = "FLock Hunter";
\r
388 self.enemy.scale = 3;
\r
389 self.enemy.effects = EF_LOWPRECISION;
\r
390 self.enemy.movetype = MOVETYPE_BOUNCEMISSILE;
\r
391 self.enemy.solid = SOLID_BBOX;
\r
392 self.enemy.think = flocker_hunter_think;
\r
393 self.enemy.nextthink = time + 10;
\r
394 self.enemy.flock_id = self.flock_id;
\r
395 self.enemy.owner = self;
\r