You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

295 lines
8.4 KiB

  1. /*
  2. * ttyvaders Textmode shoot'em up
  3. * Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id: collide.c,v 1.11 2003/01/06 12:22:58 sam Exp $
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #include <stdlib.h>
  23. #include "common.h"
  24. void collide_weapons_tunnel( game *g, weapons *wp, tunnel *t, explosions *ex )
  25. {
  26. int i, j, x, y;
  27. for( i = 0; i < WEAPONS; i++ )
  28. {
  29. x = wp->x[i] >> 4;
  30. y = wp->y[i] >> 4;
  31. switch( wp->type[i] )
  32. {
  33. case WEAPON_LIGHTNING:
  34. case WEAPON_NONE:
  35. break;
  36. case WEAPON_SEEKER:
  37. case WEAPON_BOMB:
  38. case WEAPON_FRAGBOMB:
  39. if( y < 0 || y >= g->h )
  40. {
  41. break;
  42. }
  43. if( x <= t->left[y]
  44. || x >= t->right[y] )
  45. {
  46. int damage = wp->type[i] == WEAPON_SEEKER ? 1 : 2;
  47. add_explosion( g, ex, x, y, 0, 1, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM );
  48. if( x <= t->left[y] )
  49. {
  50. if( y-2 >= 0 ) t->left[y-2] -= damage - 1;
  51. if( y-1 >= 0 ) t->left[y-1] -= damage;
  52. t->left[y] -= damage + 1;
  53. if( y+1 < g->h ) t->left[y+1] -= damage;
  54. if( y+2 < g->h ) t->left[y+2] -= damage - 1;
  55. }
  56. else
  57. {
  58. if( y-2 >= 0 ) t->right[y-2] += damage - 1;
  59. if( y-1 >= 0 ) t->right[y-1] += damage;
  60. t->right[y] += damage + 1;
  61. if( y+1 < g->h ) t->right[y+1] += damage;
  62. if( y+2 < g->h ) t->right[y+2] += damage - 1;
  63. }
  64. if( wp->type[i] == WEAPON_FRAGBOMB )
  65. {
  66. wp->n[i] = -1;
  67. }
  68. else
  69. {
  70. wp->type[i] = WEAPON_NONE;
  71. }
  72. }
  73. break;
  74. case WEAPON_LASER:
  75. for( j = GET_MIN( 0, wp->vy[i] >> 4 ) ;
  76. j < GET_MAX( 0, wp->vy[i] >> 4 ) ;
  77. j++ )
  78. {
  79. if( y+j >= g->h || y+j < 0 )
  80. {
  81. continue;
  82. }
  83. if( x <= t->left[y+j] || x >= t->right[y+j] )
  84. {
  85. add_explosion( g, ex, x, y+j, 0, 1, EXPLOSION_SMALL );
  86. wp->type[i] = WEAPON_NONE;
  87. if( x <= t->left[y+j] )
  88. {
  89. if( y+j-1 >= 0 ) t->left[y+j-1]--;
  90. t->left[y+j] -= 2;
  91. if( y+j+1 < g->h ) t->left[y+j+1]--;
  92. }
  93. else
  94. {
  95. if( y+j-1 >= 0 ) t->right[y+j-1]++;
  96. t->right[y+j] += 2;
  97. if( y+j+1 < g->h ) t->right[y+j+1]++;
  98. }
  99. break;
  100. }
  101. }
  102. break;
  103. case WEAPON_BEAM:
  104. if( wp->n[i] > 19 )
  105. {
  106. break;
  107. }
  108. j = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
  109. j = GET_MIN( y, j );
  110. for( ; j > 0 ; j-- )
  111. {
  112. if( x - 2 <= t->left[y-j] )
  113. {
  114. add_explosion( g, ex, GET_MIN(t->left[y-j], x+3), y-j, 0, 1, EXPLOSION_SMALL );
  115. t->left[y-j] -= GET_RAND(0,3);
  116. }
  117. else if( x + 3 >= t->right[y-j] )
  118. {
  119. add_explosion( g, ex, GET_MAX(t->right[y-j], x-2), y-j, 0, 1, EXPLOSION_SMALL );
  120. t->right[y-j] += GET_RAND(0,3);
  121. }
  122. }
  123. break;
  124. case WEAPON_NUKE:
  125. /* The nuke does not break the tunnel */
  126. break;
  127. }
  128. }
  129. }
  130. void collide_weapons_aliens( game *g, weapons *wp, aliens *al, explosions *ex )
  131. {
  132. int i, j, k, x, y;
  133. for( i = 0; i < WEAPONS; i++ )
  134. {
  135. int ok = 0;
  136. int r;
  137. x = wp->x[i] >> 4;
  138. y = wp->y[i] >> 4;
  139. switch( wp->type[i] )
  140. {
  141. case WEAPON_LIGHTNING:
  142. case WEAPON_NONE:
  143. break;
  144. case WEAPON_NUKE:
  145. /* Big nuke */
  146. r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
  147. for( j = 0; j < ALIENS; j++ )
  148. {
  149. if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
  150. {
  151. continue;
  152. }
  153. if( wp->n[i] == 0 /* Nuke destroys _everything_ */ ||
  154. (al->x[j] - x) * (al->x[j] - x)
  155. + 4 * (al->y[j] - y) * (al->y[j] - y)
  156. <= r * r )
  157. {
  158. /* Kill alien, not nuke */
  159. al->life[j] -= 10;
  160. }
  161. }
  162. break;
  163. case WEAPON_BEAM:
  164. if( wp->n[i] > 19 )
  165. {
  166. break;
  167. }
  168. r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
  169. for( j = 0; j < ALIENS; j++ )
  170. {
  171. if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
  172. {
  173. continue;
  174. }
  175. if( x >= al->x[j] && x <= al->x[j] + 4
  176. && y >= al->y[j] + 2 && y-5-r <= al->y[j] )
  177. {
  178. al->life[j] -= 4;
  179. }
  180. }
  181. break;
  182. case WEAPON_LASER:
  183. for( j = 0; j < ALIENS; j++ )
  184. {
  185. if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
  186. {
  187. continue;
  188. }
  189. for( k = GET_MIN( 0, wp->vy[i] >> 4 ) ;
  190. k < GET_MAX( 0, wp->vy[i] >> 4 ) ;
  191. k++ )
  192. {
  193. if( x >= al->x[j] && x <= al->x[j] + 4
  194. && y+k >= al->y[j] && y+k <= al->y[j] + 2 )
  195. {
  196. al->life[j]--;
  197. ok = 1;
  198. break;
  199. }
  200. }
  201. }
  202. if( ok )
  203. {
  204. add_explosion( g, ex, x, y+1, 0, 0, EXPLOSION_SMALL );
  205. wp->type[i] = WEAPON_NONE;
  206. }
  207. break;
  208. case WEAPON_SEEKER:
  209. case WEAPON_BOMB:
  210. case WEAPON_FRAGBOMB:
  211. for( j = 0; j < ALIENS; j++ )
  212. {
  213. if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
  214. {
  215. continue;
  216. }
  217. if( x >= al->x[j] && x <= al->x[j] + 4
  218. && y >= al->y[j] && y <= al->y[j] + 2 )
  219. {
  220. al->life[j] -= wp->type[i] == WEAPON_SEEKER ? 1 : 5;
  221. ok = 1;
  222. }
  223. }
  224. if( ok )
  225. {
  226. add_explosion( g, ex, x, y+1, 0, 0, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM );
  227. if( wp->type[i] == WEAPON_FRAGBOMB )
  228. {
  229. wp->n[i] = -1;
  230. }
  231. else
  232. {
  233. wp->type[i] = WEAPON_NONE;
  234. }
  235. }
  236. break;
  237. }
  238. }
  239. }
  240. void collide_player_tunnel( game *g, player *p, tunnel *t, explosions *ex )
  241. {
  242. if( p->dead )
  243. {
  244. return;
  245. }
  246. if( p->x <= t->left[p->y] )
  247. {
  248. p->x += 3;
  249. p->vx = 2;
  250. add_explosion( g, ex, p->x+1, p->y-1, 0, 0, EXPLOSION_SMALL );
  251. p->life -= 180;
  252. }
  253. else if( p->x + 5 >= t->right[p->y] )
  254. {
  255. p->x -= 3;
  256. p->vx = -2;
  257. add_explosion( g, ex, p->x+4, p->y-1, 0, 0, EXPLOSION_SMALL );
  258. p->life -= 180;
  259. }
  260. }