]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/pathlib/utility.qc
take3: format 903 files
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / pathlib / utility.qc
1 #include "utility.qh"
2
3 #include <server/defs.qh>
4 #include <server/miscfunctions.qh>
5 #include "pathlib.qh"
6
7 bool location_isok(vector point, bool waterok, bool air_isok)
8 {
9         if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) {
10                 return false;
11         }
12
13         int pc = pointcontents(point);
14         int pc2 = pointcontents(point - '0 0 1');
15
16         if (pc == CONTENT_EMPTY && pc2 == CONTENT_SOLID) {
17                 return true;
18         }
19         if (pc == CONTENT_EMPTY && pc2 == CONTENT_WATER && waterok) {
20                 return true;
21         }
22         if (pc == CONTENT_EMPTY && pc2 == CONTENT_EMPTY && air_isok) {
23                 return true;
24         }
25         if (pc == CONTENT_WATER && waterok) {
26                 return true;
27         }
28         return false;
29 }
30
31 entity pathlib_nodeatpoint(vector where)
32 {
33         ++pathlib_searched_cnt;
34
35         where.x = fsnap(where.x, pathlib_gridsize);
36         where.y = fsnap(where.y, pathlib_gridsize);
37
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),
40         {
41                 found = it;
42                 break;
43         });
44
45         return found;
46 }
47
48 bool tile_check_cross(entity this, vector where)
49 {
50         vector p;
51         vector f = PLIB_FORWARD * tile_check_size;
52         vector r = PLIB_RIGHT   * tile_check_size;
53
54
55         // forward-right
56         p = where + f + r;
57         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
58         if (!location_isok(trace_endpos, 1, 0)) {
59                 return false;
60         }
61
62         // Forward-left
63         p = where + f - r;
64         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
65         if (!location_isok(trace_endpos, 1, 0)) {
66                 return false;
67         }
68
69         // Back-right
70         p = where - f + r;
71         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
72         if (!location_isok(trace_endpos, 1, 0)) {
73                 return false;
74         }
75
76         // Back-left
77         p = where - f - r;
78         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
79         if (!location_isok(trace_endpos, 1, 0)) {
80                 return false;
81         }
82
83         return true;
84 }
85
86 bool tile_check_plus(entity this, vector where)
87 {
88         vector p;
89
90         vector f = PLIB_FORWARD * tile_check_size;
91         vector r = PLIB_RIGHT   * tile_check_size;
92
93         // forward
94         p = where + f;
95         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
96         if (!location_isok(trace_endpos, 1, 0)) {
97                 return false;
98         }
99
100
101         // left
102         p = where - r;
103         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
104         if (!location_isok(trace_endpos, 1, 0)) {
105                 return false;
106         }
107
108         // Right
109         p = where + r;
110         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
111         if (!location_isok(trace_endpos, 1, 0)) {
112                 return false;
113         }
114
115         // Back
116         p = where - f;
117         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
118         if (!location_isok(trace_endpos, 1, 0)) {
119                 return false;
120         }
121
122         return true;
123 }
124
125 float tile_check_plus2(entity this, vector where)
126 {
127         vector p;
128         int j = 0, e = 0;
129
130         vector f = PLIB_FORWARD * pathlib_gridsize;
131         vector r = PLIB_RIGHT   * pathlib_gridsize;
132
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
137
138         // forward
139         p = where + f;
140         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
141         if (location_isok(trace_endpos, 1, 0)) {
142                 ++j;
143                 e |= pathlib_node_edgeflag_forward;
144         }
145
146
147         // left
148         p = where - r;
149         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
150         if (location_isok(trace_endpos, 1, 0)) {
151                 ++j;
152                 e |= pathlib_node_edgeflag_left;
153         }
154
155
156         // Right
157         p = where + r;
158         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
159         if (location_isok(trace_endpos, 1, 0)) {
160                 ++j;
161                 e |= pathlib_node_edgeflag_right;
162         }
163
164         // Back
165         p = where - f;
166         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
167         if (location_isok(trace_endpos, 1, 0)) {
168                 ++j;
169                 e |= pathlib_node_edgeflag_back;
170         }
171
172         // forward-right
173         p = where + f + r;
174         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
175         if (location_isok(trace_endpos, 1, 0)) {
176                 ++j;
177                 e |= pathlib_node_edgeflag_forwardright;
178         }
179
180         // Forward-left
181         p = where + f - r;
182         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
183         if (location_isok(trace_endpos, 1, 0)) {
184                 ++j;
185                 e |= pathlib_node_edgeflag_forwardleft;
186         }
187
188         // Back-right
189         p = where - f + r;
190         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
191         if (location_isok(trace_endpos, 1, 0)) {
192                 ++j;
193                 e |= pathlib_node_edgeflag_backright;
194         }
195
196         // Back-left
197         p = where - f - r;
198         traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
199         if (location_isok(trace_endpos, 1, 0)) {
200                 ++j;
201                 e |= pathlib_node_edgeflag_backleft;
202         }
203
204
205         if (j == 0) {
206                 e = pathlib_node_edgeflag_none;
207         }
208
209         return e;
210 }
211
212 bool tile_check_star(entity this, vector where)
213 {
214         if (tile_check_plus(this, where)) {
215                 return tile_check_cross(this, where);
216         }
217
218         return false;
219 }