372 righe
10 KiB

  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include "common.h"
  4. static void draw_nuke( int x, int y, int frame );
  5. static void draw_beam( int x, int y, int frame );
  6. static void draw_circle( int x, int y, int r, char c );
  7. void init_weapons( game *g, weapons *wp )
  8. {
  9. int i;
  10. for( i = 0; i < WEAPONS; i++ )
  11. {
  12. wp->type[i] = WEAPON_NONE;
  13. }
  14. }
  15. void draw_weapons( game *g, weapons *wp )
  16. {
  17. int i;
  18. for( i = 0; i < WEAPONS; i++ )
  19. {
  20. switch( wp->type[i] )
  21. {
  22. case WEAPON_LASER:
  23. gfx_color( WHITE );
  24. gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
  25. gfx_putchar( '|' );
  26. gfx_color( CYAN );
  27. gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
  28. gfx_putchar( '|' );
  29. break;
  30. case WEAPON_SEEKER:
  31. gfx_color( CYAN );
  32. gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
  33. gfx_putchar( '.' );
  34. gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
  35. gfx_putchar( 'o' );
  36. gfx_color( WHITE );
  37. gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
  38. gfx_putchar( '@' );
  39. break;
  40. case WEAPON_BEAM:
  41. draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
  42. break;
  43. case WEAPON_NUKE:
  44. draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
  45. break;
  46. case WEAPON_NONE:
  47. break;
  48. }
  49. }
  50. }
  51. void update_weapons( game *g, weapons *wp )
  52. {
  53. int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
  54. for( i = 0; i < WEAPONS; i++ )
  55. {
  56. switch( wp->type[i] )
  57. {
  58. case WEAPON_LASER:
  59. wp->x[i] += wp->vx[i];
  60. wp->y[i] += wp->vy[i];
  61. if( wp->y[i] < 0 )
  62. {
  63. wp->type[i] = WEAPON_NONE;
  64. }
  65. break;
  66. case WEAPON_SEEKER:
  67. /* Update tail */
  68. wp->x3[i] = wp->x2[i];
  69. wp->y3[i] = wp->y2[i];
  70. wp->x2[i] = wp->x[i];
  71. wp->y2[i] = wp->y[i];
  72. wp->x[i] += wp->vx[i];
  73. wp->y[i] += wp->vy[i];
  74. if( wp->y[i] < 0 )
  75. {
  76. wp->type[i] = WEAPON_NONE;
  77. break;
  78. }
  79. if( wp->n[i] < 0 )
  80. {
  81. /* Stop updating direction */
  82. break;
  83. }
  84. wp->n[i]--;
  85. /* Estimate our position in 2 frames */
  86. xnew = wp->x[i] + 4 * wp->vx[i];
  87. ynew = wp->y[i] + 4 * wp->vy[i];
  88. xmin = xnew;
  89. ymin = - (g->h << 4);
  90. dist = (xnew - xmin) * (xnew - xmin)
  91. + 4 * (ynew - ymin) * (ynew - ymin);
  92. /* Find the nearest alien */
  93. for( j = 0; j < ALIENS; j++ )
  94. {
  95. if( g->al->type[j] != ALIEN_NONE )
  96. {
  97. int alx = g->al->x[j] << 4;
  98. int aly = g->al->y[j] << 4;
  99. int new = (xnew - alx) * (xnew - alx)
  100. + 4 * (ynew - aly) * (ynew - aly);
  101. if( new <= dist )
  102. {
  103. dist = new;
  104. xmin = alx;
  105. ymin = aly;
  106. }
  107. }
  108. }
  109. /* Find our new direction */
  110. dx = xmin - wp->x[i];
  111. dy = ymin - wp->y[i];
  112. /* Normalize and update speed */
  113. wp->vx[i] = (7 * wp->vx[i]
  114. + (dx * 48) / sqrt(dx*dx+dy*dy) ) / 8;
  115. wp->vy[i] = (7 * wp->vy[i]
  116. + (dy * 24) / sqrt(dx*dx+dy*dy) ) / 8;
  117. break;
  118. case WEAPON_BEAM:
  119. wp->x[i] = (g->p->x + 2) << 4;
  120. wp->y[i] = g->p->y << 4;
  121. wp->n[i]--;
  122. if( wp->n[i] < 0 )
  123. {
  124. wp->type[i] = WEAPON_NONE;
  125. }
  126. break;
  127. case WEAPON_NUKE:
  128. wp->n[i]--;
  129. if( wp->n[i] < 0 )
  130. {
  131. wp->type[i] = WEAPON_NONE;
  132. }
  133. break;
  134. case WEAPON_NONE:
  135. break;
  136. }
  137. }
  138. }
  139. void add_weapon( game *g, weapons *wp, int x, int y, int vx, int vy, int type )
  140. {
  141. int i;
  142. for( i = 0; i < WEAPONS; i++ )
  143. {
  144. if( wp->type[i] == WEAPON_NONE )
  145. {
  146. wp->x[i] = x;
  147. wp->y[i] = y;
  148. wp->vx[i] = vx;
  149. wp->vy[i] = vy;
  150. wp->type[i] = type;
  151. switch( type )
  152. {
  153. case WEAPON_LASER:
  154. break;
  155. case WEAPON_SEEKER:
  156. wp->x2[i] = x;
  157. wp->y2[i] = y;
  158. wp->x3[i] = x;
  159. wp->y3[i] = y;
  160. wp->n[i] = 10;
  161. break;
  162. case WEAPON_BEAM:
  163. wp->n[i] = 25;
  164. break;
  165. case WEAPON_NUKE:
  166. wp->n[i] = 25;
  167. break;
  168. case WEAPON_NONE:
  169. break;
  170. }
  171. break;
  172. }
  173. }
  174. }
  175. static void draw_beam( int x, int y, int frame )
  176. {
  177. int r = (29 - frame) * (29 - frame) / 8;
  178. int i;
  179. switch( frame )
  180. {
  181. case 24:
  182. gfx_color( WHITE );
  183. gfx_goto( x, y-3 );
  184. gfx_putstr( "__" );
  185. gfx_goto( x-1, y-2 );
  186. gfx_putchar( '\'' );
  187. gfx_goto( x+2, y-2 );
  188. gfx_putchar( '`' );
  189. break;
  190. case 23:
  191. gfx_color( CYAN );
  192. gfx_goto( x, y-3 );
  193. gfx_putstr( "__" );
  194. gfx_color( WHITE );
  195. gfx_goto( x-2, y-2 );
  196. gfx_putstr( "-'" );
  197. gfx_goto( x+2, y-2 );
  198. gfx_putstr( "`-" );
  199. break;
  200. case 22:
  201. gfx_color( CYAN );
  202. gfx_goto( x, y-3 );
  203. gfx_putstr( "__" );
  204. gfx_goto( x-1, y-2 );
  205. gfx_putchar( '\'' );
  206. gfx_goto( x+2, y-2 );
  207. gfx_putchar( '`' );
  208. gfx_color( WHITE );
  209. gfx_goto( x-3, y-2 );
  210. gfx_putstr( ",-" );
  211. gfx_goto( x+3, y-2 );
  212. gfx_putstr( "-." );
  213. break;
  214. case 21:
  215. gfx_color( CYAN );
  216. gfx_goto( x-1, y-3 );
  217. gfx_putstr( "____" );
  218. gfx_goto( x-2, y-2 );
  219. gfx_putchar( '\'' );
  220. gfx_goto( x+3, y-2 );
  221. gfx_putchar( '`' );
  222. gfx_color( WHITE );
  223. gfx_goto( x-4, y-2 );
  224. gfx_putstr( ",-" );
  225. gfx_goto( x+4, y-2 );
  226. gfx_putstr( "-." );
  227. break;
  228. case 20:
  229. gfx_color( WHITE );
  230. gfx_goto( x, y-3 );
  231. gfx_putstr( "%%" );
  232. gfx_goto( x-4, y-2 );
  233. gfx_putchar( ',' );
  234. gfx_goto( x+5, y-2 );
  235. gfx_putchar( '.' );
  236. gfx_color( CYAN );
  237. gfx_goto( x-1, y-3 );
  238. gfx_putchar( ':' );
  239. gfx_goto( x+2, y-3 );
  240. gfx_putchar( ':' );
  241. gfx_goto( x-3, y-2 );
  242. gfx_putstr( "-'" );
  243. gfx_goto( x+3, y-2 );
  244. gfx_putstr( "`-" );
  245. break;
  246. case 19:
  247. gfx_color( WHITE );
  248. gfx_goto( x, y-4 );
  249. gfx_putstr( "%%" );
  250. gfx_goto( x, y-3 );
  251. gfx_putstr( "##" );
  252. gfx_color( CYAN );
  253. gfx_goto( x-1, y-4 );
  254. gfx_putchar( ':' );
  255. gfx_goto( x+2, y-4 );
  256. gfx_putchar( ':' );
  257. gfx_goto( x-1, y-3 );
  258. gfx_putchar( '%' );
  259. gfx_goto( x+2, y-3 );
  260. gfx_putchar( '%' );
  261. gfx_goto( x-4, y-2 );
  262. gfx_putstr( ",-'" );
  263. gfx_goto( x+3, y-2 );
  264. gfx_putstr( "`-." );
  265. gfx_color( BLUE );
  266. gfx_goto( x-2, y-3 );
  267. gfx_putchar( ':' );
  268. gfx_goto( x+3, y-3 );
  269. gfx_putchar( ':' );
  270. break;
  271. case 18:
  272. default:
  273. r = (18 - frame) * (18 - frame);
  274. gfx_color( WHITE );
  275. gfx_goto( x-1, y-5-r );
  276. gfx_putstr( ":%%:" );
  277. gfx_goto( x-1, y-4-r );
  278. gfx_putstr( "%##%" );
  279. gfx_color( CYAN );
  280. gfx_goto( x-2, y-4-r );
  281. gfx_putchar( ':' );
  282. gfx_goto( x+3, y-4-r );
  283. gfx_putchar( ':' );
  284. gfx_goto( x-2, y-2 );
  285. gfx_putchar( '\'' );
  286. gfx_goto( x+3, y-2 );
  287. gfx_putchar( '`' );
  288. gfx_color( BLUE );
  289. gfx_goto( x-3, y-2 );
  290. gfx_putchar( ':' );
  291. gfx_goto( x+4, y-2 );
  292. gfx_putchar( ':' );
  293. for( i = 0; i <= r; i++ )
  294. {
  295. gfx_color( WHITE );
  296. gfx_goto( x-1, y-3-i );
  297. gfx_putstr( "####" );
  298. gfx_color( CYAN );
  299. gfx_goto( x-2, y-3-i );
  300. gfx_putchar( '%' );
  301. gfx_goto( x+3, y-3-i );
  302. gfx_putchar( '%' );
  303. gfx_color( BLUE );
  304. gfx_goto( x-3, y-3-i );
  305. gfx_putchar( ':' );
  306. gfx_goto( x+4, y-3-i );
  307. gfx_putchar( ':' );
  308. }
  309. break;
  310. }
  311. }
  312. static void draw_nuke( int x, int y, int frame )
  313. {
  314. int r = (29 - frame) * (29 - frame) / 8;
  315. /* Lots of duplicate pixels, but we don't care */
  316. gfx_color( BLUE );
  317. draw_circle( x, y, r++, ':' );
  318. gfx_color( CYAN );
  319. draw_circle( x, y, r++, '%' );
  320. gfx_color( WHITE );
  321. draw_circle( x, y, r++, '#' );
  322. draw_circle( x, y, r++, '#' );
  323. }
  324. static void draw_circle( int x, int y, int r, char c )
  325. {
  326. int test, dx, dy;
  327. /* Optimized Bresenham. Kick ass. */
  328. for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
  329. {
  330. gfx_putcharTO( x + dx, y + dy / 2, c );
  331. gfx_putcharTO( x - dx, y + dy / 2, c );
  332. gfx_putcharTO( x + dx, y - dy / 2, c );
  333. gfx_putcharTO( x - dx, y - dy / 2, c );
  334. gfx_putcharTO( x + dy, y + dx / 2, c );
  335. gfx_putcharTO( x - dy, y + dx / 2, c );
  336. gfx_putcharTO( x + dy, y - dx / 2, c );
  337. gfx_putcharTO( x - dy, y - dx / 2, c );
  338. test += test > 0 ? dx - dy-- : dx;
  339. }
  340. }