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  //}}}

