map_collision.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. #include "map.hh"
  9. #include "g1_object.hh"
  10. #include "height_info.hh"
  11. #include "map_cell.hh"
  12. // int g1_map_class::check_collision(i4_float x, i4_float y,
  13. // i4_float occupancy_radius,
  14. // i4_float &dx, i4_float &dy,
  15. // sw32 _ix, sw32 _iy,
  16. // g1_object_class*& hit) const
  17. // {
  18. // i4_float gx,gy,r;
  19. // i4_float a,b,c,d,e;
  20. // hit = 0;
  21. // i4_float min_dist=0;
  22. // sw32 x_left,x_right,y_top,y_bottom,ix,iy;
  23. // if (
  24. // (cell(_ix,_iy)->is_blocking()) ||
  25. // (x<0) || (y<0) || (x>=w) || (y>=h) ||
  26. // (x+dx<0) || (y+dy<0) || (x+dx>=w) || (y+dy>=h)
  27. // )
  28. // {
  29. // //dx = 0;
  30. // //dy = 0;
  31. // return -1;
  32. // }
  33. // x_left = i4_f_to_i(x - fabs(dx)); if (x_left<0) x_left=0;
  34. // x_right = i4_f_to_i(x + fabs(dx)); if (x_right>w-1) x_right=w-1;
  35. // y_top = i4_f_to_i(y - fabs(dy)); if (y_top<0) y_top=0;
  36. // y_bottom = i4_f_to_i(y + fabs(dy)); if (y_bottom>h-1) y_bottom=h-1;
  37. // for (ix=x_left; ix<=x_right; ix++)
  38. // for (iy=y_top; iy<=y_bottom; iy++)
  39. // {
  40. // if (ix>=0 && iy>=0 && ix<w && iy<h)
  41. // {
  42. // g1_object_chain_class *p = cell(ix,iy)->get_solid_list();
  43. // while (p)
  44. // {
  45. // //if its an exact collision (exactly same x's and y's) its probably the same object,
  46. // //so ignore it
  47. // if (p->object->x!=x || p->object->y!=y)
  48. // {
  49. // gx = p->object->x - x;
  50. // gy = p->object->y - y;
  51. // a = dx*gx + dy*gy;
  52. // b = dx*dx + dy*dy;
  53. // c = (a*a)/b;
  54. // d = gx*gx + gy*gy;
  55. // r = p->object->occupancy_radius();
  56. // if ((r*r)>d-c)
  57. // {
  58. // i4_bool x_check=i4_F,y_check=i4_F;
  59. // //min_dist=d;
  60. // if (dx>0)
  61. // {
  62. // if ((p->object->x+r > x) && (p->object->x-r < (x+dx))) x_check = i4_T;
  63. // }
  64. // else
  65. // {
  66. // if ((p->object->x-r < x) && (p->object->x+r > (x+dx))) x_check = i4_T;
  67. // }
  68. // if (dy>0)
  69. // {
  70. // if ((p->object->y+r > y) && (p->object->y-r < (y+dy))) y_check = i4_T;
  71. // }
  72. // else
  73. // {
  74. // if ((p->object->y-r < y) && (p->object->y+r > (y+dy))) y_check = i4_T;
  75. // }
  76. // if (x_check && y_check)
  77. // hit =p->object;
  78. // }
  79. // }
  80. // p = p->next_solid();
  81. // }
  82. // }
  83. // }
  84. // if (hit)
  85. // return 1;
  86. // return 0;
  87. // }
  88. int g1_map_class::check_non_player_collision(g1_player_type player_num,
  89. const i4_3d_vector &point,
  90. i4_3d_vector &ray,
  91. g1_object_class*& hit) const
  92. {
  93. hit = 0;
  94. sw32 x_left,x_right,y_top,y_bottom, ix,iy;
  95. if ((point.x<0) || (point.y<0) || (point.x>=w) || (point.y>=h) ||
  96. (point.x+ray.x<0) || (point.y+ray.y<0) || (point.x+ray.x>=w) || (point.y+ray.y>=h))
  97. {
  98. ray.x=0;
  99. ray.y=0;
  100. ray.z=0;
  101. return -1;
  102. }
  103. i4_3d_vector final(point);
  104. final += ray;
  105. i4_float height = terrain_height(final.x,final.y);
  106. if (final.z<height)
  107. {
  108. // hit the ground
  109. ray.z = height - point.z;
  110. return 1;
  111. }
  112. if (ray.x<0)
  113. {
  114. x_left = i4_f_to_i(point.x + ray.x);
  115. x_right = i4_f_to_i(point.x);
  116. }
  117. else
  118. {
  119. x_left = i4_f_to_i(point.x);
  120. x_right = i4_f_to_i(point.x + ray.x);
  121. }
  122. if (ray.y<0)
  123. {
  124. y_top = i4_f_to_i(point.y + ray.y);
  125. y_bottom = i4_f_to_i(point.y);
  126. }
  127. else
  128. {
  129. y_top = i4_f_to_i(point.y);
  130. y_bottom = i4_f_to_i(point.y + ray.y);
  131. }
  132. if (x_left<0) x_left=0;
  133. if (x_right>w-1) x_right=w-1;
  134. if (y_top<0) y_top=0;
  135. if (y_bottom>h-1) y_bottom=h-1;
  136. for (ix=x_left; ix<=x_right; ix++)
  137. for (iy=y_top; iy<=y_bottom; iy++)
  138. {
  139. g1_object_chain_class *p = cell(ix,iy)->get_solid_list();
  140. while (p)
  141. {
  142. // if the object is not on our team or so not dangerous (probably a building)
  143. if ((p->object->player_num!=player_num ||
  144. !p->object->get_flag(g1_object_class::DANGEROUS)) &&
  145. p->object->check_collision(point, ray))
  146. hit = p->object;
  147. p = p->next_solid();
  148. }
  149. }
  150. if (hit)
  151. return 1;
  152. return 0;
  153. }
  154. // int g1_map_class::check_cell(i4_float x, i4_float y,
  155. // i4_float occupancy_radius,
  156. // sw32 ix, sw32 iy) const
  157. // {
  158. // i4_float dx, dy, r;
  159. // if (!cell(ix,iy).get_solid_list())
  160. // return 1;
  161. // return 0;
  162. // }
  163. int g1_map_class::check_terrain_location(i4_float x, i4_float y, i4_float z,
  164. i4_float rad, w8 grade, w8 dir) const
  165. {
  166. i4_float x_left,x_right,y_top,y_bottom;
  167. x_left = x - rad; if (x_left<0) return 0;
  168. x_right = x + rad; if (x_right>=w) return 0;
  169. y_top = y - rad; if (y_top<0) return 0;
  170. y_bottom = y + rad; if (y_bottom>=h) return 0;
  171. sw32 xl = i4_f_to_i(x_left);
  172. sw32 xr = i4_f_to_i(x_right);
  173. sw32 yt = i4_f_to_i(y_top);
  174. sw32 yb = i4_f_to_i(y_bottom);
  175. g1_map_cell_class *c;
  176. // const g1_block_map_class *block = get_block_map(grade);
  177. // c = &cell(xl,yt);
  178. // if (c->is_blocking() || block->is_blocked(xl,yt,dir)) return 0;
  179. // c = &cell(xr,yt);
  180. // if (c->is_blocking() || block->is_blocked(xr,yt,dir)) return 0;
  181. // c = &cell(xl,yb);
  182. // if (c->is_blocking() || block->is_blocked(xl,yb,dir)) return 0;
  183. // c = &cell(xr,yb);
  184. // if (c->is_blocking() || block->is_blocked(xr,yb,dir)) return 0;
  185. return 1;
  186. }