-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
- #include "../dpdefs/progsdefs.qh"
- #include "../dpdefs/dpextensions.qh"
-#endif
-
-/**
- Uniform pull towards a point
-**/
-vector steerlib_pull(vector point)
-{SELFPARAM();
- return normalize(point - self.origin);
-}
-
-/**
- Uniform push from a point
-**/
-#define steerlib_push(point) normalize(self.origin - point)
-/*
-vector steerlib_push(vector point)
-{
- return normalize(self.origin - point);
-}
-*/
-/**
- Pull toward a point, The further away, the stronger the pull.
-**/
-vector steerlib_arrive(vector point,float maximal_distance)
-{SELFPARAM();
- float distance;
- vector direction;
-
- distance = bound(0.001,vlen(self.origin - point),maximal_distance);
- direction = normalize(point - self.origin);
- return direction * (distance / maximal_distance);
-}
-
-/**
- Pull toward a point increasing the pull the closer we get
-**/
-vector steerlib_attract(vector point, float maximal_distance)
-{SELFPARAM();
- float distance;
- vector direction;
-
- distance = bound(0.001,vlen(self.origin - point),maximal_distance);
- direction = normalize(point - self.origin);
-
- return direction * (1-(distance / maximal_distance));
-}
-
-vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
-{SELFPARAM();
- float distance;
- vector direction;
- float influense;
-
- distance = bound(0.00001,vlen(self.origin - point),max_distance);
- direction = normalize(point - self.origin);
-
- influense = 1 - (distance / max_distance);
- influense = min_influense + (influense * (max_influense - min_influense));
-
- return direction * influense;
-}
-
-/*
-vector steerlib_attract2(vector point, float maximal_distance,float min_influense,float max_influense,float distance)
-{
- //float distance;
- vector current_direction;
- vector target_direction;
- float i_target,i_current;
-
- if(!distance)
- distance = vlen(self.origin - point);
-
- distance = bound(0.001,distance,maximal_distance);
-
- target_direction = normalize(point - self.origin);
- current_direction = normalize(self.velocity);
-
- i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
- i_current = 1 - i_target;
-
- // i_target = bound(min_influense,(1-(distance / maximal_distance)),max_influense);
-
- string s;
- s = ftos(i_target);
- bprint("IT: ",s,"\n");
- s = ftos(i_current);
- bprint("IC : ",s,"\n");
-
- return normalize((target_direction * i_target) + (current_direction * i_current));
-}
-*/
-/**
- Move away from a point.
-**/
-vector steerlib_repell(vector point,float maximal_distance)
-{SELFPARAM();
- float distance;
- vector direction;
-
- distance = bound(0.001,vlen(self.origin - point),maximal_distance);
- direction = normalize(self.origin - point);
-
- return direction * (1-(distance / maximal_distance));
-}
-
-/**
- Try to keep at ideal_distance away from point
-**/
-vector steerlib_standoff(vector point,float ideal_distance)
-{SELFPARAM();
- float distance;
- vector direction;
-
- distance = vlen(self.origin - point);
-
-
- if(distance < ideal_distance)
- {
- direction = normalize(self.origin - point);
- return direction * (distance / ideal_distance);
- }
-
- direction = normalize(point - self.origin);
- return direction * (ideal_distance / distance);
-
-}
-
-/**
- A random heading in a forward halfcicrle
-
- use like:
- self.target = steerlib_wander(256,32,self.target)
-
- where range is the cicrle radius and tresh is how close we need to be to pick a new heading.
-**/
-vector steerlib_wander(float range,float tresh,vector oldpoint)
-{SELFPARAM();
- vector wander_point;
- wander_point = v_forward - oldpoint;
-
- if (vlen(wander_point) > tresh)
- return oldpoint;
-
- range = bound(0,range,1);
-
- wander_point = self.origin + v_forward * 128;
- wander_point = wander_point + randomvec() * (range * 128) - randomvec() * (range * 128);
-
- return normalize(wander_point - self.origin);
-}
-
-/**
- Dodge a point. dont work to well.
-**/
-vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
-{SELFPARAM();
- float distance;
-
- distance = max(vlen(self.origin - point),min_distance);
- if (min_distance < distance)
- return '0 0 0';
-
- return dodge_dir * (min_distance/distance);
-}
-
-/**
- flocking by .flock_id
- Group will move towards the unified direction while keeping close to eachother.
-**/
-.float flock_id;
-vector steerlib_flock(float _radius, float standoff,float separation_force,float flock_force)
-{SELFPARAM();
- entity flock_member;
- vector push = '0 0 0', pull = '0 0 0';
- float ccount = 0;
-
- flock_member = findradius(self.origin, _radius);
- while(flock_member)
- {
- if(flock_member != self)
- if(flock_member.flock_id == self.flock_id)
- {
- ++ccount;
- push = push + (steerlib_repell(flock_member.origin,standoff) * separation_force);
- pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity, _radius) * flock_force);
- }
- flock_member = flock_member.chain;
- }
- return push + (pull* (1 / ccount));
-}
-
-/**
- flocking by .flock_id
- Group will move towards the unified direction while keeping close to eachother.
- xy only version (for ground movers).
-**/
-vector steerlib_flock2d(float _radius, float standoff,float separation_force,float flock_force)
-{SELFPARAM();
- entity flock_member;
- vector push = '0 0 0', pull = '0 0 0';
- float ccount = 0;
-
- flock_member = findradius(self.origin,_radius);
- while(flock_member)
- {
- if(flock_member != self)
- if(flock_member.flock_id == self.flock_id)
- {
- ++ccount;
- push = push + (steerlib_repell(flock_member.origin, standoff) * separation_force);
- pull = pull + (steerlib_arrive(flock_member.origin + flock_member.velocity, _radius) * flock_force);
- }
- flock_member = flock_member.chain;
- }
-
- push.z = 0;
- pull.z = 0;
-
- return push + (pull * (1 / ccount));
-}
-
-/**
- All members want to be in the center, and keep away from eachother.
- The furtehr form the center the more they want to be there.
-
- This results in a aligned movement (?!) much like flocking.
-**/
-vector steerlib_swarm(float _radius, float standoff,float separation_force,float swarm_force)
-{SELFPARAM();
- entity swarm_member;
- vector force = '0 0 0', center = '0 0 0';
- float ccount = 0;
-
- swarm_member = findradius(self.origin,_radius);
-
- while(swarm_member)
- {
- if(swarm_member.flock_id == self.flock_id)
- {
- ++ccount;
- center = center + swarm_member.origin;
- force = force + (steerlib_repell(swarm_member.origin,standoff) * separation_force);
- }
- swarm_member = swarm_member.chain;
- }
-
- center = center * (1 / ccount);
- force = force + (steerlib_arrive(center,_radius) * swarm_force);
-
- return force;
-}
-
-/**
- Steer towards the direction least obstructed.
- Run four tracelines in a forward funnel, bias each diretion negative if something is found there.
- You need to call makevectors() (or equivalent) before this function to set v_forward and v_right
-**/
-vector steerlib_traceavoid(float pitch,float length)
-{SELFPARAM();
- vector vup_left,vup_right,vdown_left,vdown_right;
- float fup_left,fup_right,fdown_left,fdown_right;
- vector upwish,downwish,leftwish,rightwish;
- vector v_left,v_down;
-
-
- v_left = v_right * -1;
- v_down = v_up * -1;
-
- vup_left = (v_forward + (v_left * pitch + v_up * pitch)) * length;
- traceline(self.origin, self.origin + vup_left,MOVE_NOMONSTERS,self);
- fup_left = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vup_right = (v_forward + (v_right * pitch + v_up * pitch)) * length;
- traceline(self.origin,self.origin + vup_right ,MOVE_NOMONSTERS,self);
- fup_right = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vdown_left = (v_forward + (v_left * pitch + v_down * pitch)) * length;
- traceline(self.origin,self.origin + vdown_left,MOVE_NOMONSTERS,self);
- fdown_left = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vdown_right = (v_forward + (v_right * pitch + v_down * pitch)) * length;
- traceline(self.origin,self.origin + vdown_right,MOVE_NOMONSTERS,self);
- fdown_right = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
- upwish = v_up * (fup_left + fup_right);
- downwish = v_down * (fdown_left + fdown_right);
- leftwish = v_left * (fup_left + fdown_left);
- rightwish = v_right * (fup_right + fdown_right);
-
- return (upwish+leftwish+downwish+rightwish) * 0.25;
-
-}
-
-/**
- Steer towards the direction least obstructed.
- Run tracelines in a forward trident, bias each direction negative if something is found there.
-**/
-vector steerlib_traceavoid_flat(float pitch, float length, vector vofs)
-{SELFPARAM();
- vector vt_left, vt_right,vt_front;
- float f_left, f_right,f_front;
- vector leftwish, rightwish,frontwish, v_left;
-
- v_left = v_right * -1;
-
-
- vt_front = v_forward * length;
- traceline(self.origin + vofs, self.origin + vofs + vt_front,MOVE_NOMONSTERS,self);
- f_front = trace_fraction;
-
- vt_left = (v_forward + (v_left * pitch)) * length;
- traceline(self.origin + vofs, self.origin + vofs + vt_left,MOVE_NOMONSTERS,self);
- f_left = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- vt_right = (v_forward + (v_right * pitch)) * length;
- traceline(self.origin + vofs, self.origin + vofs + vt_right ,MOVE_NOMONSTERS,self);
- f_right = trace_fraction;
-
- //te_lightning1(world,self.origin, trace_endpos);
-
- leftwish = v_left * f_left;
- rightwish = v_right * f_right;
- frontwish = v_forward * f_front;
-
- return normalize(leftwish + rightwish + frontwish);
-}
-
-float beamsweep_badpoint(vector point,float waterok)
-{
- float pc,pc2;
-
- if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
- return 1;
-
- pc = pointcontents(point);
- pc2 = pointcontents(point - '0 0 1');
-
- switch(pc)
- {
- case CONTENT_SOLID: break;
- case CONTENT_SLIME: break;
- case CONTENT_LAVA: break;
-
- case CONTENT_SKY:
- return 1;
-
- case CONTENT_EMPTY:
- if (pc2 == CONTENT_SOLID)
- return 0;
-
- if (pc2 == CONTENT_WATER)
- if(waterok)
- return 0;
-
- break;
-
- case CONTENT_WATER:
- if(waterok)
- return 0;
-
- break;
- }
-
- return 1;
-}
-
-//#define BEAMSTEER_VISUAL
-float beamsweep(vector from, vector dir,float length, float step,float step_up, float step_down)
-{SELFPARAM();
- float i;
- vector a,b,u,d;
-
- u = '0 0 1' * step_up;
- d = '0 0 1' * step_down;
-
- traceline(from + u, from - d,MOVE_NORMAL,self);
- if(trace_fraction == 1.0)
- return 0;
-
- if(beamsweep_badpoint(trace_endpos,0))
- return 0;
-
- a = trace_endpos;
- for(i = 0; i < length; i += step)
- {
-
- b = a + dir * step;
- tracebox(a + u,'-4 -4 -4','4 4 4', b + u,MOVE_NORMAL,self);
- if(trace_fraction != 1.0)
- return i / length;
-
- traceline(b + u, b - d,MOVE_NORMAL,self);
- if(trace_fraction == 1.0)
- return i / length;
-
- if(beamsweep_badpoint(trace_endpos,0))
- return i / length;
-#ifdef BEAMSTEER_VISUAL
- te_lightning1(world,a+u,b+u);
- te_lightning1(world,b+u,b-d);
-#endif
- a = trace_endpos;
- }
-
- return 1;
-}
-
-vector steerlib_beamsteer(vector dir, float length, float step, float step_up, float step_down)
-{SELFPARAM();
- float bm_forward, bm_right, bm_left,p;
- vector vr,vl;
-
- dir.z *= 0.15;
- vr = vectoangles(dir);
- //vr_x *= -1;
-
- tracebox(self.origin + '0 0 1' * step_up, self.mins, self.maxs, ('0 0 1' * step_up) + self.origin + (dir * length), MOVE_NOMONSTERS, self);
- if(trace_fraction == 1.0)
- {
- //te_lightning1(self,self.origin,self.origin + (dir * length));
- return dir;
- }
-
-
-
-
- makevectors(vr);
- bm_forward = beamsweep(self.origin, v_forward, length, step, step_up, step_down);
-
- vr = normalize(v_forward + v_right * 0.125);
- vl = normalize(v_forward - v_right * 0.125);
-
- bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
- bm_left = beamsweep(self.origin, vl, length, step, step_up, step_down);
-
-
- p = bm_left + bm_right;
- if(p == 2)
- {
- //te_lightning1(self,self.origin + '0 0 32',self.origin + '0 0 32' + vr * length);
- //te_lightning1(self.tur_head,self.origin + '0 0 32',self.origin + '0 0 32' + vl * length);
-
- return v_forward;
- }
-
- p = 2 - p;
-
- vr = normalize(v_forward + v_right * p);
- vl = normalize(v_forward - v_right * p);
- bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
- bm_left = beamsweep(self.origin, vl, length, step, step_up, step_down);
-
-
- if(bm_left + bm_right < 0.15)
- {
- vr = normalize((v_forward*-1) + v_right * 0.75);
- vl = normalize((v_forward*-1) - v_right * 0.75);
-
- bm_right = beamsweep(self.origin, vr, length, step, step_up, step_down);
- bm_left = beamsweep(self.origin, vl, length, step, step_up, step_down);
- }
-
- //te_lightning1(self,self.origin + '0 0 32',self.origin + '0 0 32' + vr * length);
- //te_lightning1(self.tur_head,self.origin + '0 0 32',self.origin + '0 0 32' + vl * length);
-
- bm_forward *= bm_forward;
- bm_right *= bm_right;
- bm_left *= bm_left;
-
- vr = vr * bm_right;
- vl = vl * bm_left;
-
- return normalize(vr + vl);
-
-}
-
-
-//////////////////////////////////////////////
-// Testting //
-// Everything below this point is a mess :D //
-//////////////////////////////////////////////
-//#define TLIBS_TETSLIBS
-#ifdef TLIBS_TETSLIBS
-void flocker_die()
-{SELFPARAM();
- Send_Effect(EFFECT_ROCKET_EXPLODE, self.origin, '0 0 0', 1);
-
- self.owner.cnt += 1;
- self.owner = world;
-
- self.nextthink = time;
- self.think = SUB_Remove;
-}
-
-
-void flocker_think()
-{SELFPARAM();
- vector dodgemove,swarmmove;
- vector reprellmove,wandermove,newmove;
-
- self.angles_x = self.angles.x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles.x * -1;
-
- dodgemove = steerlib_traceavoid(0.35,1000);
- swarmmove = steerlib_flock(500,75,700,500);
- reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
-
- if(vlen(dodgemove) == 0)
- {
- self.pos1 = steerlib_wander(0.5,0.1,self.pos1);
- wandermove = self.pos1 * 50;
- }
- else
- self.pos1 = normalize(self.velocity);
-
- dodgemove = dodgemove * vlen(self.velocity) * 5;
-
- newmove = swarmmove + reprellmove + wandermove + dodgemove;
- self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
- //self.velocity = movelib_inertmove(dodgemove,0.65);
-
- self.velocity = movelib_dragvec(0.01,0.6);
-
- self.angles = vectoangles(self.velocity);
-
- if(self.health <= 0)
- flocker_die();
- else
- self.nextthink = time + 0.1;
-}
-
-MODEL(FLOCKER, "models/turrets/rocket.md3");
-
-void spawn_flocker()
-{SELFPARAM();
- entity flocker;
-
- flocker = spawn ();
-
- setorigin(flocker, self.origin + '0 0 32');
- setmodel (flocker, MDL_FLOCKER);
- setsize (flocker, '-3 -3 -3', '3 3 3');
-
- flocker.flock_id = self.flock_id;
- flocker.classname = "flocker";
- flocker.owner = self;
- flocker.think = flocker_think;
- flocker.nextthink = time + random() * 5;
- PROJECTILE_MAKETRIGGER(flocker);
- flocker.movetype = MOVETYPE_BOUNCEMISSILE;
- flocker.effects = EF_LOWPRECISION;
- flocker.velocity = randomvec() * 300;
- flocker.angles = vectoangles(flocker.velocity);
- flocker.health = 10;
- flocker.pos1 = normalize(flocker.velocity + randomvec() * 0.1);
-
- self.cnt = self.cnt -1;
-
-}
-
-void flockerspawn_think()
-{SELFPARAM();
-
-
- if(self.cnt > 0)
- spawn_flocker();
-
- self.nextthink = time + self.delay;
-
-}
-
-void flocker_hunter_think()
-{SELFPARAM();
- vector dodgemove,attractmove,newmove;
- entity e,ee;
- float d,bd;
-
- self.angles_x = self.angles.x * -1;
- makevectors(self.angles);
- self.angles_x = self.angles.x * -1;
-
- if(self.enemy)
- if(vlen(self.enemy.origin - self.origin) < 64)
- {
- ee = self.enemy;
- ee.health = -1;
- self.enemy = world;
-
- }
-
- if(!self.enemy)
- {
- e = findchainfloat(flock_id,self.flock_id);
- while(e)
- {
- d = vlen(self.origin - e.origin);
-
- if(e != self.owner)
- if(e != ee)
- if(d > bd)
- {
- self.enemy = e;
- bd = d;
- }
- e = e.chain;
- }
- }
-
- if(self.enemy)
- attractmove = steerlib_attract(self.enemy.origin+self.enemy.velocity * 0.1,5000) * 1250;
- else
- attractmove = normalize(self.velocity) * 200;
-
- dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
-
- newmove = dodgemove + attractmove;
- self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
- self.velocity = movelib_dragvec(0.01,0.5);
-
-
- self.angles = vectoangles(self.velocity);
- self.nextthink = time + 0.1;
-}
-
-
-float globflockcnt;
-spawnfunc(flockerspawn)
-{SELFPARAM();
- ++globflockcnt;
-
- if(!self.cnt) self.cnt = 20;
- if(!self.delay) self.delay = 0.25;
- if(!self.flock_id) self.flock_id = globflockcnt;
-
- self.think = flockerspawn_think;
- self.nextthink = time + 0.25;
-
- self.enemy = spawn();
-
- setmodel(self.enemy, MDL_FLOCKER);
- setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
-
- self.enemy.classname = "FLock Hunter";
- self.enemy.scale = 3;
- self.enemy.effects = EF_LOWPRECISION;
- self.enemy.movetype = MOVETYPE_BOUNCEMISSILE;
- PROJECTILE_MAKETRIGGER(self.enemy);
- self.enemy.think = flocker_hunter_think;
- self.enemy.nextthink = time + 10;
- self.enemy.flock_id = self.flock_id;
- self.enemy.owner = self;
-}
-#endif
-
-
-