source: golgotha/src/golg/critical_map.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 6.8 KB
RevLine 
[80]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
17void 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
30g1_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
38i4_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
52void 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
66i4_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
88i4_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
104i4_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
179i4_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
264i4_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//}}}
Note: See TracBrowser for help on using the repository browser.