3 #include <server/defs.qh>
4 #include <server/miscfunctions.qh>
7 bool location_isok(vector point, bool waterok, bool air_isok)
9 if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) {
13 int pc = pointcontents(point);
14 int pc2 = pointcontents(point - '0 0 1');
16 if (pc == CONTENT_EMPTY && pc2 == CONTENT_SOLID) {
19 if (pc == CONTENT_EMPTY && pc2 == CONTENT_WATER && waterok) {
22 if (pc == CONTENT_EMPTY && pc2 == CONTENT_EMPTY && air_isok) {
25 if (pc == CONTENT_WATER && waterok) {
31 entity pathlib_nodeatpoint(vector where)
33 ++pathlib_searched_cnt;
35 where.x = fsnap(where.x, pathlib_gridsize);
36 where.y = fsnap(where.y, pathlib_gridsize);
38 entity found = NULL; // TODO: using FOREACH_ENTITY_RADIUS here causes mutex loop warnings, this may need a proper fix!
39 IL_EACH(g_pathlib_nodes, it.is_path_node && vdist(it.origin - where, <, pathlib_gridsize * 0.5),
48 bool tile_check_cross(entity this, vector where)
51 vector f = PLIB_FORWARD * tile_check_size;
52 vector r = PLIB_RIGHT * tile_check_size;
57 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
58 if (!location_isok(trace_endpos, 1, 0)) {
64 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
65 if (!location_isok(trace_endpos, 1, 0)) {
71 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
72 if (!location_isok(trace_endpos, 1, 0)) {
78 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
79 if (!location_isok(trace_endpos, 1, 0)) {
86 bool tile_check_plus(entity this, vector where)
90 vector f = PLIB_FORWARD * tile_check_size;
91 vector r = PLIB_RIGHT * tile_check_size;
95 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
96 if (!location_isok(trace_endpos, 1, 0)) {
103 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
104 if (!location_isok(trace_endpos, 1, 0)) {
110 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
111 if (!location_isok(trace_endpos, 1, 0)) {
117 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
118 if (!location_isok(trace_endpos, 1, 0)) {
125 float tile_check_plus2(entity this, vector where)
130 vector f = PLIB_FORWARD * pathlib_gridsize;
131 vector r = PLIB_RIGHT * pathlib_gridsize;
133 // #define pathlib_node_edgeflag_left 2
134 // #define pathlib_node_edgeflag_right 4
135 // #define pathlib_node_edgeflag_forward 8
136 // #define pathlib_node_edgeflag_back 16
140 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
141 if (location_isok(trace_endpos, 1, 0)) {
143 e |= pathlib_node_edgeflag_forward;
149 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
150 if (location_isok(trace_endpos, 1, 0)) {
152 e |= pathlib_node_edgeflag_left;
158 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
159 if (location_isok(trace_endpos, 1, 0)) {
161 e |= pathlib_node_edgeflag_right;
166 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
167 if (location_isok(trace_endpos, 1, 0)) {
169 e |= pathlib_node_edgeflag_back;
174 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
175 if (location_isok(trace_endpos, 1, 0)) {
177 e |= pathlib_node_edgeflag_forwardright;
182 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
183 if (location_isok(trace_endpos, 1, 0)) {
185 e |= pathlib_node_edgeflag_forwardleft;
190 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
191 if (location_isok(trace_endpos, 1, 0)) {
193 e |= pathlib_node_edgeflag_backright;
198 traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
199 if (location_isok(trace_endpos, 1, 0)) {
201 e |= pathlib_node_edgeflag_backleft;
206 e = pathlib_node_edgeflag_none;
212 bool tile_check_star(entity this, vector where)
214 if (tile_check_plus(this, where)) {
215 return tile_check_cross(this, where);