[nexuiz-commits] r6318 - trunk/data/qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Mar 27 04:57:06 EDT 2009


Author: tzork
Date: 2009-03-27 04:57:06 -0400 (Fri, 27 Mar 2009)
New Revision: 6318

Modified:
   trunk/data/qcsrc/server/movelib.qc
   trunk/data/qcsrc/server/pathlib.qc
   trunk/data/qcsrc/server/steerlib.qc
   trunk/data/qcsrc/server/verbstack.qc
Log:
Lib updates

Modified: trunk/data/qcsrc/server/movelib.qc
===================================================================
--- trunk/data/qcsrc/server/movelib.qc	2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/movelib.qc	2009-03-27 08:57:06 UTC (rev 6318)
@@ -1,102 +1,104 @@
-/**
-    Simulate drag
-    self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
-**/
-vector movelib_dragvec(float drag, float exp)
-{
-    float lspeed,ldrag;
-
-    lspeed = vlen(self.velocity);
-    ldrag = lspeed * drag;
-    ldrag = ldrag * (drag * exp);
-    ldrag = 1 - (ldrag / lspeed);
-
-    return self.velocity * ldrag;
-}
-
-/**
-    Simulate drag
-    self.velocity = movelib_vdrag(somespeed,0.01,0.7);
-**/
-float movelib_dragflt(float fspeed,float drag,float exp)
-{
-    float ldrag;
-
-    ldrag = fspeed * drag;
-    ldrag = ldrag * ldrag * exp;
-    ldrag = 1 - (ldrag / fspeed);
-
-    return ldrag;
-}
-
-/**
-    Do a inertia simulation based on velocity.
-    Basicaly, this allows you to simulate loss of steering with higher speed.
-    self.velocity = movelib_inertia_fromspeed(self.velocity,newvel,1000,0.1,0.9);
-**/
-vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
-{
-    float influense;
-
-    influense = vlen(self.velocity) * (1 / vel_max);
-
-    influense = bound(newmin,influense,oldmax);
-
-    return (vel_new * (1 - influense)) + (self.velocity * influense);
-}
-
-vector movelib_inertmove(vector new_vel,float new_bias)
-{
-    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;
+.vector moveto;
+
+/**
+    Simulate drag
+    self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
+**/
+vector movelib_dragvec(float drag, float exp)
+{
+    float lspeed,ldrag;
+
+    lspeed = vlen(self.velocity);
+    ldrag = lspeed * drag;
+    ldrag = ldrag * (drag * exp);
+    ldrag = 1 - (ldrag / lspeed);
+
+    return self.velocity * ldrag;
+}
+
+/**
+    Simulate drag
+    self.velocity = movelib_vdrag(somespeed,0.01,0.7);
+**/
+float movelib_dragflt(float fspeed,float drag,float exp)
+{
+    float ldrag;
+
+    ldrag = fspeed * drag;
+    ldrag = ldrag * ldrag * exp;
+    ldrag = 1 - (ldrag / fspeed);
+
+    return ldrag;
+}
+
+/**
+    Do a inertia simulation based on velocity.
+    Basicaly, this allows you to simulate loss of steering with higher speed.
+    self.velocity = movelib_inertia_fromspeed(self.velocity,newvel,1000,0.1,0.9);
+**/
+vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
+{
+    float influense;
+
+    influense = vlen(self.velocity) * (1 / vel_max);
+
+    influense = bound(newmin,influense,oldmax);
+
+    return (vel_new * (1 - influense)) + (self.velocity * influense);
+}
+
+vector movelib_inertmove(vector new_vel,float new_bias)
+{
+    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;
-    vector breakvec;
-
-    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)
+    vector breakvec;
+
+    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)
         {
             breakvec = (normalize(self.velocity) * (breakforce / mass) * deltatime);
-            self.velocity = self.velocity - breakvec;
+            self.velocity = self.velocity - breakvec;
         }
-
-        self.velocity = self.velocity + force * (acceleration * deltatime);
+
+        self.velocity = self.velocity + force * (acceleration * deltatime);
     }
-
-    if(drag)
+
+    if (drag)
         self.velocity = movelib_dragvec(drag, 1);
 
-    if(self.waterlevel > 1)
+    if (self.waterlevel > 1)
     {
         self.velocity = self.velocity + force * (acceleration * deltatime);
         self.velocity = self.velocity + '0 0 0.05' * sv_gravity * deltatime;
     }
-    else
-        self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
+    else
+        self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
 
-    mspeed = vlen(self.velocity);
-
-    if(max_velocity)
-        if(mspeed > max_velocity)
-            self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
+    mspeed = vlen(self.velocity);
+
+    if (max_velocity)
+        if (mspeed > max_velocity)
+            self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
 }
 
 /*
@@ -117,7 +119,7 @@
 
     self.movelib_lastupdate = time;
 }
-
+
 void movelib_update(vector dir,float force)
 {
     vector acceleration;
@@ -158,11 +160,11 @@
 
 }
 */
-
-void movelib_move_simple(vector newdir,float velo,float blendrate)
-{
-    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
-}
+
+void movelib_move_simple(vector newdir,float velo,float blendrate)
+{
+    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
+}
 void movelib_beak_simple(float force)
 {
     float mspeed;
@@ -176,28 +178,37 @@
 
 void movelib_groundalign4point(float spring_length,float spring_up)
 {
-    vector a,b,c,d,e,r,push_angle;
+    vector a,b,c,d,e,r,push_angle, ahead,side;
+
     push_angle_y = 0;
     r = (self.absmax + self.absmin) * 0.5 + (v_up * spring_up);
     e = v_up * spring_length;
 
-    a = r + (v_forward * self.maxs_x) + (v_right * self.maxs_y);
-    b = r + (v_forward * self.maxs_x) - (v_right * self.maxs_y);
-    c = r - (v_forward * self.maxs_x) + (v_right * self.maxs_y);
-    d = r - (v_forward * self.maxs_x) - (v_right * self.maxs_y);
+    // Put springs slightly inside bbox
+    ahead = v_forward * (self.maxs_x * 0.85);
+    side  = v_right   * (self.maxs_y * 0.85);
 
+    a = r + ahead + side;
+    b = r + ahead - side;
+    c = r - ahead + side;
+    d = r - ahead - side;
+
     traceline(a, a - e,MOVE_NORMAL,self);
     a_z =  (1 - trace_fraction);
     r = trace_endpos;
+
     traceline(b, b - e,MOVE_NORMAL,self);
     b_z =  (1 - trace_fraction);
     r += trace_endpos;
+
     traceline(c, c - e,MOVE_NORMAL,self);
     c_z =  (1 - trace_fraction);
     r += trace_endpos;
+
     traceline(d, d - e,MOVE_NORMAL,self);
     d_z =  (1 - trace_fraction);
     r += trace_endpos;
+
     a_x = r_z;
     r = self.origin;
     r_z = r_z;

Modified: trunk/data/qcsrc/server/pathlib.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib.qc	2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/pathlib.qc	2009-03-27 08:57:06 UTC (rev 6318)
@@ -7,6 +7,8 @@
     .entity path_prev;
 #endif
 
+#define medium spawnshieldtime
+
 entity openlist;
 entity closedlist;
 entity scraplist;
@@ -40,17 +42,13 @@
 entity best_open_node;
 .float is_path_node;
 
-
-
-#define DEBUGPATHING
+//#define DEBUGPATHING
 #ifdef DEBUGPATHING
 float edge_show(vector point,float fsize);
 void mark_error(vector where,float lifetime);
 void mark_info(vector where,float lifetime);
 entity mark_misc(vector where,float lifetime);
 
-
-
 void pathlib_showpath(entity start)
 {
     entity e;
@@ -91,19 +89,6 @@
 
 #endif
 
-/*
-float pathlib_stdproc_path_validate(vector start,vector end)
-{
-    tracebox(start, self.mins * 2, self.maxs * 2, end, MOVE_WORLDONLY, self);
-
-    if(vlen(trace_endpos - end) < 5)
-        return 1;
-
-    return 0;
-}
-*/
-
-
 void pathlib_deletepath(entity start)
 {
     entity e;
@@ -133,16 +118,13 @@
     return vret;
 }
 
-
-#define floor_failmask (DPCONTENTS_SLIME | DPCONTENTS_LAVA)
-// | DPCONTENTS_MONSTERCLIP | DPCONTENTS_DONOTENTER
-float walknode_stepsize;
+float  walknode_stepsize;
 vector walknode_stepup;
 vector walknode_maxdrop;
 vector walknode_boxup;
 vector walknode_boxmax;
 vector walknode_boxmin;
-float pathlib_movenode_goodnode;
+float  pathlib_movenode_goodnode;
 
 float floor_ok(vector point)
 {
@@ -173,15 +155,16 @@
     return 0;
 }
 
+#define inwater(point) (pointcontents(point) == CONTENT_WATER)
+/*
 float inwater(vector point)
 {
     if(pointcontents(point) == CONTENT_WATER)
         return 1;
-
     return 0;
 }
+*/
 
-//#define _pcheck(p) traceline(p+z_up,p-z_down,MOVE_WORLDONLY,self); if(trace_fraction == 1.0) return 1
 #define _pcheck(p) traceline(p+z_up,p-z_down,MOVE_WORLDONLY,self); if not(floor_ok(trace_endpos)) return 1
 float edge_check(vector point,float fsize)
 {
@@ -245,17 +228,13 @@
         if(pointcontents(surface) == CONTENT_EMPTY)
             break;
     }
-    //mark_error(surface,10);
 
     if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
         return end;
 
     tracebox(start + '0 0 64', walknode_boxmin,walknode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
     if(trace_fraction == 1)
-    {
         pathlib_movenode_goodnode = 1;
-        //mark_error(end + '0 0 64',30);
-    }
 
     if(fabs(surface_z - end_z) > 32)
         pathlib_movenode_goodnode = 0;
@@ -287,13 +266,6 @@
 {
     pathlib_movenode_goodnode = 0;
 
-    /*
-    if(pointcontents(start) == CONTENT_EMPTY)
-        return end;
-
-    if(pointcontents(end) == CONTENT_EMPTY)
-        return end;
-    */
     end_x = fsnap(end_x, pathlib_gridsize);
     end_y = fsnap(end_y, pathlib_gridsize);
 
@@ -394,24 +366,48 @@
         return parent.pathlib_node_g + static_cost;
 }
 
+float pathlib_g_static_water(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + static_cost;
+}
+
 float pathlib_g_euclidean(entity parent,vector to, float static_cost)
 {
-    return vlen(parent.origin - to);
+    return parent.pathlib_node_g + vlen(parent.origin - to);
 }
+float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + vlen(parent.origin - to) * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + vlen(parent.origin - to);
+}
 
 var float(vector from,vector to) pathlib_heuristic;
+
+/**
+    Manhattan Menas we expect to move up,down left or right
+    No diagonal moves espected. (like moving bewteen city blocks)
+**/
 float pathlib_h_manhattan(vector a,vector b)
 {
     //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
 
     float h;
-    h = fabs(a_x - b_x);
-    h = h + fabs(a_y - b_y);
-    h = pathlib_gridsize * h;
+    h  = fabs(a_x - b_x);
+    h += fabs(a_y - b_y);
+    h *= pathlib_gridsize;
 
     return h;
 }
 
+/**
+    This heuristic consider both stright and disagonal moves
+    to have teh same cost.
+**/
 float pathlib_h_diagonal(vector a,vector b)
 {
     //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
@@ -424,11 +420,20 @@
     return h;
 }
 
+/**
+    This heuristic only considers the stright line distance.
+    Will usualy mean a lower H then G meaning A* Will speand more
+    and run slower.
+**/
 float pathlib_h_euclidean(vector a,vector b)
 {
     return vlen(a - b);
 }
 
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
+**/
 float pathlib_h_diagonal2(vector a,vector b)
 {
     float h_diag,h_str,h,x,y;
@@ -451,35 +456,12 @@
     return h;
 }
 
-float pathlib_h_diagonal2tbs(vector start,vector point,vector end)
-{
-    float h_diag,h_str,h,x,y;
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
 
-    /*
-    h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
-    h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
-    h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
-    */
 
-    float dx1,dx2,dy1,dy2,fcross;
-    dx1 = point_x - end_x;
-    dy1 = point_y - end_y;
-    dx2 = start_x - end_x;
-    dy2 = start_y - end_y;
-    fcross = fabs(dx1*dy2 - dx2*dy1);
-
-    x = fabs(point_x - end_x);
-    y = fabs(point_y - end_y);
-
-    h_diag = min(x,y);
-    h_str = x + y;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    return h + (fcross * 0.001);
-}
-
+**/
 float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
 {
     float h_diag,h_str,h,x,y,z;
@@ -501,13 +483,11 @@
     float m;
     vector d1,d2;
 
-    m = 0.999;
-    d1 = normalize(preprev - prev);
-    d2 = normalize(prev - point);
-    if(vlen(d1-d2) > 0.6)
-        m = 1;
+    d1 = normalize(preprev - point);
+    d2 = normalize(prev    - point);
+    m = vlen(d1-d2);
+    //bprint("pathlib_h_diagonal2sdp-M = ",ftos(m),"\n");
 
-
     return h * m;
 }
 
@@ -530,13 +510,11 @@
     h =  pathlib_movecost_diag * h_diag;
     h += pathlib_movecost * (h_str - 2 * h_diag);
 
-    //if(inwater(a))
-    //h =
-
     return h;
 }
 
 //#define PATHLIB_USE_NODESCRAP
+#define PATHLIB_NODEEXPIRE 0.05
 float pathlib_scraplist_cnt;
 entity newnode()
 {
@@ -557,6 +535,9 @@
 #endif
     ++pathlib_made_cnt;
     n = spawn();
+#ifdef PATHLIB_NODEEXPIRE
+    n.think      = SUB_Remove;
+    n.nextthink  = time + PATHLIB_NODEEXPIRE;
     return n;
 }
 
@@ -564,11 +545,15 @@
 {
 #ifdef PATHLIB_USE_NODESCRAP
     ++pathlib_scraplist_cnt;
-    n.owner = scraplist;
+
+    n.path_next    = world;
+    n.path_prev    = world;
+    n.is_path_node = FALSE;
+    n.owner        = scraplist;
 #else
-    n.is_path_node = FALSE;
-    n.think = SUB_Remove;
-    n.nextthink= time;
+    //n.is_path_node = FALSE;
+    n.think        = SUB_Remove;
+    n.nextthink    = time;
 #endif
 }
 
@@ -585,19 +570,17 @@
 
     ++pathlib_open_cnt;
 
-    //if(inwater(where))
-    //{
-        //node.waterlevel = 1;
-        //mark_info(where,5);
-    //}
-    //mark_info(where,30);
+    node.medium = pointcontents(where);
+
     return node;
 }
+
 var float pathlib_expandnode(entity node, vector start, vector goal);
 float pathlib_expandnode_star(entity node, vector start, vector goal);
 float pathlib_expandnode_box(entity node, vector start, vector goal);
 
-float pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost)
+var float pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
+float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
 {
     entity node;
     float h,g,f,doedge;
@@ -607,32 +590,19 @@
 
     if(inwater(parent.origin))
     {
-        if(inwater(to))
-        {
-            //bprint("Switch to water tracing\n");
-            pathlib_expandnode = pathlib_expandnode_box;
-            pathlib_movenode   = pathlib_swimnode;
-        }
-        else
-        {
-
-            //bprint("Switch to get out of water tracing\n");
-            pathlib_expandnode = pathlib_expandnode_box;
-            pathlib_movenode   = pathlib_swimnode;
-        }
+        pathlib_expandnode = pathlib_expandnode_box;
+        pathlib_movenode   = pathlib_swimnode;
     }
     else
     {
         if(inwater(to))
         {
-            //bprint("Switch to get into water tracing\n");
             pathlib_expandnode = pathlib_expandnode_box;
             pathlib_movenode   = pathlib_swimnode;
         }
         else
         {
 
-            //bprint("Switch to land tracing\n");
             pathlib_expandnode = pathlib_expandnode_star;
             pathlib_movenode   = pathlib_walknode;
             doedge = 1;
@@ -641,26 +611,16 @@
 
     where = pathlib_movenode(parent.origin,to,0);
     if not(pathlib_movenode_goodnode)
-    {
-        //mark_error(where,15);
         return 0;
-    }
 
     if(doedge)
     if(edge_check(where,pathlib_edge_check_size))
         return 0;
 
-    h = pathlib_heuristic(where,goal);
-
-    /*
     if(parent.path_prev)
-        h = pathlib_h_diagonal2sdp(parent.path_prev.origin,parent.origin,where,goal);
-    else
-        h = pathlib_heuristic(where,goal);
-    */
+        pathlib_h_diagonal2sdp(parent.path_prev.origin,parent.origin,where,goal);
 
-
-    //h = 0;
+    h = pathlib_heuristic(where,goal);
     g = pathlib_cost(parent,where,cost);
     f = g + h;
 
@@ -692,7 +652,6 @@
     }
 
     node = pathlib_mknode(where,parent);
-
     node.pathlib_node_h = h;
     node.pathlib_node_g = g;
     node.pathlib_node_f = f;
@@ -754,14 +713,14 @@
 
     if(vlen(node.origin - goal) <= pathlib_gridsize)
     {
-        //if(vlen(node.origin - goal) < 128)
         vector goalmove;
+
         goalmove = pathlib_walknode(node.origin,goal,1);
         if(pathlib_movenode_goodnode)
-            {
-                goal_node         = node;
-                pathlib_foundgoal = TRUE;
-            }
+        {
+            goal_node         = node;
+            pathlib_foundgoal = TRUE;
+        }
     }
 }
 
@@ -830,14 +789,9 @@
 {
     entity node;
 
-    best_open_node = world;
-
     node = findfloat(world,is_path_node, TRUE);
     while(node)
     {
-        node.path_next = world;
-        node.path_prev = world;
-        node.is_path_node = FALSE;
         dumpnode(node);
         node = findfloat(node,is_path_node, TRUE);
     }
@@ -847,20 +801,96 @@
 
     if(closedlist)
         remove(closedlist);
+
+    best_open_node = world;
+    openlist       = world;
+    closedlist     = world;
 }
 
-entity pathlib_astar(vector from,vector to)
+var float buildpath_nodefilter(vector n,vector c,vector p);
+float buildpath_nodefilter_directional(vector n,vector c,vector p)
 {
+    vector d1,d2;
+
+    d2 = normalize(p - c);
+    d1 = normalize(c - n);
+
+    if(vlen(d1-d2) < 0.25)
+        return 1;
+
+    return 0;
+}
+
+float buildpath_nodefilter_moveskip(vector n,vector c,vector p)
+{
+    pathlib_walknode(p,n,1);
+    if(pathlib_movenode_goodnode)
+        return 1;
+
+    return 0;
+}
+
+entity path_build(entity next, vector where, entity prev, entity start)
+{
     entity path;
-    entity open,n;
 
+    if(prev && next)
+        if(buildpath_nodefilter)
+            if(buildpath_nodefilter(next.origin,where,prev.origin))
+                return next;
+
+
+    path           = spawn();
+    path.owner     = start;
+    path.path_next = next;
+
+    setorigin(path,where);
+
+    if(!next)
+        path.classname = "path_end";
+    else
+    {
+        if(!prev)
+            path.classname = "path_start";
+        else
+            path.classname = "path_node";
+    }
+
+    return path;
+}
+
+entity pathlib_astar(vector from,vector to)
+{
+    entity path, start, end, open, n, ln;
+    float ptime, ftime, ctime;
+
+    ptime = gettime(GETTIME_REALTIME);
+
     pathlib_cleanup();
 
-    pathlib_heuristic  = pathlib_h_diagonal3;
-    pathlib_cost       = pathlib_g_static;
-    pathlib_expandnode = pathlib_expandnode_star;
-    pathlib_movenode   = pathlib_walknode;
+    // Select water<->land capable node make/link
+    pathlib_makenode     = pathlib_makenode_adaptive;
+    // Select XYZ cost estimate
+    pathlib_heuristic    = pathlib_h_diagonal3;
+    // Select distance + waterfactor cost
+    pathlib_cost         = pathlib_g_euclidean_water;
+    // Select star expander
+    pathlib_expandnode   = pathlib_expandnode_star;
+    // Select walk simulation movement test
+    pathlib_movenode     = pathlib_walknode;
+    // Filter final nodes by direction
+    buildpath_nodefilter = buildpath_nodefilter_directional;
 
+    // If the start is in water we need diffrent settings
+    if(inwater(from))
+    {
+        // Select volumetric node expaner
+        pathlib_expandnode = pathlib_expandnode_box;
+
+        // Water movement test
+        pathlib_movenode   = pathlib_swimnode;
+    }
+
     if not(openlist)
         openlist       = spawn();
 
@@ -879,7 +909,7 @@
     pathlib_bestcash_saved = 0;
     pathlib_recycle_cnt    = 0;
 
-    pathlib_gridsize       = 192;
+    pathlib_gridsize       = 128;
     pathlib_movecost       = pathlib_gridsize;
     pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
     pathlib_movecost_waterfactor = 1.1;
@@ -888,24 +918,31 @@
     walknode_boxmax   = self.maxs * 1.5;
     walknode_boxmin   = self.mins * 1.5;
 
-    pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.25);
+    pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.5);
 
     walknode_boxup    = '0 0 2' * self.maxs_z;
     walknode_stepsize = 32;
     walknode_stepup   = '0 0 1' * walknode_stepsize;
     walknode_maxdrop  = '0 0 3' * walknode_stepsize;
 
+    from_x = fsnap(from_x,pathlib_gridsize);
+    from_y = fsnap(from_y,pathlib_gridsize);
+
+    to_x = fsnap(to_x,pathlib_gridsize);
+    to_y = fsnap(to_y,pathlib_gridsize);
+
     dprint("AStar init. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n");
     path = pathlib_mknode(from,world);
     pathlib_close_node(path,to);
     if(pathlib_foundgoal)
     {
-        dprint("A* Goal fond in first square!\n");
+        dprint("AStar: Goal found on first node!\n");
 
         open           = spawn();
         open.owner     = open;
         open.classname = "path_end";
         setorigin(open,path.origin);
+
         pathlib_cleanup();
 
         return open;
@@ -913,8 +950,9 @@
 
     if(pathlib_expandnode(path,from,to) <= 0)
     {
-        dprint("A* pathing fail\n");
+        dprint("AStar path fail.\n");
         pathlib_cleanup();
+
         return world;
     }
 
@@ -939,53 +977,55 @@
 
         if(pathlib_foundgoal)
         {
-            dprint("Path found, re-tracing...\n");
+            dprint("Target found. Rebuilding and filtering path...\n");
+            ftime = gettime(GETTIME_REALTIME);
+            ptime = ftime - ptime;
 
-            open              = goal_node;
-            open.is_path_node = FALSE;
-            open.classname    = "path_end";
-            open.owner        = path;
-            open.path_next    = world;
+            start = path_build(world,path.origin,world,world);
+            end   = path_build(world,goal_node.origin,world,start);
+            ln    = end;
 
-
-            while(open.path_prev != path)
+            open = goal_node;
+            for(open = goal_node; open.path_prev != path; open = open.path_prev)
             {
-                n                 = open;
-                open              = open.path_prev;
-                open.owner        = path;
-                open.path_next    = n;
-
-                open.is_path_node = FALSE;
-                open.classname    = "path_node";
+                n    = path_build(ln,open.origin,open.path_prev,start);
+                ln.path_prev = n;
+                ln = n;
             }
+            start.path_next = n;
+            n.path_prev = start;
+            ftime = gettime(GETTIME_REALTIME) - ftime;
 
-            open.path_prev    = path;
-            path.path_next    = open;
-            path.classname    = "path_master";
-            path.is_path_node = FALSE;
-            path.owner        = path;
-
+            ctime = gettime(GETTIME_REALTIME);
             pathlib_cleanup();
+            ctime = gettime(GETTIME_REALTIME) - ctime;
 
+
 #ifdef DEBUGPATHING
-            dprint("Chain done..\n");
-            pathlib_showpath2(path);
+            pathlib_showpath2(start);
 
+            dprint("Time used -      pathfinding: ", ftos(ptime),"\n");
+            dprint("Time used - rebuild & filter: ", ftos(ftime),"\n");
+            dprint("Time used -          cleanup: ", ftos(ctime),"\n");
+            dprint("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
+            dprint("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_ticrate)),"\n\n");
+            dprint("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
+            dprint("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
+            dprint("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
+            dprint("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
+            dprint("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
 
-            dprint("           Nodes reused: ", ftos(pathlib_recycle_cnt),"\n");
-            dprint("          Nodes created: ", ftos(pathlib_made_cnt),"\n");
-            dprint("       Nodes make/reuse: ", ftos(pathlib_made_cnt / pathlib_recycle_cnt),"\n");
-            dprint("             Nodes open: ", ftos(pathlib_open_cnt),"\n");
-            dprint("           Nodes merged: ", ftos(pathlib_merge_cnt),"\n");
-            dprint("           Nodes closed: ", ftos(pathlib_closed_cnt),"\n");
-            dprint("         Nodes searched: ", ftos(pathlib_searched_cnt),"\n");
+        if(pathlib_recycle_cnt)
+            dprint("Nodes -      make/reuse: ", ftos(pathlib_made_cnt / pathlib_recycle_cnt),"\n");
+        if(pathlib_recycle_cnt)
+            dprint("Nodes -          reused: ", ftos(pathlib_recycle_cnt),"\n");
+
             dprint("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
-            dprint("    Nodes bestcash hits: ", ftos(pathlib_bestcash_hits),"\n");
-            dprint("    Nodes bestcash save: ", ftos(pathlib_bestcash_saved),"\n");
+            dprint("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
+            dprint("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
             dprint("AStar done. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n\n");
-
 #endif
-            return path;
+            return start;
         }
     }
 
@@ -996,3 +1036,5 @@
     return world;
 }
 
+
+

Modified: trunk/data/qcsrc/server/steerlib.qc
===================================================================
--- trunk/data/qcsrc/server/steerlib.qc	2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/steerlib.qc	2009-03-27 08:57:06 UTC (rev 6318)
@@ -1,3 +1,5 @@
+.vector steerto;
+
 /**
     Uniform pull towards a point
 **/
@@ -260,10 +262,48 @@
 
     return (upwish+leftwish+downwish+rightwish) * 0.25;
 
-}
+}
 
+/**
+    Steer towards the direction least obstructed.
+    Run two tracelines in a forward trident, bias each diretion negative if something is found there.
+**/
+vector steerlib_traceavoid_flat(float pitch, float length, vector vofs)
+{
+    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);
+
+}
+
 
 
+
 //////////////////////////////////////////////
 //     Testting                             //
 // Everything below this point is a mess :D //

Modified: trunk/data/qcsrc/server/verbstack.qc
===================================================================
--- trunk/data/qcsrc/server/verbstack.qc	2009-03-27 08:56:37 UTC (rev 6317)
+++ trunk/data/qcsrc/server/verbstack.qc	2009-03-27 08:57:06 UTC (rev 6318)
@@ -1,21 +1,49 @@
-entity verb;
+/// Some default stacks.
 .entity verbs_idle;
 .entity verbs_attack;
 .entity verbs_move;
 
-.float(float eval) verb_call;
+/// This global gets set to the verb in question each time the stack manager calls verb_call
+entity verb;
+
+/// Execure this verb
+#define VCM_DO     0
+/// Return teh value of this verb. Return VS_CALL_REMOVE to delete it.
+#define VCM_EVAL   1
+/// This verb is beeing removed NOW (not sent when verb_call returns VS_CALL_REMOVE)
+#define VCM_REMOVE 2
+
+/// Verb callback
+.float(float message) verb_call;
+
+/// Points to this verb's stack.
 .entity  verbstack;
+
+/// Static value of this verb
 .float verb_static_value;
 
+/// verb_call returns this when a verb in not doable
 #define VS_CALL_NO        0
+/// verb_call(VCM_DO) returns this when a verb is executing
 #define VS_CALL_YES_DOING -1
+/// verb_call(VCM_DO) returns this when a verb did execure and is done
 #define VS_CALL_YES_DONE  -2
+/// verb_call(VCM_DO) returns this when a verb should be deleted by the stack manager
 #define VS_CALL_REMOVE    -3
 
+/**
+    Push a new verb onto the specified stack. Set vrb_life to make it time-limited.
+**/
 entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life)
 {
     entity vrb;
 
+    if not(stack)
+        return world;
+
+    if not(vrb_call)
+        return world;
+
     vrb                   = spawn();
     vrb.owner             = self;
     vrb.verbstack         = stack;
@@ -31,43 +59,48 @@
     return vrb;
 }
 
+/**
+    Find the best verb in this stack and execurte it.
+    ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL or VCM_DO
+**/
 float verbstack_pop(entity stack)
 {
-    entity vrb;
-    entity bestverb,oldself;
-    float value,bestvalue;
+    entity vrb, bestverb, oldself;
+    float  value, bestvalue;
 
     oldself = self;
 
     vrb = findchainentity(verbstack,stack);
     while(vrb)
     {
-        verb = vrb;
-        self = vrb.owner;
-        value = vrb.verb_call(TRUE);
+        verb  = vrb;
+        vrb   = vrb.chain;
+        self  = verb.owner;
+        value = verb.verb_call(VCM_EVAL);
+
         if(value < 0)
         {
             if(value == VS_CALL_REMOVE)
-                remove(vrb);
+                remove(verb);
         }
         else
         {
             if(value > bestvalue)
             {
-                bestverb = vrb;
+                bestverb  = verb;
                 bestvalue = value;
             }
         }
-        vrb = vrb.chain;
     }
 
     if(bestverb)
     {
-        verb = bestverb;
-        self = verb.owner;
-        value = bestverb.verb_call(FALSE);
-            if(value == VS_CALL_REMOVE)
-                remove(bestverb);
+        verb  = bestverb;
+        self  = verb.owner;
+        value = verb.verb_call(VCM_DO);
+
+        if(value == VS_CALL_REMOVE)
+            remove(bestverb);
     }
 
     self = oldself;
@@ -75,11 +108,15 @@
     return value;
 }
 
+/**
+    Find the best verb in this stack and return it.
+    ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL.
+**/
 entity verbstack_pull(entity stack)
 {
     entity vrb;
-    entity bestverb,oldself;
-    float value,bestvalue;
+    entity bestverb, oldself;
+    float  value, bestvalue;
 
     oldself = self;
 
@@ -87,25 +124,50 @@
     while(vrb)
     {
         self = vrb.owner;
-        verb = vrb;
-        value = vrb.verb_call(TRUE);
+
+        verb  = vrb;
+        vrb   = vrb.chain;
+        value = verb.verb_call(VCM_EVAL);
+
         if(value > 0)
         {
             if(value == VS_CALL_REMOVE)
-                remove(vrb);
+                remove(verb);
         }
         else
         {
             if(value > bestvalue)
             {
-                bestverb = vrb;
+                bestverb = verb;
                 bestvalue = value;
             }
         }
-        vrb =vrb.chain;
     }
 
     self = oldself;
 
     return bestverb;
 }
+
+/**
+    Delete every verb on this stack, signaling them with VCM_REMOVE first.
+**/
+void verbstack_flush(entity stack)
+{
+    entity vrb, oldself;
+
+    oldself = self;
+
+    vrb = findchainentity(verbstack,stack);
+    while(vrb)
+    {
+        self = vrb.owner;
+
+        verb = vrb;
+        vrb  = vrb.chain;
+        verb.verb_call(VCM_REMOVE);
+        remove(verb);
+    }
+
+    self = oldself;
+}



More information about the nexuiz-commits mailing list