[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 


 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_CELL1]!=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_LEVELS1; 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,y1,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(x1,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<wy1 && !map>block[grade].is_blocked(x,y1,G1_NORTH))


 246  add_critical(x,y1,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<wx1 && !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(x1,y,G1_EAST))


 252  add_critical(x1,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  // foldedfile: t


 282  // End:


 283  //}}}

