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