r5474 - in trunk/data/qcsrc/server: . tturrets/system tturrets/units

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Jan 9 11:45:52 EST 2009


Author: tzork
Date: 2009-01-09 11:45:52 -0500 (Fri, 09 Jan 2009)
New Revision: 5474

Modified:
   trunk/data/qcsrc/server/movelib.qc
   trunk/data/qcsrc/server/pathlib.qc
   trunk/data/qcsrc/server/progs.src
   trunk/data/qcsrc/server/steerlib.qc
   trunk/data/qcsrc/server/tturrets/system/system_damage.qc
   trunk/data/qcsrc/server/tturrets/system/system_main.qc
   trunk/data/qcsrc/server/tturrets/system/system_misc.qc
   trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
   trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
   trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc
   trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
   trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
Log:
Turret should now work in ONS.
Updates to moving units.

Modified: trunk/data/qcsrc/server/movelib.qc
===================================================================
--- trunk/data/qcsrc/server/movelib.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/movelib.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -2,13 +2,13 @@
     Simulate drag
     self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
 **/
-vector movelib_drag(float drag, float exp)
+vector movelib_dragvec(float drag, float exp)
 {
     float lspeed,ldrag;
 
     lspeed = vlen(self.velocity);
     ldrag = lspeed * drag;
-    ldrag = ldrag * drag * exp;
+    ldrag = ldrag * (drag * exp);
     ldrag = 1 - (ldrag / lspeed);
 
     return self.velocity * ldrag;
@@ -50,19 +50,82 @@
     return new_vel * new_bias + self.velocity * (1-new_bias);
 }
 
+.float  movelib_lastupdate;
+void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
+{
+    float deltatime;
+    float acceleration;
+    //float mspeed;
 
-/**
-    Applies absolute force to a velocity
-**/
-vector movelib_accelerate(vector vel,float force)
+    deltatime = time - self.movelib_lastupdate;
+    if (deltatime > 0.15) deltatime = 0;
+    self.movelib_lastupdate = time;
+    if(!deltatime) return;
+
+    //mspeed = vlen(self.velocity);
+
+    if(mass)
+        acceleration = vlen(force) / mass;
+    else
+        acceleration = vlen(force);
+
+    if(self.flags & FL_ONGROUND)
+    {
+        if(breakforce)
+        {
+            breakforce = 1 - ((breakforce / mass) * deltatime);
+            self.velocity = self.velocity * breakforce;
+        }
+
+        self.velocity = self.velocity + force * (acceleration * deltatime);
+    }
+
+    self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
+
+    if(drag)
+        self.velocity = movelib_dragvec(drag, 1);
+
+    if(max_velocity)
+    if(vlen(self.velocity) > max_velocity)
+        self.velocity = normalize(self.velocity) * max_velocity;
+}
+
+void movelib_move_simple(vector newdir,float velo,float turnrate)
 {
-    return normalize(vel) * (vlen(vel) + force);
+    vector olddir;
+
+    olddir = normalize(self.velocity);
+
+    self.velocity = normalize(olddir + newdir * turnrate) * velo;
 }
-vector movelib_decelerate(vector vel,float force)
+
+/*
+vector movelib_accelerate(float force)
 {
-    return normalize(vel) * (vlen(vel) - force);
+    vector vel;
+    vel = self.velocity;
+    vel = normalize(vel) * (vlen(vel) + force);
+    self.velocity = self.velocity  + vel;
 }
 
+
+vector movelib_decelerate(float force,float mass)
+{
+    vector vel;
+    float decel;
+
+    if(mass)
+        decel = force / mass;
+    else
+        decel = force;
+
+    vel = self.velocity;
+    vel = normalize(vel) * max((vlen(vel) - decel),0);
+    self.velocity = self.velocity - vel;
+
+    if(vlen(self.velocity) < 5) self.velocity = '0 0 0';
+}
+*/
 vector movelib_velocity_transfer(entity source,entity destination)
 {
     return '0 0 0';

Modified: trunk/data/qcsrc/server/pathlib.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/pathlib.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -2,6 +2,10 @@
 #define PLF_NOOPTIMIZE 2
 #define PLF_SUBPATH3D  4
 
+#define PT_QUICKSTAR 1
+#define PT_QUICKBOX  2
+#define PT_ASTAR     4  // FIXME NOT IMPLEMENTED
+
 //#define PATHLIB_RDFIELDS
 #ifdef PATHLIB_RDFIELDS
     #define path_flags lip
@@ -21,13 +25,13 @@
 #endif
 
 #define pathlib_garbagetime 120
-#define pathib_maxdivide 256
+#define pathib_maxdivide 512
 
 .float(vector start,vector end) path_validate;
 
 float pathlib_stdproc_path_validate(vector start,vector end)
 {
-    tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self);
+    tracebox(start, self.mins, self.maxs, end, MOVE_WORLDONLY, self);
 
     if(vlen(trace_endpos - end) < 32)
         return 1;
@@ -35,13 +39,13 @@
     return 0;
 }
 
-vector pathlib_groundsnap(vector where,entity path)
+vector pathlib_groundsnap(vector where)
 {
     float lsize;
 
     lsize = vlen(self.mins - self.maxs) * 0.25;
 
-    traceline(where + ('0 0 1' * lsize) ,where - '0 0 10000',MOVE_NORMAL,self);
+    traceline(where + ('0 0 1' * lsize) ,where - '0 0 10240',MOVE_WORLDONLY,self);
 
     return trace_endpos + ('0 0 1' * lsize);
 
@@ -68,33 +72,46 @@
     if(next)
     {
         point.path_next = next;
-        //point.path_nodelength = vlen(point.origin - next.origin)
     }
     else
         point.classname = "path_end";
 
-    if(point.owner.path_flags & PLF_GROUNDSNAP)
-        where = pathlib_groundsnap(where,parent);
+    if (point.owner.path_flags & PLF_GROUNDSNAP)
+        where = pathlib_groundsnap(where);
 
-
     setorigin(point,where);
 
 
     return point;
 }
 
-vector pathlib_findsubpath(entity start,vector vcrash,entity end,float maxsize)
+/*
+float pathlib_scoresubpath(vector start,vector point,vector end,float minstep)
 {
-    float x,y,z;
+    float dist_stp,dist_pte,dist_total;
+
+    dist_stp = vlen(start - point);
+    if(dist_stp < minstep)
+        return 100000000;
+
+    dist_pte = vlen(point - end);
+    dist_total = dist_stp + dist_pte;
+    return -1;
+}
+*/
+
+vector pathlib_subpath_quickbox(entity start,vector vcrash,entity end,float maxsize)
+{
+
     float step;
+    float pathscore;
+    float pathscore_best;
     float dist;
-    float pathlength;
-    float pathlength_best;
-    vector bestpoint;
-    vector point;
+    vector bestpoint,point;
     float zmin,zmax;
+    vector box;
 
-    pathlength_best = 1000000;
+    pathscore_best = 0;
 
     step = vlen(self.maxs - self.mins) * start.owner.path_subpathing_bboxexpand;
 
@@ -109,59 +126,153 @@
         zmax = 1;
     }
 
-    for(z = zmin; z < zmax; z += step)
-    for(y = -maxsize; y < maxsize; y += step)
-    for(x = -maxsize; x < maxsize; x += step)
+    for(box_z = zmin; box_z < zmax; box_z += step)
+    for(box_y = -maxsize; box_y < maxsize; box_y += step)
+    for(box_x = -maxsize; box_x < maxsize; box_x += step)
     {
 
-        point_z = vcrash_z + z;
-        point_x = vcrash_x + x;
-        point_y = vcrash_y + y;
+        point = vcrash + box;
 
-
         if(start.owner.path_flags & PLF_GROUNDSNAP)
-            point = pathlib_groundsnap(point,start);
+            point = pathlib_groundsnap(point);
 
         if(self.path_validate(start.origin,point))
         {
             dist = vlen(start.origin - point);
             if(dist > step)
             {
-                pathlength = dist + vlen(point - end.origin);
-                if(pathlength < pathlength_best)
+                pathscore = 1 / (dist + vlen(point - end.origin));
+                if(pathscore > pathscore_best)
                 {
                     bestpoint = point;
-                    pathlength_best = pathlength;
+                    pathscore_best = pathscore;
                 }
             }
         }
 
     }
 
-    if(pathlength_best != 1000000)
+    if(pathscore_best != 0)
         return bestpoint;
 
-    return vcrash;
+    return start.origin;
 }
 
-float pathlib_path(entity start,entity end)
+vector pathlib_subpath_quickstar(entity start,entity end,float gridsize)
 {
+    vector point, best_point;
+    float  score, best_score;
+    vector dir_end;
+
+    dir_end   = normalize(end.origin - start.origin);
+    dir_end_x = dir_end_x * -1;
+
+    makevectors(dir_end);
+
+    best_score = 0;
+    score      = 0;
+
+    best_point = start.origin;
+
+    // Forward
+    point = start.origin + v_forward * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+    // Forward-right
+    point = start.origin + (v_forward + v_right * 0.5) * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+
+    // Forward-left
+    point = start.origin + (v_forward - v_right * 0.5) * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+
+    // Right
+    point = start.origin + v_right * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+    // Left
+    point = start.origin - v_right * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+    // Back
+    point = start.origin - v_forward * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+    // Back-right
+
+    point = start.origin - (v_forward + v_right * 0.5) * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+    // Back-left
+    point = start.origin - (v_forward - v_right * 0.5) * gridsize;
+    point  = pathlib_groundsnap(point);
+    if(self.path_validate(start.origin,point)) score = 1 / vlen(point - end.origin);
+    if(score < best_score) { best_point = point; best_score = score; }
+    //te_lightning1(world,start.origin,point);
+
+    return(best_point);
+}
+
+float pathlib_path(entity start,entity end,float pathing_method)
+{
     vector vcrash;
     vector subpath_point;
     entity subpoint;
 
     // Fail.
     if(start.cnt > pathib_maxdivide)
+    {
+        bprint("To many segments!\n");
         return 0;
+    }
 
     if(self.path_validate(start.origin,end.origin))
         return 1;
 
     vcrash = trace_endpos;
 
-    subpath_point = pathlib_findsubpath(start,vcrash,end,start.owner.path_subpathing_size);
+    switch(pathing_method)
+    {
+        case PT_QUICKSTAR:
+            subpath_point = pathlib_subpath_quickstar(start,end,start.owner.path_subpathing_size);
+            break;
+        case PT_QUICKBOX:
+            subpath_point = pathlib_subpath_quickbox(start,vcrash,end,start.owner.path_subpathing_size);
+            break;
+        case PT_ASTAR:
+            dprint("Pathlib error: A* pathing not implemented!\n");
+            return 0;
+            break;
+        default:
+            subpath_point = pathlib_subpath_quickstar(start,end,start.owner.path_subpathing_size);
+            dprint("Pathlib warning: unknown pathing method, using quickstar!\n");
+            break;
+    }
 
-    if(subpath_point == vcrash)
+    if(subpath_point == start.origin)
         return 0; // Fail.
 
     subpoint = pathlib_createpoint(start,end,start.owner,subpath_point);
@@ -173,7 +284,7 @@
     if(self.path_validate(start.origin,end.origin))
         return 1;
 
-    return pathlib_path(subpoint,end);
+    return pathlib_path(subpoint,end,pathing_method);
 }
 
 void pathlib_path_optimize(entity start,entity end)
@@ -208,14 +319,17 @@
 {
     entity e;
 
-    e = findentity(start, owner, start);
+    e = findchainentity(owner, start);
     while(e)
     {
-        remove(e);
-        e = findentity(start, owner, start);
+        e.think = SUB_Remove;
+        e.nextthink = time;
+        e = e.chain;
     }
 }
 
+//#define DEBUGPATHING
+#ifdef DEBUGPATHING
 void pathlib_showpath(entity start)
 {
     entity e;
@@ -227,10 +341,16 @@
     }
 }
 
+void path_dbg_think()
+{
+    pathlib_showpath(self);
+    self.nextthink = time + 1;
+}
+#endif
 /**
-    Run a A*-like pathing from 'from' to 'to'
+    Pathing from 'from' to 'to'
 **/
-entity pathlib_makepath(vector from, vector to,float pathflags,float subpathing_size, float subpathing_bboxexpand)
+entity pathlib_makepath(vector from, vector to,float pathflags,float subpathing_size, float subpathing_bboxexpand,float pathing_method)
 {
     entity e_start,e_end;
 
@@ -244,6 +364,13 @@
     if(subpathing_bboxexpand < 1)
         subpathing_bboxexpand = 1;
 
+    if(pathflags & PLF_GROUNDSNAP)
+    {
+        //bprint("SnapIT!\n");
+        from = pathlib_groundsnap(from);
+        to = pathlib_groundsnap(to);
+    }
+
     e_start = pathlib_createpoint(world,world,world,from);
     e_start.path_flags = pathflags;
 
@@ -256,20 +383,54 @@
     e_start.path_next = e_end;
     e_start.cnt = 0;
 
-    if(!pathlib_path(e_start,e_end))
+    if(!pathlib_path(e_start,e_end,pathing_method))
     {
+        bprint("Fail, Fail, Fail!\n");
         pathlib_deletepath(e_start);
         remove(e_start);
+
         return world;
     }
 
     pathlib_path_optimize(e_start,e_end);
 
+#ifdef DEBUGPATHING
+    e_start.think = path_dbg_think;
+    e_start.nextthink = time + 1;
+#endif
+
     return e_start;
 
 }
 
+/*
+.entity goalcurrent, goalstack01, goalstack02, goalstack03;
+.entity goalstack04, goalstack05, goalstack06, goalstack07;
+.entity goalstack08, goalstack09, goalstack10, goalstack11;
+.entity goalstack12, goalstack13, goalstack14, goalstack15;
+.entity goalstack16, goalstack17, goalstack18, goalstack19;
+.entity goalstack20, goalstack21, goalstack22, goalstack23;
+.entity goalstack24, goalstack25, goalstack26, goalstack27;
+.entity goalstack28, goalstack29, goalstack30, goalstack31;
+*/
 
+#define node_left  goalstack01
+#define node_right goalstack02
+#define node_front goalstack03
+#define node_back  goalstack04
+
+#define node_open    goalstack05
+#define node_closed  goalstack06
+#define node_blocked goalstack07
+
+
+
+float pointinbox(vector point,vector box,float ssize)
+{
+    return 0;
+}
+#ifdef DEBUGPATHING
+
 /* TESTING */
 void pathlib_test_think()
 {
@@ -298,7 +459,7 @@
     }
 
     setsize(self,'-50 -50 0','50 50 50');
-    path = pathlib_makepath(self.origin,end.origin, PLF_GROUNDSNAP,500,1.25);
+    path = pathlib_makepath(self.origin,end.origin, PLF_GROUNDSNAP,500,1.25,PT_QUICKSTAR);
 
     if(!path)
     {
@@ -317,3 +478,5 @@
     self.think = pathlib_test_dinit;
     self.nextthink = time + 2;
 }
+
+#endif

Modified: trunk/data/qcsrc/server/progs.src
===================================================================
--- trunk/data/qcsrc/server/progs.src	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/progs.src	2009-01-09 16:45:52 UTC (rev 5474)
@@ -52,12 +52,6 @@
 g_subs.qc
 
 
-// tZork's libs
-movelib.qc
-steerlib.qc
-pathlib.qc
-
-
 runematch.qc
 arena.qc
 
@@ -68,6 +62,12 @@
 
 cl_physics.qc
 
+// tZork's libs
+movelib.qc
+steerlib.qc
+pathlib.qc
+//animation.qc
+
 g_world.qc
 g_decors.qc
 g_casings.qc

Modified: trunk/data/qcsrc/server/steerlib.qc
===================================================================
--- trunk/data/qcsrc/server/steerlib.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/steerlib.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -1,4 +1,20 @@
 /**
+    Uniform pull towards a point
+**/
+vector steerlib_pull(vector point)
+{
+    return normalize(point - self.origin);
+}
+
+/**
+    Uniform push from a 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)
@@ -25,6 +41,51 @@
     return  direction * (1-(distance / maximal_distance));
 }
 
+vector steerlib_attract2(vector point, float min_influense,float max_distance,float max_influense)
+{
+    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.
 **/
@@ -40,7 +101,7 @@
 }
 
 /**
-    Keep at ideal_distance away from point
+    Try to keep at ideal_distance away from point
 **/
 vector steerlib_standoff(vector point,float ideal_distance)
 {
@@ -63,6 +124,11 @@
 
 /**
     A random heading in a forward halfcicrle
+
+    use like:
+    self.target = steerlib_waner(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_waner(float range,float tresh,vector oldpoint)
 {
@@ -81,7 +147,7 @@
 }
 
 /**
-    Dodge a point-
+    Dodge a point. dont work to well.
 **/
 vector steerlib_dodge(vector point,vector dodge_dir,float min_distance)
 {
@@ -121,6 +187,8 @@
 /**
     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)
 {
@@ -155,52 +223,36 @@
 {
     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;
-    //vector point;
 
-    /*
-    traceline(self.origin,self.origin + v_forward * length,MOVE_NOMONSTERS,self);
-    if(trace_fraction == 1)
-        return '0 0 0';
-    */
-
     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);
-    //vup_left = trace_endpos;
     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);
-    //vup_right = trace_endpos;
     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);
-    //vdown_left = trace_endpos;
     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);
-    //vdown_right = trace_endpos;
     fdown_right = trace_fraction;
 
     //te_lightning1(world,self.origin, trace_endpos);
 
-    //(v_for * f_for) +
-
-    //point = self.origin + (vup_left * fup_left) + (vup_right * fup_right) +
-    //        (vdown_left * fdown_left) + (vdown_right * fdown_right);
-
-    vector upwish,downwish,leftwish,rightwish;
     upwish    = v_up    * (fup_left   + fup_right);
     downwish  = v_down  * (fdown_left + fdown_right);
     leftwish  = v_left  * (fup_left   + fdown_left);
@@ -208,9 +260,6 @@
 
     return (upwish+leftwish+downwish+rightwish) * 0.25;
 
-    //point = point * 0.2; // /5
-
-   // return normalize(point - self.origin) * (1- (fup_left+fup_right+fdown_left+fdown_right) * 0.25);
 }
 
 
@@ -219,7 +268,7 @@
 //     Testting                             //
 // Everything below this point is a mess :D //
 //////////////////////////////////////////////
-#define TLIBS_TETSLIBS
+//#define TLIBS_TETSLIBS
 #ifdef TLIBS_TETSLIBS
 void flocker_die()
 {
@@ -245,8 +294,8 @@
     self.angles_x = self.angles_x * -1;
 
     dodgemove   = steerlib_traceavoid(0.35,1000);
-    swarmmove   = steerlib_swarm(1000,100,150,400);
-    reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,1000) * 700;
+    swarmmove   = steerlib_flock(500,75,700,500);
+    reprellmove = steerlib_repell(self.owner.enemy.origin+self.enemy.velocity,2000) * 700;
 
     if(vlen(dodgemove) == 0)
     {
@@ -256,13 +305,13 @@
     else
         self.pos1 = normalize(self.velocity);
 
-    dodgemove = dodgemove * 700;
+    dodgemove = dodgemove * vlen(self.velocity) * 5;
 
     newmove = swarmmove + reprellmove + wandermove + dodgemove;
-    self.velocity = movelib_inertmove_byspeed(newmove,900,0.4,0.8);
+    self.velocity = movelib_inertmove_byspeed(newmove,300,0.2,0.9);
     //self.velocity  = movelib_inertmove(dodgemove,0.65);
 
-    self.velocity = movelib_drag(0.02,0.6);
+    self.velocity = movelib_dragvec(0.01,0.6);
 
     self.angles = vectoangles(self.velocity);
 
@@ -349,15 +398,15 @@
     }
 
     if(self.enemy)
-        attractmove = steerlib_attract(self.enemy.origin,5000) * 1100;
+        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) * 1700;
+    dodgemove = steerlib_traceavoid(0.35,1500) * vlen(self.velocity);
 
     newmove = dodgemove + attractmove;
-    self.velocity = movelib_inertmove_byspeed(newmove,850,0.5,0.9);
-    self.velocity = movelib_drag(0.01,0.5);
+    self.velocity = movelib_inertmove_byspeed(newmove,1250,0.3,0.7);
+    self.velocity = movelib_dragvec(0.01,0.5);
 
 
     self.angles = vectoangles(self.velocity);
@@ -395,3 +444,5 @@
     self.enemy.owner     = self;
 }
 #endif
+
+

Modified: trunk/data/qcsrc/server/tturrets/system/system_damage.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_damage.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/system/system_damage.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -289,24 +289,25 @@
     self = baseent;
 
     if (teamplay != 0)
+    if (self.team == attacker.team)
     {
-        if (self.team == attacker.team)
+        // This does not happen anymore. Re-enable if you fix that.
+        //if(attacker.flags & FL_CLIENT)
+            //if not(attacker.isbot)
+                //sprint(attacker, "\{1}Turret tells you: I'm on your team!\n");
+
+        if(cvar("g_friendlyfire"))
         {
-            sprint(attacker, "\{1}Turret tells you: I'm on your team!\n");
+            self = oldself;
             return;
         }
         else
         {
-            /*
-            // This will get enoying fast...
-            FOR_EACH_PLAYER(player)
-            	if(player.team == self.team)
-            		sprint(player, "The enemy is attacking your base!");
-            */
+            damage = damage * cvar("g_friendlyfire");
         }
     }
 
-    baseent.health = baseent.health - damage;
+    self.health = self.health - damage;
 
     // thorw head slightly off aim when hit?
     if (oldself.classname == "turret_head")

Modified: trunk/data/qcsrc/server/tturrets/system/system_main.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_main.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/system/system_main.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -177,32 +177,31 @@
         real_angle = wish_angle - (self.angles + self.tur_head.angles);
     else
     {
-        //if(vlen(wish_angle - self.tur_head.angles) > vlen(self.tur_head.angles - wish_angle))
         real_angle = wish_angle - self.tur_head.angles;
-        //else
-        //    real_angle =  self.tur_head.angles - wish_angle;
+
     }
 
-    /*
-    if(real_angle_y > 180)
-        bprint("^3");
-    if(real_angle_y < -180)
-        bprint("^1");
-    string s;
-    s = vtos(real_angle);
-    bprint("RA1: ",s);
-    */
+    if(real_angle_x > self.tur_head.angles_x)
+    {
+        if(real_angle_x >= 180)
+            real_angle_x -= 360;
+    }
+    else
+    {
+        if(real_angle_x <= -180)
+            real_angle_x += 360;
+    }
+    if(real_angle_y > self.tur_head.angles_y)
+    {
+        if(real_angle_y >= 180)
+            real_angle_y -= 360;
+    }
+    else
+    {
+        if(real_angle_y <= -180)
+            real_angle_y += 360;
+    }
 
-
-    if (real_angle_x < 0) real_angle_x += 360;
-    if (real_angle_x > 180) real_angle_x -= 360;
-
-    if (real_angle_y < 0) real_angle_y += 360;
-    if (real_angle_y >= 180) real_angle_y -= 360;
-
-    //s = vtos(real_angle);
-    //bprint(" RA2: ",s,"\n");
-
     // Limit pitch
 
     if (self.track_flags & TFL_TRACK_PITCH)
@@ -426,6 +425,7 @@
 			return -5.5;
 	}
 
+
     // Missile
     if (e_target.flags & FL_PROJECTILE)
     {
@@ -459,13 +459,13 @@
     {
         v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
         //v_tmp = e_target.origin;
-        traceline(e_turret.origin,v_tmp,0,e_turret);
+        traceline(e_turret.origin + e_turret.tur_aimorg,v_tmp,0,e_turret);
 
         if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
             return -10;
     }
 
-    // Can we even aim this thing? (anglecheck)
+    // Can we even aim this thing?
     tvt_thadv = angleofs(e_turret.tur_head,e_target);
     tvt_tadv  = angleofs(e_turret,e_target);
     tvt_thadf = vlen(tvt_thadv);
@@ -501,44 +501,39 @@
 entity turret_select_target()
 {
     entity e;        // target looper entity
-    entity e_enemy;  // currently best scoreing enemy
-
-    float score;     // current target (e) score
-    float m_score;   // current best target (e_enemy) score
+    float  score;    // target looper entity score
+    entity e_enemy;  // currently best scoreing target
+    float  m_score;  // currently best scoreing target's score
     float f;
-    // string s;
+
+    m_score = 0;
+    if(self.enemy)
+    if(turret_validate_target(self,e,self.target_select_flags) > 0)
+    {
+        e_enemy = self.enemy;
+        m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;
+    }
+
     e = findradius(self.origin,self.target_range);
 
-    // Nothing to aim at.
+    // Nothing to aim at?
     if (!e) return world;
 
-    m_score = 0;
-
     while (e)
     {
         f = turret_validate_target(self,e,self.target_select_flags);
-        //s = ftos(f);
-        //bprint(e.netname, " = ",s,"\n");
         if (f > 0)
         {
-
             score = self.turret_score_target(self,e);
-
             if ((score > m_score) && (score > 0))
             {
                 e_enemy = e;
                 m_score = score;
             }
         }
-
         e = e.chain;
     }
 
-//    self.tur_lastscore = m_score;
-
-    //if (self.enemy != e_enemy)
-    //self.volly_counter = 0;
-
     return e_enemy;
 }
 
@@ -731,9 +726,13 @@
     dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
 }
 
+/*
+    When .used a turret switched team to activator.team.
+    If activator is world, the turrets goes inactive.
+*/
 void turret_stdproc_use()
 {
-    // bprint("Used:",self.netname, " By ",other.netname,"\n");
+     //bprint("Used:",self.netname, " By ",other.classname,"\n");
 
     self.team = activator.team;
 
@@ -742,38 +741,6 @@
     else
         self.tur_active = 1;
 
-    // ONS Uses _use to communicate.
-    //if (g_onslaught)
-    /*
-    if (1) // if anyone ever figures out why i needed a active toggle here, fix this
-    {
-        entity e;
-
-        if (self.targetname)
-        {
-            e = find(world,target,self.targetname);
-            if (e != world)
-                self.team = e.team;
-        }
-
-        if (self.team != self.tur_head.team)
-            turret_stdproc_respawn();
-
-        if(self.team == 0)
-            self.tur_active = 0;
-        else
-            self.tur_active = 1;
-
-    }
-    else
-    {
-        if (self.tur_active)
-            self.tur_active = 0;
-        else
-            self.tur_active = 1;
-    }
-    */
-
 }
 
 /*
@@ -1105,9 +1072,11 @@
 
     self.tur_active = 1;
 
-    if (g_onslaught)
-        self.use();
+    //if (g_onslaught)
+    //    self.use();
 
+    //turret_stdproc_use();
+
     return 1;
 }
 

Modified: trunk/data/qcsrc/server/tturrets/system/system_misc.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_misc.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/system/system_misc.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -1,5 +1,31 @@
 //--// Some support routines //--//
 
+float shortangle_f(float ang1,float ang2)
+{
+    if(ang1 > ang2)
+    {
+        if(ang1 >= 180)
+            return ang1 - 360;
+    }
+    else
+    {
+        if(ang1 <= -180)
+            return ang1 + 360;
+    }
+
+    return ang1;
+}
+vector shortangle_v(vector ang1,vector ang2)
+{
+    vector vtmp;
+    vtmp_x = shortangle_f(ang1_x,ang2_x);
+    vtmp_y = shortangle_f(ang1_y,ang2_y);
+    vtmp_z = shortangle_f(ang1_z,ang2_z);
+
+    return vtmp;
+}
+
+
 // Get real origin
 vector real_origin(entity ent)
 {

Modified: trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -39,7 +39,7 @@
     float d_score;      // Distance score
     //float da_score;     // Distance from aimpoint score
     float a_score;      // Angular score
-    float s_score;      // samescore (same target as last time)
+    //float s_score;      // samescore (same target as last time)
     float m_score;      // missile score
     float p_score;      // player score
 
@@ -47,7 +47,7 @@
 
     if(!e_target) return 0;
 
-    if (e_target == e_turret.enemy) s_score = 1;
+    //if (e_target == e_turret.enemy) s_score = 1;
 
     if (e_turret.tur_defend)
     {
@@ -84,13 +84,13 @@
         p_score = 1;
 
     d_score = max(d_score,0);
-    s_score = max(s_score,0);
+    //s_score = max(s_score,0);
     a_score = max(a_score,0);
     m_score = max(m_score,0);
     p_score = max(p_score,0);
 
+    // (s_score * e_turret.target_select_samebias) +
     score = (d_score * e_turret.target_select_rangebias) +
-            (s_score * e_turret.target_select_samebias) +
             (a_score * e_turret.target_select_anglebias) +
             (m_score * e_turret.target_select_missilebias) +
             (p_score * e_turret.target_select_playerbias);

Modified: trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -1,15 +1,19 @@
 /**
     turret_checkpoint
-    Semi smart pathing system for move capable turrets.
 **/
 
-#define checkpoint_path swampslug
-#define checkpoint_target enemy
 
-#define checkpoint_cache_who flagcarried
+#define checkpoint_target goalstack03
+
+/*
+#define checkpoint_cache_who  flagcarried
 #define checkpoint_cache_from lastrocket
-#define checkpoint_cache_to selected_player
+#define checkpoint_cache_to   selected_player
+*/
 
+#define pathgoal    goalstack01
+#define pathcurrent goalstack02
+
 entity path_makeorcache(entity forwho,entity start, entity end)
 {
     entity oldself;
@@ -17,21 +21,14 @@
     oldself = self;
     self = forwho;
 
-    pth = pathlib_makepath(start.origin,end.origin,PLF_GROUNDSNAP,500,1.5);
+    pth = pathlib_makepath(start.origin,end.origin,PLF_GROUNDSNAP,500,1.5,PT_QUICKSTAR);
+
     self = oldself;
     return pth;
 }
 
 void turret_checkpoint_use()
 {
-    if(other.checkpoint_path)
-        pathlib_deletepath(other.checkpoint_path);
-
-    other.checkpoint_path = world;
-
-    if(self.checkpoint_target)
-        other.checkpoint_path = path_makeorcache(other,self,self.checkpoint_target);
-
 }
 
 /*QUAKED turret_checkpoint (1 0 1) (-32 -32 -32) (32 32 32)
@@ -43,15 +40,21 @@
 If a loop is of targets are formed, any unit entering this loop will patrol it indefinitly.
 If the checkpoint chain in not looped, the unit will go "Roaming" when the last point is reached.
 */
-void spawnfunc_turret_checkpoint()
+void turret_checkpoint_init()
 {
     if(self.target != "")
     {
-        self.checkpoint_target = find(world,targetname,self.target);
-        if(!self.checkpoint_target)
+        self.enemy = find(world,targetname,self.target);
+        if(self.enemy == world)
             dprint("A turret_checkpoint faild to find its target!\n");
     }
+}
 
+void spawnfunc_turret_checkpoint()
+{
+    setorigin(self,self.origin);
+    self.think = turret_checkpoint_init;
+    self.nextthink = time + 0.25;
 }
 
 // Compat.

Modified: trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -26,7 +26,7 @@
     vector v;
     float f,i;
 
-    for(i=0;i<2;++i)
+    for (i=0;i<1;i++)
     {
         f = gettagindex(self.tur_head,"tag_fire");
         v = gettaginfo(self.tur_head,f);
@@ -56,61 +56,172 @@
         proj.enemy           = self.enemy;
         proj.flags           = FL_PROJECTILE | FL_NOTARGET;
 
-        self.tur_head.frame += 1;
+        self.tur_head.frame += 2;
 
         if (self.tur_head.frame > 3)
-        self.tur_head.frame = 0;
-        }
+            self.tur_head.frame = 0;
+    }
 
 }
 
-void ewheel_postthink()
+#define EWHEEL_MASS 50
+#define EWHEEL_MAXSPEED 1500
+#define EWHEEL_ACCEL_SLOW 50
+#define EWHEEL_ACCEL_FAST 150
+#define EWHEEL_BREAK_SLOW 100
+#define EWHEEL_BREAK_FAST 250
+
+void ewheel_enemymove()
 {
-    vector wish_angle,real_angle;
-    float turn_limit;
+    vector wish_angle,real_angle,steer,avoid;
+    float turn_limit,angle_ofs;
 
-    if (!self.enemy)
+    //steer = steerlib_attract2(point,0.5,2000,0.95);
+    steer = steerlib_pull(self.enemy.origin);
+    avoid = steerlib_traceavoid(0.3,350);
+
+    wish_angle = normalize(avoid * 0.5 + steer);
+    wish_angle = vectoangles(wish_angle);
+    real_angle = wish_angle - self.angles;
+
+    if (real_angle_x > self.angles_x)
     {
-        self.velocity = '0 0 0';
-        return;
+        if (real_angle_x >= 180)
+            real_angle_x -= 360;
     }
+    else
+    {
+        if (real_angle_x <= -180)
+            real_angle_x += 360;
+    }
 
-    wish_angle = normalize(self.enemy.origin - self.origin);
+    if (real_angle_y > self.tur_head.angles_y)
+    {
+        if (real_angle_y >= 180)
+            real_angle_y -= 360;
+    }
+    else
+    {
+        if (real_angle_y <= -180)
+            real_angle_y += 360;
+    }
+
+    turn_limit = cvar("g_turrets_unit_ewheel_turnrate");
+    // Convert from dgr / sec to dgr / tic
+    turn_limit    = turn_limit / (1 / self.ticrate);
+    angle_ofs     = fabs(real_angle_y);
+    real_angle_y  = bound(turn_limit * -1,real_angle_y,turn_limit);
+    self.angles_y = (self.angles_y + real_angle_y);
+
+    // Simulate banking
+    self.angles_z = bound(-45,real_angle_y * -1,45);
+
+
+    if (self.frame > 40)
+        self.frame = 1;
+
+    makevectors(self.angles);
+
+    if (self.tur_dist_enemy > self.target_range_optimal)
+    {
+        if ( angle_ofs < 10 )
+        {
+            self.frame += 2;
+            movelib_move(v_forward * EWHEEL_ACCEL_FAST,EWHEEL_MAXSPEED,0,EWHEEL_MASS,0);
+        }
+        else if (angle_ofs < 16)
+        {
+            self.frame += 0.5;
+            movelib_move(v_forward,EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_SLOW);
+        }
+        else
+        {
+            movelib_move('0 0 0',EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_FAST);
+        }
+    }
+    else
+        movelib_move('0 0 0',EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_FAST);
+}
+
+void ewheel_roammove()
+{
+    movelib_move(v_forward,EWHEEL_MAXSPEED,0,EWHEEL_MASS,EWHEEL_BREAK_SLOW);
+    self.angles_z = 0;
+
+    /*
+    vector wish_angle,real_angle,steer,avoid;
+    float turn_limit,angle_ofs;
+    float dist;
+
+    return;
+
+    dist = vlen(self.origin - self.pos1);
+
+    //steer = steerlib_attract2(point,0.5,2000,0.95);
+    steer = steerlib_pull(self.pos1);
+    avoid = steerlib_traceavoid(0.3,350);
+
+    wish_angle = normalize(avoid * 0.5 + steer);
     wish_angle = vectoangles(wish_angle);
     real_angle = wish_angle - self.angles;
 
-    if (real_angle_y < 0) real_angle_y += 360;
-    if (real_angle_y > 180) real_angle_y -= 360;
+    real_angle_y = shortangle_f(real_angle_y,self.angles_y);
 
     turn_limit = cvar("g_turrets_unit_ewheel_turnrate");
     // Convert from dgr/sec to dgr/tic
     turn_limit  = turn_limit / (1 / self.ticrate);
+    angle_ofs = fabs(real_angle_y);
+
     real_angle_y = bound(turn_limit * -1,real_angle_y,turn_limit);
-    self.angles_y = self.angles_y + real_angle_y;
-    self.angles_z = bound(-10,real_angle_y * -1,10);
+    self.angles_y = (self.angles_y + real_angle_y);
 
+    self.angles_z = bound(-12,real_angle_y * -1,12);
+
     if(self.frame > 40)
         self.frame = 1;
 
-    self.angles_z = 0;
-    if(self.tur_dist_enemy > self.target_range_optimal)
+    makevectors(self.angles);
+    float lspeed;
+    lspeed = vlen(self.velocity);
+
+    if((dist < 64)||(self.phase < time))
     {
-        self.angles_z = bound(-15,real_angle_y * -1,15);
-        makevectors(self.angles);
-        self.velocity = v_forward * 250;
-        self.frame += 2;
-        return;
+        movelib_move('0 0 0',150,0,50,200);
+        self.pos1 = self.origin + v_forward * 256 + randomvec() * 128;
+        self.pos1_z = self.origin_z;
+        self.phase = time + 5;
     }
+    else if(dist < 128)
+    {
+        self.frame += 1;
+        if(lspeed > 100)
+            movelib_move(v_forward * 50,150,0,50,50);
+        else
+            movelib_move(v_forward * 100,150,0,50,0);
+    }
+    else
+    {
+        self.frame += 1;
+        if(angle_ofs > 10)
+            movelib_move(v_forward * 50,150,0,50,50);
+        else
+            movelib_move(v_forward * 250,150,0,50,0);
+    }
+    */
+}
 
-    self.velocity = '0 0 0';
+void ewheel_postthink()
+{
+    if (self.enemy)
+        ewheel_enemymove();
+    else
+        ewheel_roammove();
 
-
 }
 
+
 void ewheel_respawnhook()
 {
-
-
     setorigin(self,self.pos1);
 
     //self.angles = self.wkr_spawn.angles;
@@ -165,6 +276,7 @@
     //self.flags      = FL_CLIENT;
     self.iscreature = TRUE;
     self.movetype   = MOVETYPE_WALK;
+    self.gravity = 0.01;
     self.solid      = SOLID_SLIDEBOX;
     self.takedamage = DAMAGE_AIM;
 

Modified: trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -35,7 +35,7 @@
 
 void beam_think()
 {
-    if ((time > self.cnt)||(self.owner.deadflag != DEAD_NO))
+    if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
     {
         self.owner.attack_finished_single = time + self.owner.shot_refire;
         self.owner.fireflag = 2;

Modified: trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_walker.qc	2009-01-09 16:45:04 UTC (rev 5473)
+++ trunk/data/qcsrc/server/tturrets/units/unit_walker.qc	2009-01-09 16:45:52 UTC (rev 5474)
@@ -1,3 +1,5 @@
+//#define rocket_rack tur_head.enemy
+
 #define ANIM_NO 0
 #define ANIM_WALK 1
 #define ANIM_RUN 1.1
@@ -8,6 +10,7 @@
 #define ANIM_LAND 5
 #define ANIM_PAIN 6
 #define ANIM_MEELE 7
+
 .float animflag;
 
 .entity wkr_props;
@@ -27,33 +30,29 @@
 .entity goalstack28, goalstack29, goalstack30, goalstack31;
 */
 
+
 float walker_firecheck()
 {
-    if (!turret_stdproc_firecheck()) return 0;
-    //if(self.tur_cannon.frame != 0) return 0;
-
-    //if(self.walking  == 1) self.walking = 2;
-    //if(self.walking != 0)
-    //    return 0;
-
-    return 1;
+    return turret_stdproc_firecheck();
 }
 
-void walker_meele_dmg()
+void walker_meele_do_dmg()
 {
     vector where;
     entity e;
-
     makevectors(self.angles);
     where = self.origin + v_forward * 128;
 
-    e = findradius(where,80);
+    e = findradius(where,128);
     while (e)
     {
         if (turret_validate_target(self,e,self.target_validate_flags))
             if (e != self)
-                Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg "),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
+            {
+                //bprint(self.netname, " is meele hitting ",e.netname,"\n");
+                Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg"),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
 
+            }
         e = e.chain;
     }
 }
@@ -61,27 +60,22 @@
 void walker_animate()
 {
 
-    if (self.tur_head.frame != 0)
-        self.tur_head.frame = self.tur_head.frame +1;
-
-    if (self.tur_head.frame > 12)
-        self.tur_head.frame = 0;
-
-
     switch (self.animflag)
     {
     case ANIM_NO:
-        //if(self.frame != 0)
-        //    self.frame = 0;
+        if(self.frame != 0)
+            self.frame = 0;
         break;
 
     case ANIM_WALK:
         self.frame = self.frame + 1;
         if (self.frame > 25)
             self.frame = 5;
+
         break;
 
     case ANIM_RUN:
+
         self.frame = self.frame + 2;
         if (self.frame > 25)
             self.frame = 5;
@@ -114,7 +108,7 @@
         break;
 
     case ANIM_PAIN:
-        if (self.frame < 90) self.frame = 90;
+        if (self.frame < 60) self.frame = 90;
         self.frame = self.frame + 1;
         if (self.frame > 95)
             self.animflag = ANIM_NO;
@@ -125,7 +119,7 @@
         self.frame = self.frame + 1;
 
         if (self.frame == 133)
-            walker_meele_dmg();
+            walker_meele_do_dmg();
 
         if (self.frame > 140)
             self.animflag = ANIM_NO;
@@ -133,6 +127,7 @@
     }
 }
 
+
 void walker_rocket_explode()
 {
     vector org2;
@@ -148,11 +143,7 @@
     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", 1, ATTN_NORM);
     org2 = findbetterlocation (self.origin, 16);
 
-    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-    WriteByte (MSG_BROADCAST, 78);
-    WriteCoord (MSG_BROADCAST, org2_x);
-    WriteCoord (MSG_BROADCAST, org2_y);
-    WriteCoord (MSG_BROADCAST, org2_z);
+    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
 
     RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world);
 
@@ -166,17 +157,8 @@
     if (self.health <= 0) walker_rocket_explode();
 }
 
-
-/*
-g_turrets_unit_walker_std_rocket_refire
-g_turrets_unit_walker_std_rocket_dmg
-g_turrets_unit_walker_std_rocket_radius
-g_turrets_unit_walker_std_rocket_force
-g_turrets_unit_walker_std_rocket_tunrate
-g_turrets_unit_walker_std_rocket_speed
-g_turrets_unit_walker_std_rocket_speed_add
-*/
-
+//#define WALKER_ROCKET_MOVE movelib_move(newdir * 275,900,0.1,10)
+#define WALKER_ROCKET_MOVE movelib_move_simple(newdir,1000,cvar("g_turrets_unit_walker_std_rocket_tunrate"))
 void walker_rocket_loop();
 void walker_rocket_think()
 {
@@ -218,7 +200,6 @@
 
     olddir = normalize(self.velocity);
 
-    // Accelerate
     m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
 
     // Enemy dead? just keep on the current heading then.
@@ -234,33 +215,36 @@
 
     if (self.enemy)
     {
-        // Predict enemy position
         itime = max(edist / m_speed,1);
-        newdir = normalize((self.enemy.origin + self.tur_shotorg) - self.origin);
+        newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
     }
     else
     {
-        //pre_pos = self.origin + olddir;
         newdir  = olddir;
     }
 
-    // Turn
-    newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
+    WALKER_ROCKET_MOVE;
 
-    self.velocity = newdir * m_speed;
 
     // Turn model
     self.angles = vectoangles(self.velocity);
 
-    if (time+itime < time+0.1)
+    if (time + itime < time + 0.1)
     {
-        self.think = turret_hellion_missile_explode;
+        self.think = walker_rocket_explode;
         self.nextthink = time + itime;
     }
 }
 
 void walker_rocket_loop3()
 {
+    if (self.tur_health < time)
+    {
+        self.think = walker_rocket_explode;
+        self.nextthink = time;
+        return;
+    }
+
     self.nextthink = time + 0.1;
 
     if (vlen(self.origin - self.tur_shotorg) < 128 )
@@ -270,22 +254,24 @@
     }
 
     vector newdir;
-    vector olddir;
-    float m_speed;
 
-    m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
-    olddir = normalize(self.velocity);
-    newdir = normalize(self.tur_shotorg  - self.origin);
-    newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
+    newdir = steerlib_pull(self.tur_shotorg);
+    WALKER_ROCKET_MOVE;
 
-    self.velocity = newdir * m_speed;
     self.angles = vectoangles(self.velocity);
 }
 
 void walker_rocket_loop2()
 {
-    self.nextthink = time + 0;
+    if (self.tur_health < time)
+    {
+        self.think = walker_rocket_explode;
+        self.nextthink = time;
+        return;
+    }
 
+    self.nextthink = time;
+
     if (vlen(self.origin - self.tur_shotorg) < 128 )
     {
         self.tur_shotorg = self.origin - '0 0 200';
@@ -294,21 +280,16 @@
     }
 
     vector newdir;
-    vector olddir;
-    float m_speed;
 
-    m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
-    olddir = normalize(self.velocity);
-    newdir = normalize(self.tur_shotorg  - self.origin);
-    newdir = normalize(olddir + newdir * cvar("g_turrets_unit_walker_std_rocket_tunrate"));
-    self.velocity = newdir * m_speed;
+    newdir = steerlib_pull(self.tur_shotorg);
+    WALKER_ROCKET_MOVE;
+
     self.angles = vectoangles(self.velocity);
 
 }
 
 void walker_rocket_loop()
 {
-
     self.nextthink= time + 0;
     self.tur_shotorg = self.origin + '0 0 400';
     self.think = walker_rocket_loop2;
@@ -352,11 +333,11 @@
 
     rocket.event_damage       = walker_rocket_damage;
 
-    rocket.nextthink          = time + 0.2;
+    rocket.nextthink          = time + 0.25;
     rocket.solid              = SOLID_BBOX;
     rocket.movetype           = MOVETYPE_FLYMISSILE;
     rocket.effects            = EF_LOWPRECISION;
-    rocket.velocity           = ((v_forward + v_up * 0.35) +(randomvec() * 0.15))* cvar("g_turrets_unit_walker_std_rocket_speed");
+    rocket.velocity           = ((v_forward + v_up * 0.25) +(randomvec() * 0.1))* cvar("g_turrets_unit_walker_std_rocket_speed");
     rocket.angles             = vectoangles(rocket.velocity);
     rocket.touch              = walker_rocket_explode;
     rocket.flags              = FL_PROJECTILE;
@@ -367,18 +348,27 @@
 
 }
 
+/*
 #define s_turn 10
 #define s_walk 100
 #define s_run 300
 #define s_accel1 8
 #define s_accel2 16
 #define s_decel 8
+*/
 
 void rv_think()
 {
     float f;
     vector org;
+    entity oldself;
 
+    if(self.owner.deadflag != DEAD_NO)
+    {
+        remove(self);
+        return;
+    }
+
     self.cnt = self.cnt -1;
 
     if (self.cnt < 0)
@@ -395,233 +385,198 @@
     org = self.owner.origin + gettaginfo(self.owner,f);
 
 
+
     self.nextthink = time + 0.2;
+    oldself = self;
     self = self.owner;
     walker_fire_rocket(org);
+    self=oldself;
 }
 
+/*
+void acb_run()
+{
+    //bprint("run\n");
+    animation_set(self,5,25,40,AF_ENDCALLBACK,5);
+}
+void acb_walk()
+{
+    bprint("walk\n");
+    animation_set(self,5,25,20,AF_ENDCALLBACK,5);
+}
+void acb_meele()
+{
+    walker_do_meele();
+}
+
+void set_acb(void() acb_func)
+{
+    self.animator_callback = acb_func;
+    if(animation_query(self) != AS_RUNNING)
+    {
+        bprint("Not running\n");
+        acb_func();
+    }
+    else
+    {
+        if not(self.animator.anim_flags & AF_ENDCALLBACK)
+            self.animator.anim_flags = self.animator.anim_flags | AF_ENDCALLBACK;
+    }
+}
+*/
+
 void walker_postthink()
 {
     vector wish_angle;
     vector real_angle;
-    float turn_limit;
+    vector steer;
+    float vel;
 
-    if ((self.flags & FL_ONGROUND)&&(self.animflag != ANIM_MEELE))
-        self.animflag = ANIM_NO;
+    //if (self.flags & FL_ONGROUND)
+    //if (self.animflag != ANIM_MEELE)
+    //    self.animflag = ANIM_NO;
 
+    if (self.tur_head.attack_finished_single < time)
     if (self.enemy)
-        if (self.tur_head.attack_finished_single < time)
-        {
-            entity rv;
-            rv = spawn();
-            rv.think = rv_think;
-            rv.nextthink = time;
-            rv.cnt = 4;
-            rv.owner = self;
+    {
+        entity rv;
 
-            self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
-        }
+        rv = spawn();
+        rv.think = rv_think;
+        rv.nextthink = time;
+        rv.cnt = 4;
+        rv.owner = self;
 
+        self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
+    }
 
-    if (self.checkpoint_path)
+    // Do we have a path?
+    if (self.pathcurrent)
     {
-        if (vlen(self.origin  - self.goalcurrent.origin) < 64)
-            if (self.goalcurrent.path_next == world)
+        //set_acb(acb_walk);
+        self.animflag = ANIM_WALK;
+
+        // Are we close enougth to a path node to switch to the next?
+        if (vlen(self.origin  - self.pathcurrent.origin) < 64)
+            if (self.pathcurrent.path_next == world)
             {
+                // Path endpoint reached
+                pathlib_deletepath(self.pathcurrent.owner);
+                self.pathcurrent = world;
 
-                self.checkpoint_path = world; // Path endpoint reached, go roaming.
+                if(self.pathgoal)
+                {
+                    if(self.pathgoal.use)
+                        self.pathgoal.use();
+
+                    if(self.pathgoal.enemy)
+                    {
+                        self.pathcurrent = pathlib_makepath(self.pathgoal.origin,self.pathgoal.enemy.origin,PLF_GROUNDSNAP,1500,2,PT_QUICKBOX);
+                        self.pathgoal = self.pathgoal.enemy;
+                    }
+                }
+                else
+                    self.pathgoal = world;
             }
             else
-                self.goalcurrent = self.goalcurrent.path_next;
+                self.pathcurrent = self.pathcurrent.path_next;
 
-        self.animflag = ANIM_WALK;
+        steer = steerlib_attract2(self.pathcurrent.origin,0.5,2000,0.95);
+        vel = 150;
     }
     else // Roaming mode
     {
-
         if (self.enemy)
         {
-            wish_angle = angleofs(self,self.enemy); //normalize(self.origin-self.enemy.origin);
+            wish_angle = angleofs(self,self.enemy);
+            steer = steerlib_pull(self.enemy.origin);
 
             if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))
             {
-
                 if (fabs(wish_angle_y) < 15)
+                {
+                    vel = 0;
+                    //set_acb(acb_meele);
+                    //walker_do_meele();
                     self.animflag = ANIM_MEELE;
+                    return;
+                }
             }
             else
             {
                 if (fabs(wish_angle_y) < 15)
+                {
+                    //set_acb(acb_run);
                     self.animflag = ANIM_RUN;
+                    vel = 300;
+                }
                 else if (fabs(wish_angle_y) < 30)
+                {
+                    //set_acb(acb_walk);
                     self.animflag = ANIM_WALK;
+                    vel = 150;
+                }
                 else
-                    self.animflag = ANIM_TURN;
+                {
+                    //set_acb(acb_walk);
+                    self.animflag = ANIM_WALK;
+                    vel = 50;
+                }
             }
-
         }
         else
+        {
+            vel = 0;
+
             if(self.animflag != ANIM_MEELE)
                 self.animflag = ANIM_NO;
+        }
     }
 
+    // Align the walker to the ground
 
-    float s_speed;
+    self.angles_x = self.angles_x  * -1;
+    makevectors(self.angles);
+    self.angles_x = self.angles_x  * -1;
 
-    s_speed = vlen(self.velocity);
+    traceline(self.origin + '0 0 15', self.origin - '0 0 150' ,MOVE_WORLDONLY,self);
+    wish_angle = (trace_endpos);
+    traceline(self.origin  + v_forward * 10 + '0 0 15', self.origin + v_forward * 10 - '0 0 150' ,MOVE_WORLDONLY,self);
+    real_angle = vectoangles(normalize( trace_endpos - wish_angle));
 
-    // Turn on the spot
-    if (self.animflag == ANIM_TURN)
-    {
-        if (self.enemy)
-            wish_angle = normalize(self.enemy.origin - self.origin);
-        else
-            wish_angle = normalize(self.goalcurrent.origin - self.origin);
+    self.angles_x = real_angle_x;
+    self.angles_z = real_angle_z;
 
-        wish_angle = vectoangles(wish_angle);
-
-        real_angle = wish_angle - self.angles;
-
-        if (real_angle_x < 0) real_angle_x += 360;
-        if (real_angle_x > 180) real_angle_x -= 360;
-
-        if (real_angle_y < 0) real_angle_y += 360;
-        if (real_angle_y > 180) real_angle_y -= 360;
-
-        turn_limit = cvar("g_turrets_unit_walker_turn_turnrate");
-        // Convert from dgr/sec to dgr/tic
-        turn_limit  = turn_limit / (1 / self.ticrate);
-
-        //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
-        real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
-
-        self.angles_y = self.angles_y + real_angle_y;
-
-        if (self.enemy)
-            v_forward = normalize(self.enemy.origin - self.origin);
-        else
-            v_forward = normalize(self.goalcurrent.origin - self.origin);
-
-        makevectors(self.angles);
-
-        if (s_speed > s_turn)
-            self.velocity = (v_forward * max((s_speed - s_decel),s_turn));
-        if (s_speed < s_turn)
-            self.velocity = (v_forward * min((s_speed + s_accel1),s_turn));
+    if(vel == 0)
+    {
+        self.velocity = '0 0 0';
+        //animator_remove(self);
     }
-    else if (self.animflag == ANIM_WALK) // Gg walking
+    else
     {
-        if (self.goalcurrent)
-            wish_angle = normalize(self.goalcurrent.origin - self.origin);
-        else
-            if (self.enemy)
-                wish_angle = normalize(self.enemy.origin - self.origin);
-            else
-                wish_angle = self.angles;
+        steer  = steer * 0.5  + steerlib_traceavoid(0.3,256);
+        float vz;
+        vz = self.velocity_z;
+        movelib_move_simple(steer * 200,vel,0.5);
+        self.velocity_z = vz;
 
+        wish_angle = vectoangles(self.velocity);
 
-        wish_angle = vectoangles(wish_angle);                  // And make a angle
         real_angle = wish_angle - self.angles;
 
-        if (real_angle_x < 0) real_angle_x += 360;
-        if (real_angle_x > 180) real_angle_x -= 360;
+        real_angle_y = shortangle_f(real_angle_y,self.angles_y);
 
-        if (real_angle_y < 0) real_angle_y += 360;
-        if (real_angle_y > 180) real_angle_y -= 360;
-
-        turn_limit = cvar("g_turrets_unit_walker_walk_turnrate");
-        // Convert from dgr/sec to dgr/tic
-        turn_limit  = turn_limit / (1 / self.ticrate);
-
-        //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
-        real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
-
-        self.angles_y = self.angles_y + real_angle_y;
-
-        if (self.goalcurrent)
-            v_forward = normalize(self.goalcurrent.origin - self.origin);
-        else
-            if (self.enemy)
-                v_forward = normalize(self.enemy.origin - self.origin);
-
-        makevectors(self.angles);
-        self.velocity = v_forward * s_walk;
-
-        //if(self.flags & FL_ONGROUND)
-        /*
-        {
-            float s_z;
-            s_z = self.velocity_z;
-            if(s_speed > s_walk)
-                self.velocity = (v_forward * max((s_speed - s_decel),s_walk));
-            if(s_speed <= s_walk)
-                self.velocity = (v_forward * min((s_speed + s_accel1),s_walk));
-            self.velocity_z = s_z;//s_walk;
-        }
-        */
-
-
+        self.angles_y = self.angles_y + bound(-5,real_angle_y,5);
     }
-    else if (self.animflag == ANIM_RUN) // Move fast, turn slow
-    {
-        if (self.goalcurrent)
-            wish_angle = normalize(self.goalcurrent.origin - self.origin);
-        else
-            if (self.enemy)
-                wish_angle = normalize(self.enemy.origin - self.origin);
-            else
-                wish_angle = self.angles;
+    walker_animate();
 
-        wish_angle = vectoangles(wish_angle);                  // And make a angle
-        real_angle = wish_angle - self.angles;
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame = self.tur_head.frame +1;
 
-        if (real_angle_x < 0) real_angle_x += 360;
-        if (real_angle_x > 180) real_angle_x -= 360;
+    if (self.tur_head.frame > 12)
+        self.tur_head.frame = 0;
 
-        if (real_angle_y < 0) real_angle_y += 360;
-        if (real_angle_y > 180) real_angle_y -= 360;
 
-        turn_limit = cvar("g_turrets_unit_walker_run_turnrate");
-        // Convert from dgr/sec to dgr/tic
-        turn_limit  = turn_limit / (1 / self.ticrate);
-
-        //real_angle_x = bound((-1 * turn_limit),real_angle_x, turn_limit);
-        real_angle_y = bound((-1 * turn_limit),real_angle_y, turn_limit);
-
-        self.angles_y = self.angles_y + real_angle_y;
-
-
-        if (self.enemy)
-            v_forward = normalize(self.enemy.origin - self.origin);
-        else
-            v_forward = normalize(self.goalcurrent.origin - self.origin);
-
-        makevectors(self.angles);
-
-        if (self.flags & FL_ONGROUND)
-        {
-            if (s_speed > s_run)
-                self.velocity = (v_forward * max((s_speed - s_decel),s_run));
-            if (s_speed <= s_run)
-                self.velocity = (v_forward * min((s_speed + s_accel2),s_run));
-        }
-    }
-    else
-    {
-
-        if (self.flags & FL_ONGROUND)
-        {
-            makevectors(self.angles);
-            if (s_speed > 0)
-                self.velocity = min(s_speed - s_decel,0) * v_forward;
-        }
-    }
-
-
-
-    walker_animate();
-
-
 }
 
 void walker_attack()
@@ -659,11 +614,14 @@
     self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
 }
 
+
 void walker_respawnhook()
 {
     vector vtmp;
     entity e;
 
+    //load_unit_settings(self.rocket_rack,"walker_std_rocket",1);
+
     self.origin = self.wkr_spawn.origin;
     self.wkr_props.solid = SOLID_BBOX;
     self.wkr_props.alpha = 1;
@@ -680,46 +638,48 @@
         {
             bprint("Warning! initital waypoint for Walker does NOT exsist!\n");
             self.target = "";
-
-            //remove(self);
-            //return;
         }
 
         if (e.classname != "turret_checkpoint")
             dprint("Warning: not a turrret path\n");
         else
-            self.goalcurrent = e;
+        {
+            self.pathcurrent = pathlib_makepath(self.origin,e.origin,PLF_GROUNDSNAP,500,2,PT_QUICKBOX);
+            self.pathgoal = e;
+        }
     }
 }
 void walker_diehook()
 {
+    //animator_remove(self);
 
+    if(self.pathcurrent)
+        pathlib_deletepath(self.pathcurrent.owner);
+
+    self.pathcurrent = world;
+
     self.wkr_props.solid = SOLID_NOT;
     self.wkr_props.alpha = -1;
+
+    if(self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+    {
+
+        remove(self.wkr_props);
+        //remove(self.rocket_rack);
+        remove(self.wkr_spawn);
+    }
+
 }
 
 //.string target_start;
 void turret_walker_dinit()
 {
-    if (self.netname == "")      self.netname     = "Walker Turret";
 
-    /*
-    if (self.target != "")
-    {
-        e = find(world,targetname,self.target);
-        if (!e)
-        {
-            bprint("Warning! initital waypoint for Walker does NOT exsist!\n");
-            self.target = "";
-        }
+    entity e;
 
-        if (e.classname != "turret_checkpoint")
-            dprint("Warning: not a turrret path\n");
-        else
-            self.goalcurrent = e;
-    }
-    */
+    if (self.netname == "")      self.netname     = "Walker Turret";
 
+
     self.wkr_props = spawn();
     self.wkr_spawn = spawn();
 
@@ -754,6 +714,7 @@
     self.wkr_spawn.angles   = self.angles;
     self.wkr_spawn.solid    = SOLID_NOT;
 
+
     traceline(self.wkr_spawn.origin + '0 0 10', self.wkr_spawn.origin - '0 0 10000', MOVE_NOMONSTERS, self);
     setorigin(self.wkr_spawn,trace_endpos + '0 0 4');
 
@@ -773,7 +734,7 @@
     //setsize(self,'-70 -70 0','70 70 55');
 
     self.tur_shotorg = v;
-    self.tur_aimorg  = v;
+    self.tur_aimorg  = v;// + '0 0 10';
 
     self.idle_aim = '0 0 0';
 
@@ -786,6 +747,26 @@
 
     self.turret_postthink = walker_postthink;
 
+    if (self.target != "")
+    {
+        e = find(world,targetname,self.target);
+        if (!e)
+        {
+            bprint("Warning! initital waypoint for Walker does NOT exsist!\n");
+            self.target = "";
+        }
+
+        if (e.classname != "turret_checkpoint")
+            dprint("Warning: not a turrret path\n");
+        else
+        {
+            self.pathcurrent = pathlib_makepath(self.origin,e.origin,PLF_GROUNDSNAP,500,2,PT_QUICKBOX);
+            self.pathgoal = e;
+        }
+    }
+
+    //self.solid    = SOLID_NOT;
+
 }
 
 




More information about the nexuiz-commits mailing list