-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;
}