]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/pathlib/utility.qc
Merge branch 'master' into Mario/killsound
[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     entity node;
27
28     ++pathlib_searched_cnt;
29
30     where.x = fsnap(where.x,pathlib_gridsize);
31     where.y = fsnap(where.y,pathlib_gridsize);
32
33     node = findradius(where,pathlib_gridsize * 0.5);
34     while(node)
35     {
36         if(node.is_path_node == true)
37             return node;
38
39         node = node.chain;
40     }
41
42     return NULL;
43 }
44
45 float tile_check_cross(entity this, vector where)
46 {
47     vector p,f,r;
48
49     f = PLIB_FORWARD * tile_check_size;
50     r = PLIB_RIGHT   * tile_check_size;
51
52
53     // forward-right
54     p = where + f + r;
55     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
56     if (!location_isok(trace_endpos, 1, 0))
57         return 0;
58
59     // Forward-left
60     p = where + f - r;
61     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
62     if (!location_isok(trace_endpos, 1, 0))
63         return 0;
64
65     // Back-right
66     p = where - f + r;
67     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
68     if (!location_isok(trace_endpos, 1 ,0))
69         return 0;
70
71     //Back-left
72     p = where - f - r;
73     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
74     if (!location_isok(trace_endpos, 1, 0))
75         return 0;
76
77     return 1;
78 }
79
80 float tile_check_plus(entity this, vector where)
81 {
82     vector p,f,r;
83
84     f = PLIB_FORWARD * tile_check_size;
85     r = PLIB_RIGHT   * tile_check_size;
86
87     // forward
88     p = where + f;
89     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
90     if (!location_isok(trace_endpos,1,0))
91         return 0;
92
93
94     //left
95     p = where - r;
96     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
97     if (!location_isok(trace_endpos,1,0))
98         return 0;
99
100     // Right
101     p = where + r;
102     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
103     if (!location_isok(trace_endpos,1,0))
104         return 0;
105
106     //Back
107     p = where - f;
108     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
109     if (!location_isok(trace_endpos,1,0))
110         return 0;
111
112     return 1;
113 }
114
115 float tile_check_plus2(entity this, vector where)
116 {
117     vector p,f,r;
118     float i = 0, e = 0;
119
120     f = PLIB_FORWARD * pathlib_gridsize;
121     r = PLIB_RIGHT   * pathlib_gridsize;
122
123 //#define pathlib_node_edgeflag_left    2
124 //#define pathlib_node_edgeflag_right   4
125 //#define pathlib_node_edgeflag_forward 8
126 //#define pathlib_node_edgeflag_back    16
127
128     // forward
129     p = where + f;
130     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
131     if (location_isok(trace_endpos,1,0))
132     {
133        ++i;
134        e |= pathlib_node_edgeflag_forward;
135     }
136
137
138     //left
139     p = where - r;
140     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
141     if (location_isok(trace_endpos,1,0))
142     {
143        ++i;
144        e |= pathlib_node_edgeflag_left;
145     }
146
147
148     // Right
149     p = where + r;
150     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
151     if (location_isok(trace_endpos,1,0))
152     {
153        ++i;
154        e |= pathlib_node_edgeflag_right;
155     }
156
157     //Back
158     p = where - f;
159     traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,this);
160     if (location_isok(trace_endpos,1,0))
161     {
162        ++i;
163        e |= pathlib_node_edgeflag_back;
164     }
165
166     // forward-right
167     p = where + f + r;
168     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
169     if (location_isok(trace_endpos, 1, 0))
170     {
171        ++i;
172        e |= pathlib_node_edgeflag_forwardright;
173     }
174
175     // Forward-left
176     p = where + f - r;
177     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
178     if (location_isok(trace_endpos, 1, 0))
179     {
180        ++i;
181        e |= pathlib_node_edgeflag_forwardleft;
182     }
183
184     // Back-right
185     p = where - f + r;
186     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
187     if (location_isok(trace_endpos, 1 ,0))
188     {
189        ++i;
190        e |= pathlib_node_edgeflag_backright;
191     }
192
193     //Back-left
194     p = where - f - r;
195     traceline(p + tile_check_up, p - tile_check_down, MOVE_WORLDONLY, this);
196     if (location_isok(trace_endpos, 1, 0))
197     {
198        ++i;
199        e |= pathlib_node_edgeflag_backleft;
200     }
201
202
203     if(i == 0)
204         e = pathlib_node_edgeflag_none;
205
206     return e;
207 }
208
209 float tile_check_star(entity this, vector where)
210 {
211     if(tile_check_plus(this, where))
212         return tile_check_cross(this, where);
213
214     return 0;
215 }
216