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