]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/pathlib/utility.qc
Merge branch 'master' into Lyberta/TeamplayOverhaul2
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / pathlib / utility.qc
index 81d06b2c9a6d494b73ebf5dbce42aee8a3a1efd5..151fb44b56abec6096379d63b351b42a315e7d9a 100644 (file)
-float fsnap(float val,float fsize)
+#include "utility.qh"
+
+#include <server/defs.qh>
+#include <server/miscfunctions.qh>
+#include "pathlib.qh"
+
+bool location_isok(vector point, bool waterok, bool air_isok)
 {
-    return rint(val / fsize) * fsize;
+    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+        return false;
+
+    int pc = pointcontents(point);
+    int pc2 = pointcontents(point - '0 0 1');
+
+    if(pc == CONTENT_EMPTY && pc2 == CONTENT_SOLID)
+        return true;
+    if(pc == CONTENT_EMPTY && pc2 == CONTENT_WATER && waterok)
+        return true;
+    if(pc == CONTENT_EMPTY && pc2 == CONTENT_EMPTY && air_isok)
+        return true;
+    if(pc == CONTENT_WATER && waterok)
+        return true;
+    return false;
 }
 
-vector vsnap(vector point,float fsize)
+entity pathlib_nodeatpoint(vector where)
 {
-    vector vret;
+    ++pathlib_searched_cnt;
 
-    vret_x = rint(point_x / fsize) * fsize;
-    vret_y = rint(point_y / fsize) * fsize;
-    vret_z = ceil(point_z / fsize) * fsize;
+    where.x = fsnap(where.x,pathlib_gridsize);
+    where.y = fsnap(where.y,pathlib_gridsize);
 
-    return vret;
+    entity found = NULL; // TODO: using FOREACH_ENTITY_RADIUS here causes mutex loop warnings, this may need a proper fix!
+    IL_EACH(g_pathlib_nodes, it.is_path_node && vdist(it.origin - where, <, pathlib_gridsize * 0.5),
+    {
+       found = it;
+        break;
+    });
+
+    return found;
 }
 
-float location_isok(vector point, float water_isok, float air_isok)
+bool tile_check_cross(entity this, vector where)
 {
-    float pc,pc2;
+       vector p;
+    vector f = PLIB_FORWARD * tile_check_size;
+    vector r = PLIB_RIGHT   * tile_check_size;
 
-    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-        return 0;
 
-    pc  = pointcontents(point);
-    pc2 = pointcontents(point - '0 0 1');
+    // forward-right
+    p = where + f + r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (!location_isok(trace_endpos, 1, 0))
+        return false;
+
+    // Forward-left
+    p = where + f - r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (!location_isok(trace_endpos, 1, 0))
+        return false;
 
-    switch(pc)
-    {
-        case CONTENT_SOLID:
-            break;
+    // Back-right
+    p = where - f + r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (!location_isok(trace_endpos, 1 ,0))
+        return false;
 
-        case CONTENT_SLIME:
-            break;
+    //Back-left
+    p = where - f - r;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (!location_isok(trace_endpos, 1, 0))
+        return false;
 
-        case CONTENT_LAVA:
-            break;
+    return true;
+}
 
-        case CONTENT_SKY:
-            break;
+bool tile_check_plus(entity this, vector where)
+{
+    vector p;
 
-        case CONTENT_EMPTY:
-            if (pc2 == CONTENT_SOLID)
-                return 1;
+    vector f = PLIB_FORWARD * tile_check_size;
+    vector r = PLIB_RIGHT   * tile_check_size;
 
-            if (pc2 == CONTENT_EMPTY)
-                if(air_isok)
-                    return 1;
+    // forward
+    p = where + f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (!location_isok(trace_endpos,1,0))
+        return false;
 
-            if (pc2 == CONTENT_WATER)
-                if(water_isok)
-                    return 1;
 
-            break;
+    //left
+    p = where - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (!location_isok(trace_endpos,1,0))
+        return false;
 
-        case CONTENT_WATER:
-            if (water_isok)
-                return 1;
+    // Right
+    p = where + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (!location_isok(trace_endpos,1,0))
+        return false;
 
-            break;
-    }
+    //Back
+    p = where - f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (!location_isok(trace_endpos,1,0))
+        return false;
 
-    return 0;
+    return true;
 }
 
-entity pathlib_nodeatpoint(vector where)
+float tile_check_plus2(entity this, vector where)
 {
-    entity node;
+    vector p;
+    int j = 0, e = 0;
 
-    ++pathlib_searched_cnt;
+    vector f = PLIB_FORWARD * pathlib_gridsize;
+    vector r = PLIB_RIGHT   * pathlib_gridsize;
 
-    where_x = fsnap(where_x,pathlib_gridsize);
-    where_y = fsnap(where_y,pathlib_gridsize);
+//#define pathlib_node_edgeflag_left    2
+//#define pathlib_node_edgeflag_right   4
+//#define pathlib_node_edgeflag_forward 8
+//#define pathlib_node_edgeflag_back    16
 
-    node = findradius(where,pathlib_gridsize * 0.5);
-    while(node)
+    // forward
+    p = where + f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (location_isok(trace_endpos,1,0))
     {
-        if(node.is_path_node == TRUE)
-            return node;
+       ++j;
+       e |= pathlib_node_edgeflag_forward;
+    }
 
-        node = node.chain;
+
+    //left
+    p = where - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_left;
     }
 
-    return world;
-}
 
-float tile_check_cross(vector where)
-{
-    vector p,f,r;
+    // Right
+    p = where + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_right;
+    }
 
-    f = PLIB_FORWARD * tile_check_size;
-    r = PLIB_RIGHT   * tile_check_size;
+    //Back
+    p = where - f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
+    if (location_isok(trace_endpos,1,0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_back;
+    }
 
     // forward-right
     p = where + f + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (location_isok(trace_endpos, 1, 0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_forwardright;
+    }
 
     // Forward-left
     p = where + f - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (location_isok(trace_endpos, 1, 0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_forwardleft;
+    }
 
     // Back-right
     p = where - f + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (location_isok(trace_endpos, 1 ,0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_backright;
+    }
 
     //Back-left
     p = where - f - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    return 1;
-}
-
-float tile_check_plus(vector where)
-{
-    vector p,f,r;
-
-    f = PLIB_FORWARD * tile_check_size;
-    r = PLIB_RIGHT   * tile_check_size;
-
-    // forward
-    p = where + f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    //left
-    p = where - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
+    traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
+    if (location_isok(trace_endpos, 1, 0))
+    {
+       ++j;
+       e |= pathlib_node_edgeflag_backleft;
+    }
 
 
-    // Right
-    p = where + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    //Back
-    p = where - f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
+    if(j == 0)
+        e = pathlib_node_edgeflag_none;
 
-    return 1;
+    return e;
 }
 
-float tile_check_star(vector where)
+bool tile_check_star(entity this, vector where)
 {
-    if(tile_check_plus(where))
-        return tile_check_cross(where);
+    if(tile_check_plus(this, where))
+        return tile_check_cross(this, where);
 
-    return 0;
+    return false;
 }