1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "critical_map.hh"
|
---|
10 | #include "path_api.hh"
|
---|
11 | #include "map.hh"
|
---|
12 | #include "map_cell.hh"
|
---|
13 | #include "status/status.hh"
|
---|
14 | #include <math.h>
|
---|
15 |
|
---|
16 |
|
---|
17 | void g1_critical_map_maker_class::clear_critical_map()
|
---|
18 | //{{{
|
---|
19 | {
|
---|
20 | int i,j,k;
|
---|
21 | g1_map_cell_class *c=map->cell(0,0);
|
---|
22 |
|
---|
23 | for (j=0; j<map->height(); j++)
|
---|
24 | for (i=0; i<map->width(); i++, c++)
|
---|
25 | memset(c->nearest_critical, 0, sizeof(c->nearest_critical));
|
---|
26 | }
|
---|
27 | //}}}
|
---|
28 |
|
---|
29 |
|
---|
30 | g1_graph_node g1_critical_map_maker_class::get_critical(w16 x, w16 y, int n)
|
---|
31 | //{{{
|
---|
32 | {
|
---|
33 | return map->cell(x,y)->nearest_critical[grade][tofrom][n];
|
---|
34 | }
|
---|
35 | //}}}
|
---|
36 |
|
---|
37 |
|
---|
38 | i4_bool g1_critical_map_maker_class::critical_full(w16 x, w16 y, g1_graph_node crit)
|
---|
39 | //{{{
|
---|
40 | {
|
---|
41 | w8 *p = map->cell(x,y)->nearest_critical[grade][tofrom];
|
---|
42 | if (p[G1_CRITICALS_PER_CELL-1]!=g1_map_cell_class::NO_CRITICAL)
|
---|
43 | return i4_T;
|
---|
44 | for (int i=0; i<G1_CRITICALS_PER_CELL; i++)
|
---|
45 | if (p[i]==crit)
|
---|
46 | return i4_T;
|
---|
47 | return i4_F;
|
---|
48 | }
|
---|
49 | //}}}
|
---|
50 |
|
---|
51 |
|
---|
52 | void g1_critical_map_maker_class::set_critical(w16 x, w16 y, g1_graph_node critical)
|
---|
53 | //{{{
|
---|
54 | {
|
---|
55 | I4_ASSERT(critical!=g1_map_cell_class::NO_CRITICAL, "can't set critical point to blank");
|
---|
56 | I4_ASSERT(!critical_full(x,y,critical), "Adding too many critical points to one spot");
|
---|
57 |
|
---|
58 | w8 *p = map->cell(x,y)->nearest_critical[grade][tofrom];
|
---|
59 | while (*p!=g1_map_cell_class::NO_CRITICAL)
|
---|
60 | p++;
|
---|
61 | *p = critical;
|
---|
62 | }
|
---|
63 | //}}}
|
---|
64 |
|
---|
65 |
|
---|
66 | i4_bool g1_critical_map_maker_class::add_critical(w32 x,w32 y,w8 d, g1_graph_node critical)
|
---|
67 | //{{{
|
---|
68 | {
|
---|
69 | if (d>0 &&
|
---|
70 | (x<0 || x>=map->width() || y<0 || y>=map->height() || critical_full(x,y,critical)))
|
---|
71 | return i4_F;
|
---|
72 |
|
---|
73 | set_critical(x,y,critical);
|
---|
74 |
|
---|
75 | cnx[head] = x;
|
---|
76 | cny[head] = y;
|
---|
77 | crit[head] = critical;
|
---|
78 | if (++head>=queue_length) head=0;
|
---|
79 |
|
---|
80 | if (head==tail)
|
---|
81 | i4_warning("queue overrun.");
|
---|
82 |
|
---|
83 | return i4_T;
|
---|
84 | }
|
---|
85 | //}}}
|
---|
86 |
|
---|
87 |
|
---|
88 | i4_bool g1_critical_map_maker_class::get_next_critical(w32 &x,w32 &y, g1_graph_node &critical)
|
---|
89 | //{{{
|
---|
90 | {
|
---|
91 | if (tail==head)
|
---|
92 | return i4_F;
|
---|
93 |
|
---|
94 | x = cnx[tail];
|
---|
95 | y = cny[tail];
|
---|
96 | critical = crit[tail];
|
---|
97 | if (++tail>=queue_length) tail=0;
|
---|
98 |
|
---|
99 | return i4_T;
|
---|
100 | }
|
---|
101 | //}}}
|
---|
102 |
|
---|
103 |
|
---|
104 | i4_bool g1_critical_map_maker_class::make_critical_graph()
|
---|
105 | //{{{
|
---|
106 | {
|
---|
107 | w32 i,j,g;
|
---|
108 | g1_critical_graph_class::connection_class *c;
|
---|
109 | int add;
|
---|
110 |
|
---|
111 | i4_status_class *status=i4_create_status(i4gets("make_crit_graph"),1);
|
---|
112 |
|
---|
113 | critical->clear_critical_graph();
|
---|
114 |
|
---|
115 | int canceled=0;
|
---|
116 | float update_time=0;
|
---|
117 |
|
---|
118 | for (j=1; j<critical->criticals && !canceled; j++)
|
---|
119 | {
|
---|
120 | if (status)
|
---|
121 | {
|
---|
122 | update_time=(j+1)/(float)critical->criticals;
|
---|
123 | if (!status->update(update_time))
|
---|
124 | canceled=1;
|
---|
125 | }
|
---|
126 |
|
---|
127 |
|
---|
128 | g1_critical_graph_class::critical_point_class *crit = &critical->critical[j];
|
---|
129 | for (i=1; i<critical->criticals && !canceled; i++)
|
---|
130 | {
|
---|
131 | if (i==j)
|
---|
132 | continue;
|
---|
133 |
|
---|
134 | w8 size[G1_GRADE_LEVELS];
|
---|
135 |
|
---|
136 | if (!status->update(update_time))
|
---|
137 | canceled=1;
|
---|
138 |
|
---|
139 | g1_critical_graph_class::critical_point_class *crit2 = &critical->critical[i];
|
---|
140 | for (g=0; g<G1_GRADE_LEVELS; g++)
|
---|
141 | size[g] = (w8)(64.0*map->block[g].line_of_sight(crit->x, crit->y, crit2->x, crit2->y));
|
---|
142 |
|
---|
143 | add = 0;
|
---|
144 | for (g=0; g<G1_GRADE_LEVELS-1; g++)
|
---|
145 | if (size[g])
|
---|
146 | add=1;
|
---|
147 |
|
---|
148 | if (add)
|
---|
149 | {
|
---|
150 | I4_ASSERT(crit->connections<g1_critical_graph_class::MAX_CONNECTIONS,
|
---|
151 | "Adding too many connections");
|
---|
152 |
|
---|
153 | // goto next available connection entry
|
---|
154 | c = &crit->connection[crit->connections];
|
---|
155 | crit->connections++;
|
---|
156 |
|
---|
157 | // calculate info
|
---|
158 | i4_float
|
---|
159 | dx = crit2->x - crit->x,
|
---|
160 | dy = crit2->y - crit->y;
|
---|
161 |
|
---|
162 | c->ref = i;
|
---|
163 | c->dist = sqrt(dx*dx+dy*dy);
|
---|
164 |
|
---|
165 | for (g=0; g<G1_GRADE_LEVELS; g++)
|
---|
166 | c->size[g] = size[g];
|
---|
167 | }
|
---|
168 | }
|
---|
169 | }
|
---|
170 |
|
---|
171 | if (status)
|
---|
172 | delete status;
|
---|
173 |
|
---|
174 | return !canceled;
|
---|
175 | }
|
---|
176 | //}}}
|
---|
177 |
|
---|
178 |
|
---|
179 | i4_bool g1_critical_map_maker_class::make_critical_map()
|
---|
180 | //{{{
|
---|
181 | {
|
---|
182 | w32 x,y;
|
---|
183 | g1_graph_node c;
|
---|
184 |
|
---|
185 | i4_status_class *stat = i4_create_status(i4gets("make_critical_map"), 1);
|
---|
186 | int canceled=0;
|
---|
187 |
|
---|
188 | clear_critical_map();
|
---|
189 | tofrom=0;
|
---|
190 | float stime=0;
|
---|
191 |
|
---|
192 | for (grade=0; grade<G1_GRADE_LEVELS && !canceled; grade++)
|
---|
193 | {
|
---|
194 | stime=(float)grade/(G1_GRADE_LEVELS*2);
|
---|
195 |
|
---|
196 | clear_queue();
|
---|
197 |
|
---|
198 | for (c=1; c<critical->criticals; c++)
|
---|
199 | {
|
---|
200 | if (stat)
|
---|
201 | if (!stat->update(stime))
|
---|
202 | canceled=1;
|
---|
203 |
|
---|
204 | add_critical((w32)critical->critical[c].x,
|
---|
205 | (w32)critical->critical[c].y,
|
---|
206 | 0,c);
|
---|
207 | }
|
---|
208 |
|
---|
209 | while (get_next_critical(x,y,c))
|
---|
210 | {
|
---|
211 | if (!map->block[grade].is_blocked(x,y,G1_SOUTH))
|
---|
212 | add_critical(x,y-1,G1_NORTH,c);
|
---|
213 | if (!map->block[grade].is_blocked(x,y,G1_NORTH))
|
---|
214 | add_critical(x,y+1,G1_SOUTH,c);
|
---|
215 | if (!map->block[grade].is_blocked(x,y,G1_EAST))
|
---|
216 | add_critical(x+1,y,G1_WEST,c);
|
---|
217 | if (!map->block[grade].is_blocked(x,y,G1_WEST))
|
---|
218 | add_critical(x-1,y,G1_EAST,c);
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | w32 wx = map->width(), wy=map->height();
|
---|
223 | tofrom=1;
|
---|
224 | for (grade=0; grade<G1_GRADE_LEVELS && !canceled; grade++)
|
---|
225 | {
|
---|
226 | stime=(float)(grade+G1_GRADE_LEVELS)/(G1_GRADE_LEVELS*2);
|
---|
227 |
|
---|
228 | clear_queue();
|
---|
229 |
|
---|
230 | for (c=1; c<critical->criticals; c++)
|
---|
231 | {
|
---|
232 | if (stat && !stat->update(stime))
|
---|
233 | canceled=1;
|
---|
234 |
|
---|
235 | add_critical((w32)critical->critical[c].x,
|
---|
236 | (w32)critical->critical[c].y,
|
---|
237 | 0,c);
|
---|
238 | }
|
---|
239 |
|
---|
240 | while (get_next_critical(x,y,c))
|
---|
241 | {
|
---|
242 | if (stat && !stat->update(stime))
|
---|
243 | canceled=1;
|
---|
244 |
|
---|
245 | if (y<wy-1 && !map->block[grade].is_blocked(x,y-1,G1_NORTH))
|
---|
246 | add_critical(x,y-1,G1_NORTH,c);
|
---|
247 | if (y>0 && !map->block[grade].is_blocked(x,y+1,G1_SOUTH))
|
---|
248 | add_critical(x,y+1,G1_SOUTH,c);
|
---|
249 | if (x<wx-1 && !map->block[grade].is_blocked(x+1,y,G1_WEST))
|
---|
250 | add_critical(x+1,y,G1_WEST,c);
|
---|
251 | if (x>0 && !map->block[grade].is_blocked(x-1,y,G1_EAST))
|
---|
252 | add_critical(x-1,y,G1_EAST,c);
|
---|
253 | }
|
---|
254 | }
|
---|
255 |
|
---|
256 | if (stat)
|
---|
257 | delete stat;
|
---|
258 |
|
---|
259 | return !canceled;
|
---|
260 | }
|
---|
261 | //}}}
|
---|
262 |
|
---|
263 |
|
---|
264 | i4_bool g1_critical_map_maker_class::make_criticals(g1_map_class *_map,
|
---|
265 | g1_critical_graph_class *graph)
|
---|
266 | //{{{
|
---|
267 | {
|
---|
268 | map = _map;
|
---|
269 | critical = graph;
|
---|
270 |
|
---|
271 | if (make_critical_map() && make_critical_graph())
|
---|
272 | return i4_T;
|
---|
273 | else return i4_F;
|
---|
274 |
|
---|
275 | }
|
---|
276 | //}}}
|
---|
277 |
|
---|
278 |
|
---|
279 | //{{{ Emacs Locals
|
---|
280 | // Local Variables:
|
---|
281 | // folded-file: t
|
---|
282 | // End:
|
---|
283 | //}}}
|
---|