1 /* $Id: hatsuda.c,v 1.231 2005/07/12 20:34:49 oohara Exp $ */
2 /* [hard] 0x82da3104 */
3 /* read: hatsuda satoshi */
4
5 #include <stdio.h>
6 /* malloc, rand */
7 #include <stdlib.h>
8 /* strlen, strcmp */
9 #include <string.h>
10
11 #include "const.h"
12 #include "tenm_object.h"
13 #include "tenm_graphic.h"
14 #include "tenm_primitive.h"
15 #include "util.h"
16 #include "player-shot.h"
17 #include "tenm_table.h"
18 #include "background.h"
19 #include "chain.h"
20 #include "laser.h"
21 #include "normal-shot.h"
22 #include "tenm_math.h"
23 #include "fragment.h"
24 #include "explosion.h"
25 #include "stage-clear.h"
26 #include "score.h"
27 #include "ship.h"
28
29 #include "hatsuda.h"
30
31 #define NEAR_ZERO 0.0001
32
33 static int hatsuda_move(tenm_object *my, double turn_per_frame);
34 static int hatsuda_hit(tenm_object *my, tenm_object *your);
35 static void hatsuda_next(tenm_object *my);
36 static int hatsuda_signal_shroud(tenm_object *my, int n);
37 static int hatsuda_act(tenm_object *my, const tenm_object *player);
38 static void hatsuda_act_reflect(tenm_object *my, const tenm_object *player,
39 int direction);
40 static int hatsuda_draw(tenm_object *my, int priority);
41 static int hatsuda_green(const tenm_object *my);
42
43 static tenm_object *hatsuda_wall_triangle_new(double y, double size,
44 double speed, int n, int t);
45 static int hatsuda_wall_triangle_move(tenm_object *my, double turn_per_frame);
46 static int hatsuda_wall_triangle_act(tenm_object *my,
47 const tenm_object *player);
48 static double hatsuda_wall_triangle_edge(int t);
49 static int hatsuda_wall_triangle_draw(tenm_object *my, int priority);
50
51 static tenm_object *hatsuda_wall_reflect_new(double x, double y,
52 double speed_x, double speed_y,
53 int number_reflect);
54 static int hatsuda_wall_reflect_move(tenm_object *my, double turn_per_frame);
55 static int hatsuda_wall_reflect_act(tenm_object *my,
56 const tenm_object *player);
57 static int hatsuda_wall_reflect_draw(tenm_object *my, int priority);
58
59 static tenm_object *hatsuda_shroud_new(int n);
60 static int hatsuda_shroud_move(tenm_object *my, double turn_per_frame);
61 static int hatsuda_shroud_act(tenm_object *my, const tenm_object *player);
62 static int hatsuda_shroud_draw(tenm_object *my, int priority);
63
64 tenm_object *
hatsuda_new(void)65 hatsuda_new(void)
66 {
67 int i;
68 tenm_object *new = NULL;
69 int *count = NULL;
70 double *count_d = NULL;
71 double x = (double) (WINDOW_WIDTH / 2);
72 double y = ((double) (WINDOW_HEIGHT)) - 286.0 * tenm_cos(45);
73
74 count = (int *) malloc(sizeof(int) * 8);
75 if (count == NULL)
76 {
77 fprintf(stderr, "hatsuda_new: malloc(count) failed\n");
78 return NULL;
79 }
80 count_d = (double *) malloc(sizeof(double) * 2);
81 if (count_d == NULL)
82 {
83 fprintf(stderr, "hatsuda_new: malloc(count_d) failed\n");
84 free(count);
85 return NULL;
86 }
87
88 /* list of count
89 * [0] for deal_damage
90 * [1] "damaged" timer
91 * [2] move mode
92 * [3] move timer
93 * [4] "was green when killed" flag
94 * [5 -- 7] shroud index
95 */
96 /* list of count_d
97 * [0] speed x
98 * [1] speed y
99 */
100
101 count[0] = 0;
102 count[1] = 0;
103 count[2] = 0;
104 count[3] = 0;
105 count[4] = 0;
106 for (i = 0; i < 3; i++)
107 count[5 + i] = -1;
108
109 count_d[0] = 0.0;
110 count_d[1] = 0.0;
111
112 new = tenm_object_new("0x82da3104", ATTR_BOSS, ATTR_PLAYER_SHOT,
113 400, x, y,
114 8, count, 2, count_d, 0, NULL,
115 (int (*)(tenm_object *, double))
116 (&hatsuda_move),
117 (int (*)(tenm_object *, tenm_object *))
118 (&hatsuda_hit),
119 (int (*)(tenm_object *, const tenm_object *))
120 (&hatsuda_act),
121 (int (*)(tenm_object *, int))
122 (&hatsuda_draw));
123 if (new == NULL)
124 {
125 fprintf(stderr, "hatsuda_new: tenm_object_new failed\n");
126 if (count_d != NULL)
127 free(count_d);
128 if (count != NULL)
129 free(count);
130 return NULL;
131 }
132
133 return new;
134 }
135
136 static int
hatsuda_move(tenm_object * my,double turn_per_frame)137 hatsuda_move(tenm_object *my, double turn_per_frame)
138 {
139 double dx_temp;
140 double dy_temp;
141
142 /* sanity check */
143 if (my == NULL)
144 {
145 fprintf(stderr, "hatsuda_move: my is NULL\n");
146 return 0;
147 }
148 if (turn_per_frame <= 0.5)
149 {
150 fprintf(stderr, "hatsuda_move: strange turn_per_frame (%f)\n",
151 turn_per_frame);
152 return 0;
153 }
154
155 dx_temp = my->count_d[0] / turn_per_frame;
156 dy_temp = my->count_d[1] / turn_per_frame;
157 my->x += dx_temp;
158 my->y += dy_temp;
159 if (my->mass != NULL)
160 tenm_move_mass(my->mass, dx_temp, dy_temp);
161
162 return 0;
163 }
164
165 static int
hatsuda_hit(tenm_object * my,tenm_object * your)166 hatsuda_hit(tenm_object *my, tenm_object *your)
167 {
168 /* sanity check */
169 if (my == NULL)
170 {
171 fprintf(stderr, "hatsuda_hit: my is NULL\n");
172 return 0;
173 }
174 if (your == NULL)
175 {
176 fprintf(stderr, "hatsuda_hit: your is NULL\n");
177 return 0;
178 }
179
180 if (!(your->attr & ATTR_PLAYER_SHOT))
181 return 0;
182 if ((my->count[2] != 1) && (my->count[2] != 3) && (my->count[2] != 5))
183 return 0;
184 if ((my->count[2] == 5) && (my->count[3] < 290))
185 return 0;
186
187 deal_damage(my, your, 0);
188 if (hatsuda_green(my))
189 add_chain(my, your);
190 my->count[1] = 2;
191
192 if (my->hit_point <= 0)
193 {
194 if (my->count[2] == 1)
195 add_score(10000);
196 else if (my->count[2] == 3)
197 add_score(15000);
198 else if (my->count[2] == 5)
199 add_score(35000);
200 set_background(1);
201 hatsuda_next(my);
202 return 0;
203 }
204
205 return 0;
206 }
207
208 static void
hatsuda_next(tenm_object * my)209 hatsuda_next(tenm_object *my)
210 {
211 int n;
212 int i;
213
214 /* sanity check */
215 if (my == NULL)
216 {
217 fprintf(stderr, "hatsuda_next: my is NULL\n");
218 return;
219 }
220
221 if ((my->count[2] != 1) && (my->count[2] != 3) && (my->count[2] != 5))
222 return;
223
224 tenm_table_apply_all((int (*)(tenm_object *, int)) (&delete_enemy_shot), 0);
225 tenm_table_apply_all((int (*)(tenm_object *, int)) (&delete_enemy), 0);
226
227 /* don't modify my->attr or my->hit_mask here, or the player shot
228 * may fly through the enemy */
229 tenm_mass_delete(my->mass);
230 my->mass = NULL;
231
232 /* set "was green" flag before we change the life mode */
233 if (hatsuda_green(my))
234 {
235 n = 8;
236 my->count[4] = 1;
237 }
238 else
239 {
240 n = 7;
241 my->count[4] = 0;
242 }
243
244 if (my->count[2] == 1)
245 {
246 tenm_table_add(explosion_new(my->x, my->y,
247 0.0, 0.0,
248 1, 3000, n, 10.0, 8));
249 tenm_table_add(explosion_new(my->x, my->y,
250 0.0, 0.0,
251 2, 800, n, 6.0, 8));
252 my->hit_point = 750;
253 my->count[2] = 2;
254 my->count[3] = 0;
255 my->count[1] = 0;
256 my->count_d[0] = 0.0;
257 my->count_d[1] = 0.0;
258 }
259 if (my->count[2] == 3)
260 {
261 tenm_table_add(explosion_new(my->x, my->y,
262 0.0, 0.0,
263 1, 3000, n, 10.0, 8));
264 tenm_table_add(fragment_new(my->x, my->y, 0.0, 0.0,
265 30.0, 100, n, 4.0, 0.0, 16));
266 tenm_table_add(fragment_new(my->x, my->y, 0.0, 0.0,
267 50.0, 30, n, 2.5, 0.0, 12));
268 my->hit_point = 400;
269 my->count[2] = 4;
270 my->count[3] = 0;
271 my->count[1] = 0;
272 my->count_d[0] = 0.0;
273 my->count_d[1] = 0.0;
274 }
275 if (my->count[2] == 5)
276 {
277 tenm_table_add(explosion_new(my->x, my->y, 0.0, 0.0,
278 1, 5000, n, 10.0, 6));
279 my->count[2] = 6;
280 my->count[3] = 0;
281 my->count[1] = 0;
282 my->count_d[0] = 0.0;
283 my->count_d[1] = 0.5;
284
285 for (i = 0; i < 3; i++)
286 if (my->count[5 + i] >= 0)
287 tenm_table_apply(my->count[5 + i],
288 (int (*)(tenm_object *, int))
289 (&hatsuda_signal_shroud),
290 0);
291 }
292 }
293
294 static int
hatsuda_signal_shroud(tenm_object * my,int n)295 hatsuda_signal_shroud(tenm_object *my, int n)
296 {
297 /* sanity check */
298 if (my == NULL)
299 return 0;
300 if (strcmp(my->name, "0x82da3104 shroud") != 0)
301 return 0;
302
303 tenm_table_add(explosion_new(my->x, my->y, 0.0, 0.0,
304 1, 1000, 9, 4.0, 6));
305 tenm_table_add(fragment_new(my->x, my->y, 0.0, 0.0,
306 30.0, 100, 9, 4.0, 0.0, 16));
307 tenm_table_add(fragment_new(my->x, my->y, 0.0, 0.0,
308 50.0, 30, 9, 2.5, 0.0, 12));
309
310 return 1;
311 }
312
313 static int
hatsuda_act(tenm_object * my,const tenm_object * player)314 hatsuda_act(tenm_object *my, const tenm_object *player)
315 {
316 int theta;
317 int i;
318 tenm_primitive **p = NULL;
319 int n;
320
321 /* sanity check */
322 if (my == NULL)
323 {
324 fprintf(stderr, "hatsuda_act: my is NULL\n");
325 return 0;
326 }
327 if (player == NULL)
328 return 0;
329
330 /* for deal_damage */
331 my->count[0] = 0;
332
333 /* "damaged" count down */
334 if (my->count[1] > 0)
335 (my->count[1])--;
336
337 (my->count[3])++;
338 /* speed change */
339 if (my->count[2] == 1)
340 {
341 my->count_d[0] = hatsuda_wall_triangle_edge(my->count[3]) - my->x;
342 my->count_d[1] = 0.0;
343 }
344
345 /* encounter */
346 if (my->count[2] == 0)
347 {
348 if (my->count[3] == 60)
349 {
350 my->count_d[0] = (((double) (WINDOW_WIDTH / 2)) - my->x) / 60.0;
351 my->count_d[1] = (40.0 - my->y) / 60.0;
352 return 0;
353 }
354 if (my->count[3] >= 120)
355 {
356 my->count[2] = 1;
357 my->count[3] = 0;
358 my->count[4] = 0;
359 my->count_d[0] = 0.0;
360 my->count_d[1] = 0.0;
361
362 p = (tenm_primitive **) malloc(sizeof(tenm_primitive *) * 1);
363 if (p == NULL)
364 {
365 fprintf(stderr, "hatsuda_act: malloc(p) failed (form 1)\n");
366 return 0;
367 }
368
369 p[0] = (tenm_primitive *) tenm_circle_new(my->x, my->y, 25.0);
370 if (p[0] == NULL)
371 {
372 fprintf(stderr, "hatsuda_act: cannot set p[0] (form 1)\n");
373 free(p);
374 return 0;
375 }
376
377 my->mass = tenm_mass_new(1, p);
378 if (my->mass == NULL)
379 {
380 fprintf(stderr, "hatsuda_act: tenm_mass_new failed (form 1)\n");
381 (p[0])->delete(p[0]);
382 free(p);
383 return 0;
384 }
385
386 return 0;
387 }
388
389 return 0;
390 }
391 else if (my->count[2] == 2)
392 {
393 if (my->count[3] == 30)
394 {
395 my->count_d[0] = (((double) (WINDOW_WIDTH / 2)) - my->x) / 60.0;
396 my->count_d[1] = (((double) (WINDOW_HEIGHT / 2)) - my->y) / 60.0;
397 return 0;
398 }
399 if (my->count[3] == 90)
400 {
401 my->count_d[0] = 0.0;
402 my->count_d[1] = 0.0;
403 return 0;
404 }
405 if (my->count[3] >= 120)
406 {
407 my->count[2] = 3;
408 my->count[3] = 0;
409 my->count[4] = 0;
410 my->count_d[0] = 0.0;
411 my->count_d[1] = 0.0;
412
413 p = (tenm_primitive **) malloc(sizeof(tenm_primitive *) * 1);
414 if (p == NULL)
415 {
416 fprintf(stderr, "hatsuda_act: malloc(p) failed (form 2)\n");
417 return 0;
418 }
419
420 p[0] = (tenm_primitive *) tenm_polygon_new(4,
421 my->x + 50.0 * tenm_cos(45),
422 my->y + 50.0 * tenm_cos(45),
423 my->x - 50.0 * tenm_cos(15),
424 my->y + 50.0 * tenm_cos(45),
425 my->x - 50.0 * tenm_cos(15),
426 my->y - 50.0 * tenm_cos(15),
427 my->x + 50.0 * tenm_cos(45),
428 my->y - 50.0 * tenm_cos(15));
429 if (p[0] == NULL)
430 {
431 fprintf(stderr, "hatsuda_act: cannot set p[0] (form 2)\n");
432 free(p);
433 return 0;
434 }
435
436 my->mass = tenm_mass_new(1, p);
437 if (my->mass == NULL)
438 {
439 fprintf(stderr, "hatsuda_act: tenm_mass_new failed (form 2)\n");
440 (p[0])->delete(p[0]);
441 free(p);
442 return 0;
443 }
444
445 return 0;
446 }
447
448 return 0;
449 }
450 else if (my->count[2] == 4)
451 {
452 if (my->count[3] >= 90)
453 {
454 my->count[2] = 5;
455 my->count[3] = 0;
456 my->count[4] = 0;
457 my->count_d[0] = 0.0;
458 my->count_d[1] = 0.0;
459
460 p = (tenm_primitive **) malloc(sizeof(tenm_primitive *) * 1);
461 if (p == NULL)
462 {
463 fprintf(stderr, "hatsuda_act: malloc(p) failed (form 3)\n");
464 return 0;
465 }
466
467 p[0] = (tenm_primitive *) tenm_polygon_new(3,
468 my->x + 50.0 * tenm_cos(45),
469 my->y + 50.0 * tenm_sin(45),
470 my->x + 50.0 * tenm_cos(165),
471 my->y + 50.0 * tenm_sin(165),
472 my->x + 50.0 * tenm_cos(285),
473 my->y + 50.0 * tenm_sin(285));
474 if (p[0] == NULL)
475 {
476 fprintf(stderr, "hatsuda_act: cannot set p[0] (form 3)\n");
477 free(p);
478 return 0;
479 }
480
481 my->mass = tenm_mass_new(1, p);
482 if (my->mass == NULL)
483 {
484 fprintf(stderr, "hatsuda_act: tenm_mass_new failed (form 3)\n");
485 (p[0])->delete(p[0]);
486 free(p);
487 return 0;
488 }
489
490 return 0;
491 }
492
493 return 0;
494 }
495
496 /* dead */
497 if (my->count[2] == 6)
498 {
499 if (hatsuda_green(my))
500 i = 8;
501 else
502 i = 7;
503
504 if ((my->count[3] >= 30) && (my->count[3] <= 75)
505 && (my->count[3] % 15 == 0))
506 {
507 theta = rand() % 360;
508 tenm_table_add(explosion_new(my->x + 30.0 * tenm_cos(theta),
509 my->y + 30.0 * tenm_sin(theta),
510 0.0, 0.0,
511 2, 300, i, 5.0, 8));
512 }
513
514 if (my->count[3] > 120)
515 {
516 tenm_table_add(explosion_new(my->x, my->y,
517 0.0, 0.0,
518 1, 3000, i, 10.0, 8));
519 tenm_table_add(fragment_new(my->x, my->y, 0.0, 0.0,
520 30.0, 100, i, 4.0, 0.0, 16));
521 tenm_table_add(fragment_new(my->x, my->y, 0.0, 0.0,
522 50.0, 30, i, 2.5, 0.0, 12));
523
524 tenm_table_add(stage_clear_new(100));
525 return 1;
526 }
527
528 return 0;
529 }
530
531 /* self-destruction */
532 if (((my->count[2] == 1) && (my->count[3] >= 2052))
533 || ((my->count[2] == 3) && (my->count[3] >= 1850))
534 || ((my->count[2] == 5) && (my->count[3] >= 2230)))
535 {
536 set_background(2);
537 clear_chain();
538 hatsuda_next(my);
539 return 0;
540 }
541
542 /* shoot */
543 if ((my->count[2] == 1) && (my->count[3] <= 1872))
544 {
545 if (my->count[3] % 17 == 0)
546 {
547 tenm_table_add(laser_point_new(my->x, my->y, 5.0,
548 player->x, player->y, 25.0, 4));
549 }
550
551 if (my->count[3] % 26 == 13)
552 n = 1;
553 else
554 n = 0;
555 if (my->count[3] % 312 >= 156)
556 n = 1 - n;
557 switch (my->count[3] % 156)
558 {
559 case 13:
560 tenm_table_add(hatsuda_wall_triangle_new(40.0, 40.0, 5.5, n,
561 my->count[3]));
562 break;
563 case 26:
564 tenm_table_add(hatsuda_wall_triangle_new(200.0, 40.0, -5.5, n,
565 my->count[3]));
566 break;
567 case 39:
568 if (my->count[3] > 312)
569 tenm_table_add(hatsuda_wall_triangle_new(360.0, 40.0, 5.5, n,
570 my->count[3]));
571 break;
572 case 52:
573 tenm_table_add(hatsuda_wall_triangle_new(120.0, 40.0, -5.5, n,
574 my->count[3]));
575 break;
576 case 65:
577 tenm_table_add(hatsuda_wall_triangle_new(280.0, 40.0, 5.5, n,
578 my->count[3]));
579 break;
580 case 78:
581 if (my->count[3] > 312)
582 tenm_table_add(hatsuda_wall_triangle_new(440.0, 40.0, -5.5, n,
583 my->count[3]));
584 break;
585 case 91:
586 tenm_table_add(hatsuda_wall_triangle_new(40.0, 40.0, -5.5, n,
587 my->count[3]));
588 break;
589 case 104:
590 tenm_table_add(hatsuda_wall_triangle_new(200.0, 40.0, 5.5, n,
591 my->count[3]));
592 break;
593 case 117:
594 if (my->count[3] > 312)
595 tenm_table_add(hatsuda_wall_triangle_new(360.0, 40.0, -5.5, n,
596 my->count[3]));
597 break;
598 case 130:
599 tenm_table_add(hatsuda_wall_triangle_new(120.0, 40.0, 5.5, n,
600 my->count[3]));
601 break;
602 case 143:
603 if (my->count[3] > 312)
604 tenm_table_add(hatsuda_wall_triangle_new(280.0, 40.0, -5.5, 0,
605 my->count[3]));
606 break;
607 case 0:
608 if (my->count[3] > 312)
609 tenm_table_add(hatsuda_wall_triangle_new(440.0, 40.0, 5.5, n,
610 my->count[3]));
611 break;
612 default:
613 break;
614 }
615 }
616
617 if ((my->count[2] == 3) && (my->count[3] <= 1720))
618 {
619 if (my->count[3] % 86 == 0)
620 {
621 hatsuda_act_reflect(my, player, 3);
622 hatsuda_act_reflect(my, player, 7);
623 }
624 if (my->count[3] % 86 == 43)
625 {
626 hatsuda_act_reflect(my, player, 9);
627 hatsuda_act_reflect(my, player, 1);
628 }
629 if ((my->count[3] > 172) && (my->count[3] % 7 == 0))
630 {
631 theta = -90 + (my->count[3] -172) * (-6);
632 tenm_table_add(laser_angle_new(my->x, my->y, 4.0,
633 theta, 25.0, 3));
634 tenm_table_add(laser_angle_new(my->x, my->y, 2.5,
635 theta - 5, 25.0, 3));
636 tenm_table_add(laser_angle_new(my->x, my->y, 2.5,
637 theta + 5, 25.0, 3));
638 tenm_table_add(laser_angle_new(my->x, my->y, 6.0,
639 theta - 11, 25.0, 3));
640 tenm_table_add(laser_angle_new(my->x, my->y, 6.0,
641 theta + 11, 25.0, 3));
642 }
643 }
644
645 if (my->count[2] == 5)
646 {
647 if (my->count[3] == 30)
648 for (i = 0; i < 3; i++)
649 my->count[5 + i] = tenm_table_add(hatsuda_shroud_new(i));
650
651 if ((my->count[3] >= 530) && (my->count[3] <= 2100)
652 && (my->count[3] % 5 == 0))
653 tenm_table_add(normal_shot_point_new(my->x, my->y, 7.0,
654 player->x
655 + (double) ((rand() % 151) - 75),
656 player->y
657 + (double) ((rand() % 151) - 75),
658 4));
659 }
660
661 return 0;
662 }
663
664 /* reflection shot
665 * direction
666 * 789
667 * 4*6
668 * 123
669 */
670 static void
hatsuda_act_reflect(tenm_object * my,const tenm_object * player,int direction)671 hatsuda_act_reflect(tenm_object *my, const tenm_object *player,
672 int direction)
673 {
674 double x_aim;
675 double y_aim;
676 int number_reflect;
677 double dx;
678 double dy;
679 double length;
680
681 /* sanity check */
682 if (my == NULL)
683 {
684 fprintf(stderr, "hatsuda_act_reflect: my is NULL\n");
685 return;
686 }
687 if (player == NULL)
688 return;
689 if ((direction < 1) || (direction > 9) || (direction == 5))
690 {
691 fprintf(stderr, "hatsuda_act_reflect: strange direction(%d)\n",
692 direction);
693 return;
694 }
695
696 x_aim = player->x;
697 y_aim = player->y;
698 number_reflect = 0;
699 if ((direction == 7) || (direction == 4) || (direction == 1))
700 {
701 x_aim = -x_aim;
702 number_reflect++;
703 }
704 if ((direction == 9) || (direction == 6) || (direction == 3))
705 {
706 x_aim = 2.0 * ((double) WINDOW_WIDTH) - x_aim;
707 number_reflect++;
708 }
709 if ((direction == 1) || (direction == 2) || (direction == 3))
710 {
711 y_aim = -y_aim;
712 number_reflect++;
713 }
714 if ((direction == 7) || (direction == 8) || (direction == 9))
715 {
716 y_aim = 2.0 * ((double) WINDOW_HEIGHT) - y_aim;
717 number_reflect++;
718 }
719
720 dx = x_aim - my->x;
721 dy = y_aim - my->y;
722 length = tenm_sqrt((int) (dx * dx + dy * dy));
723 if (length < NEAR_ZERO)
724 length = 1.0;
725 tenm_table_add(hatsuda_wall_reflect_new(my->x, my->y,
726 6.0 * dx / length,
727 6.0 * dy / length,
728 number_reflect));
729 }
730
731 static int
hatsuda_draw(tenm_object * my,int priority)732 hatsuda_draw(tenm_object *my, int priority)
733 {
734 int status = 0;
735 tenm_color color;
736 char temp[32];
737 double x;
738 int theta;
739 int i;
740 double c;
741 double length;
742
743 /* sanity check */
744 if (my == NULL)
745 {
746 fprintf(stderr, "hatsuda_draw: my is NULL\n");
747 return 0;
748 }
749
750 /* decoration */
751 if (priority == 0)
752 {
753 if (hatsuda_green(my))
754 {
755 if (my->count[1] >= 1)
756 color = tenm_map_color(181, 190, 92);
757 else
758 color = tenm_map_color(157, 182, 123);
759 }
760 else
761 {
762 if (my->count[1] >= 1)
763 color = tenm_map_color(200, 164, 92);
764 else
765 color = tenm_map_color(182, 147, 123);
766 }
767
768 if (my->count[2] == 0)
769 {
770 if (my->count[3] <= 60)
771 {
772 c = ((double) (my->count[3])) / 60.0;
773 for (i = 0; i < 360; i += 120)
774 {
775 if (tenm_draw_line((int) (my->x + 286.0 * tenm_cos(45 + i)),
776 (int) (my->y + 286.0 * tenm_sin(45 + i)),
777 (int) (my->x
778 + 286.0 * tenm_cos(45 + i) * (1.0 - c)
779 + 286.0 * tenm_cos(165 + i) * c),
780 (int) (my->y
781 + 286.0 * tenm_sin(45 + i) * (1.0 - c)
782 + 286.0 * tenm_sin(165 + i) * c),
783 1, color))
784 status = 1;
785 }
786 }
787 else if (my->count[3] <= 120)
788 {
789 c = ((double) (my->count[3] - 60)) / 60.0;
790 length = 286.0 * (1.0 - c) + 50.0 * c;
791 for (i = 0; i < 360; i += 120)
792 {
793 theta = 45 + i + (my->count[3] - 60) * 6;
794 if (tenm_draw_line((int) (my->x + length * tenm_cos(theta)),
795 (int) (my->y + length * tenm_sin(theta)),
796 (int) (my->x + length * tenm_cos(theta + 120)),
797 (int) (my->y + length * tenm_sin(theta + 120)),
798 1, color))
799 status = 1;
800 }
801 }
802 }
803 else if ((my->count[2] == 1) || (my->count[2] == 3) || (my->count[2] == 4))
804 {
805 for (i = 0; i < 360; i += 120)
806 {
807 if (tenm_draw_line((int) (my->x + 50.0 * tenm_cos(45 + i)),
808 (int) (my->y + 50.0 * tenm_sin(45 + i)),
809 (int) (my->x + 50.0 * tenm_cos(165 + i)),
810 (int) (my->y + 50.0 * tenm_sin(165 + i)),
811 1, color))
812 status = 1;
813 }
814 }
815 else if (my->count[2] == 2)
816 {
817 for (i = 0; i < 360; i += 120)
818 {
819 if ((my->count[3] < 30) || (my->count[3] >= 90))
820 theta = 45 + i;
821 else
822 theta = 45 + i + (my->count[3] - 30) * 6;
823 if (tenm_draw_line((int) (my->x + 50.0 * tenm_cos(theta)),
824 (int) (my->y + 50.0 * tenm_sin(theta)),
825 (int) (my->x + 50.0 * tenm_cos(theta + 120)),
826 (int) (my->y + 50.0 * tenm_sin(theta + 120)),
827 1, color))
828 status = 1;
829 }
830 }
831
832 if (my->count[2] == 1)
833 {
834 color = tenm_map_color(158, 158, 158);
835 x = hatsuda_wall_triangle_edge(my->count[3]);
836 if (tenm_draw_line((int) x, 0, (int) x, WINDOW_HEIGHT, 1, color))
837 status = 1;
838 }
839
840 if ((my->count[2] == 2)
841 &&(my->count[3] > 90) && (my->count[3] <= 120))
842 {
843 color = tenm_map_color(95, 47, 13);
844 length = 50.0 + ((double) (120 - my->count[3])) * 3.0;
845 if (tenm_draw_line((int) (my->x + length * tenm_cos(45)),
846 (int) (my->y + length * tenm_cos(45)),
847 (int) (my->x - length * tenm_cos(15)),
848 (int) (my->y + length * tenm_cos(45)),
849 1, color))
850 status = 1;
851 if (tenm_draw_line((int) (my->x - length * tenm_cos(15)),
852 (int) (my->y + length * tenm_cos(45)),
853 (int) (my->x - length * tenm_cos(15)),
854 (int) (my->y - length * tenm_cos(15)),
855 1, color))
856 status = 1;
857 if (tenm_draw_line((int) (my->x - length * tenm_cos(15)),
858 (int) (my->y - length * tenm_cos(15)),
859 (int) (my->x + length * tenm_cos(45)),
860 (int) (my->y - length * tenm_cos(15)),
861 1, color))
862 status = 1;
863 if (tenm_draw_line((int) (my->x + length * tenm_cos(45)),
864 (int) (my->y - length * tenm_cos(15)),
865 (int) (my->x + length * tenm_cos(45)),
866 (int) (my->y + length * tenm_cos(45)),
867 1, color))
868 status = 1;
869 }
870 if ((my->count[2] == 4)
871 &&(my->count[3] > 30) && (my->count[3] <= 90))
872 {
873 color = tenm_map_color(95, 47, 13);
874 length = 50.0 + ((double) (90 - my->count[3])) * 3.0;
875 for (i = 0; i < 360; i += 120)
876 {
877 theta = 45 + i + (my->count[3] - 30) * 6;
878 if (tenm_draw_line((int) (my->x + length * tenm_cos(theta)),
879 (int) (my->y + length * tenm_sin(theta)),
880 (int) (my->x + length * tenm_cos(theta + 120)),
881 (int) (my->y + length * tenm_sin(theta + 120)),
882 1, color))
883 status = 1;
884 }
885 }
886 }
887
888 /* body */
889 /* dead enemy has low priority */
890 if (((my->count[2] <= 1) && (priority == 0))
891 || ((my->count[2] > 1) && (priority == -1)))
892 {
893 if (hatsuda_green(my))
894 {
895 if (my->count[1] >= 1)
896 color = tenm_map_color(109, 125, 9);
897 else
898 color = tenm_map_color(61, 95, 13);
899 }
900 else
901 {
902 if (my->count[1] >= 1)
903 color = tenm_map_color(135, 89, 9);
904 else
905 color = tenm_map_color(95, 47, 13);
906 }
907
908 if (my->count[2] == 1)
909 {
910 if (tenm_draw_circle((int) (my->x), (int) (my->y), 25, 3, color) != 0)
911 status = 1;
912 }
913 else if (my->count[2] == 3)
914 {
915 length = 50.0;
916 if (tenm_draw_line((int) (my->x + length * tenm_cos(45)),
917 (int) (my->y + length * tenm_cos(45)),
918 (int) (my->x - length * tenm_cos(15)),
919 (int) (my->y + length * tenm_cos(45)),
920 3, color))
921 status = 1;
922 if (tenm_draw_line((int) (my->x - length * tenm_cos(15)),
923 (int) (my->y + length * tenm_cos(45)),
924 (int) (my->x - length * tenm_cos(15)),
925 (int) (my->y - length * tenm_cos(15)),
926 3, color))
927 status = 1;
928 if (tenm_draw_line((int) (my->x - length * tenm_cos(15)),
929 (int) (my->y - length * tenm_cos(15)),
930 (int) (my->x + length * tenm_cos(45)),
931 (int) (my->y - length * tenm_cos(15)),
932 3, color))
933 status = 1;
934 if (tenm_draw_line((int) (my->x + length * tenm_cos(45)),
935 (int) (my->y - length * tenm_cos(15)),
936 (int) (my->x + length * tenm_cos(45)),
937 (int) (my->y + length * tenm_cos(45)),
938 3, color))
939 status = 1;
940 }
941 else if ((my->count[2] == 5) || (my->count[2] == 6))
942 {
943 length = 50.0;
944 for (i = 0; i < 360; i += 120)
945 {
946 theta = 45 + i;
947 if (tenm_draw_line((int) (my->x + length * tenm_cos(theta)),
948 (int) (my->y + length * tenm_sin(theta)),
949 (int) (my->x + length * tenm_cos(theta + 120)),
950 (int) (my->y + length * tenm_sin(theta + 120)),
951 3, color))
952 status = 1;
953 }
954 }
955 }
956
957 /* hit point stat */
958 if ((priority == 0)
959 &&((my->count[2] == 1)
960 || (my->count[2] == 3)
961 || ((my->count[2] == 5) && (my->count[3] >= 290))))
962 {
963 sprintf(temp, "%d", my->hit_point);
964 if (draw_string(((int) my->x) - 5, (int) my->y,
965 temp, (int) strlen(temp)) != 0)
966 {
967 fprintf(stderr, "hatsuda_draw: draw_string failed\n");
968 status = 1;
969 }
970 }
971
972 return status;
973 }
974
975 /* return 1 (true) or 0 (false) */
976 static int
hatsuda_green(const tenm_object * my)977 hatsuda_green(const tenm_object *my)
978 {
979 /* sanity check */
980 if (my == NULL)
981 return 0;
982
983 if ((my->count[2] == 1)
984 && (my->count[3] > 312) && (my->count[3] < 2022))
985 return 1;
986 if ((my->count[2] == 2) && (my->count[4] != 0)
987 && (my->count[3] < 30))
988 return 1;
989 if ((my->count[2] == 3)
990 && (my->count[3] > 172) && (my->count[3] < 1820))
991 return 1;
992 if ((my->count[2] == 4) && (my->count[4] != 0)
993 && (my->count[3] < 30))
994 return 1;
995 if ((my->count[2] == 5)
996 && (my->count[3] >= 530) && (my->count[3] < 2200))
997 return 1;
998 if ((my->count[2] == 6) && (my->count[4] != 0))
999 return 1;
1000
1001 return 0;
1002 }
1003
1004 static tenm_object *
hatsuda_wall_triangle_new(double y,double size,double speed,int n,int t)1005 hatsuda_wall_triangle_new(double y, double size, double speed, int n, int t)
1006 {
1007 tenm_primitive **p = NULL;
1008 tenm_object *new = NULL;
1009 int *count = NULL;
1010 double *count_d = NULL;
1011 double x;
1012
1013 /* sanity check */
1014 if (size < NEAR_ZERO)
1015 {
1016 fprintf(stderr, "hatsuda_wall_triangle_new: size is non-positive "
1017 "(%f)\n", size);
1018 return NULL;
1019 }
1020 if ((n < 0) || (n > 1))
1021 {
1022 fprintf(stderr, "hatsuda_wall_triangle_new: strange n (%d)\n", n);
1023 return NULL;
1024 }
1025
1026 p = (tenm_primitive **) malloc(sizeof(tenm_primitive *) * 1);
1027 if (p == NULL)
1028 {
1029 fprintf(stderr, "hatsuda_wall_triangle_new: malloc(p) failed\n");
1030 return NULL;
1031 }
1032
1033 if (speed > 0.0)
1034 x = 1.0 - size;
1035 else
1036 x = ((double) (WINDOW_WIDTH)) - 1.0 + size;
1037
1038 if (n == 0)
1039 {
1040 p[0] = (tenm_primitive *) tenm_polygon_new(3,
1041 x - size, y - size,
1042 x - size, y + size,
1043 x + size, y + size);
1044 }
1045 else
1046 {
1047 p[0] = (tenm_primitive *) tenm_polygon_new(3,
1048 x + size, y - size,
1049 x + size, y + size,
1050 x - size, y + size);
1051 }
1052 if (p[0] == NULL)
1053 {
1054 fprintf(stderr, "hatsuda_wall_triangle_new: cannot set p[0]\n");
1055 free(p);
1056 return NULL;
1057 }
1058
1059 count = (int *) malloc(sizeof(int) * 6);
1060 if (count == NULL)
1061 {
1062 fprintf(stderr, "hatsuda_wall_triangle_new: malloc(count) failed\n");
1063 (p[0])->delete(p[0]);
1064 free(p);
1065 return NULL;
1066 }
1067 count_d = (double *) malloc(sizeof(double) * 3);
1068 if (count_d == NULL)
1069 {
1070 fprintf(stderr, "hatsuda_wall_triangle_new: malloc(count_d) failed\n");
1071 free(count);
1072 (p[0])->delete(p[0]);
1073 free(p);
1074 return NULL;
1075 }
1076
1077 /* list of count
1078 * [0] n
1079 * [1] move mode
1080 * [2] move timer
1081 */
1082 /* list of count_d
1083 * [0] speed x
1084 * [1] speed y
1085 * [2] size
1086 */
1087
1088 count[0] = n;
1089 count[1] = 0;
1090 count[2] = t;
1091
1092 count_d[0] = speed;
1093 count_d[1] = 0.0;
1094 count_d[2] = size;
1095
1096 new = tenm_object_new("0x82da3104 wall triangle",
1097 ATTR_ENEMY | ATTR_OPAQUE, 0,
1098 1, x, y,
1099 6, count, 3, count_d, 1, p,
1100 (int (*)(tenm_object *, double))
1101 (&hatsuda_wall_triangle_move),
1102 (int (*)(tenm_object *, tenm_object *))
1103 NULL,
1104 (int (*)(tenm_object *, const tenm_object *))
1105 (&hatsuda_wall_triangle_act),
1106 (int (*)(tenm_object *, int))
1107 (&hatsuda_wall_triangle_draw));
1108 if (new == NULL)
1109 {
1110 fprintf(stderr, "hatsuda_wall_triangle_new: tenm_object_new failed\n");
1111 if (count_d != NULL)
1112 free(count_d);
1113 if (count != NULL)
1114 free(count);
1115 (p[0])->delete(p[0]);
1116 free(p);
1117 return NULL;
1118 }
1119
1120 return new;
1121 }
1122
1123 static int
hatsuda_wall_triangle_move(tenm_object * my,double turn_per_frame)1124 hatsuda_wall_triangle_move(tenm_object *my, double turn_per_frame)
1125 {
1126 double dx_temp;
1127 double dy_temp;
1128
1129 /* sanity check */
1130 if (my == NULL)
1131 {
1132 fprintf(stderr, "hatsuda_wall_triangle_move: my is NULL\n");
1133 return 0;
1134 }
1135 if (turn_per_frame <= 0.5)
1136 {
1137 fprintf(stderr, "hatsuda_wall_triangle_move: "
1138 "strange turn_per_frame (%f)\n",
1139 turn_per_frame);
1140 return 0;
1141 }
1142
1143 dx_temp = my->count_d[0] / turn_per_frame;
1144 dy_temp = my->count_d[1] / turn_per_frame;
1145 my->x += dx_temp;
1146 my->y += dy_temp;
1147 if (my->mass != NULL)
1148 tenm_move_mass(my->mass, dx_temp, dy_temp);
1149
1150 if (!in_window_object(my))
1151 return 1;
1152
1153 return 0;
1154 }
1155
1156 static int
hatsuda_wall_triangle_act(tenm_object * my,const tenm_object * player)1157 hatsuda_wall_triangle_act(tenm_object *my, const tenm_object *player)
1158 {
1159 double edge_x;
1160
1161 /* sanity check */
1162 if (my == NULL)
1163 {
1164 fprintf(stderr, "hatsuda_wall_triangle_act: my is NULL\n");
1165 return 0;
1166 }
1167 if (player == NULL)
1168 return 0;
1169
1170 (my->count[2])++;
1171 if (my->count[1] == 0)
1172 {
1173 edge_x = hatsuda_wall_triangle_edge(my->count[2]);
1174 if ((my->x + my->count_d[2] >= edge_x)
1175 && (my->x - my->count_d[2] <= edge_x))
1176 {
1177 my->count[1] = 1;
1178 my->count[2] = 0;
1179 if (my->count_d[0] > 0.0)
1180 my->count_d[1] = my->count_d[0];
1181 else
1182 my->count_d[1] = -my->count_d[0];
1183 if (my->y - my->count_d[2] > player->y)
1184 my->count_d[1] *= -1.0;
1185 my->count_d[0] = 0.0;
1186 }
1187 }
1188
1189 return 0;
1190 }
1191
1192 static double
hatsuda_wall_triangle_edge(int t)1193 hatsuda_wall_triangle_edge(int t)
1194 {
1195 if (t < 180)
1196 return ((double) (WINDOW_WIDTH / 2));
1197
1198 return ((double) (WINDOW_WIDTH / 2))
1199 + ((double) (WINDOW_WIDTH / 3)) * tenm_sin(t * 2);
1200 }
1201
1202 static int
hatsuda_wall_triangle_draw(tenm_object * my,int priority)1203 hatsuda_wall_triangle_draw(tenm_object *my, int priority)
1204 {
1205 int status = 0;
1206 tenm_color color;
1207 double size;
1208
1209 /* sanity check */
1210 if (my == NULL)
1211 {
1212 fprintf(stderr, "hatsuda_wall_triangle_draw: my is NULL\n");
1213 return 0;
1214 }
1215
1216 if (priority != 0)
1217 return 0;
1218
1219 /* body */
1220 color = tenm_map_color(95, 13, 68);
1221 size = my->count_d[2];
1222
1223 if (my->count[0] == 0)
1224 {
1225 if (tenm_draw_line((int) (my->x - size), (int) (my->y - size),
1226 (int) (my->x - size), (int) (my->y + size),
1227 3, color))
1228 status = 1;
1229 if (tenm_draw_line((int) (my->x - size), (int) (my->y + size),
1230 (int) (my->x + size), (int) (my->y + size),
1231 3, color))
1232 status = 1;
1233 if (tenm_draw_line((int) (my->x + size), (int) (my->y + size),
1234 (int) (my->x - size), (int) (my->y - size),
1235 3, color))
1236 status = 1;
1237 }
1238 else
1239 {
1240 if (tenm_draw_line((int) (my->x + size), (int) (my->y - size),
1241 (int) (my->x + size), (int) (my->y + size),
1242 3, color))
1243 status = 1;
1244 if (tenm_draw_line((int) (my->x + size), (int) (my->y + size),
1245 (int) (my->x - size), (int) (my->y + size),
1246 3, color))
1247 status = 1;
1248 if (tenm_draw_line((int) (my->x - size), (int) (my->y + size),
1249 (int) (my->x + size), (int) (my->y - size),
1250 3, color))
1251 status = 1;
1252 }
1253
1254 return status;
1255 }
1256
1257 static tenm_object *
hatsuda_wall_reflect_new(double x,double y,double speed_x,double speed_y,int number_reflect)1258 hatsuda_wall_reflect_new(double x, double y, double speed_x, double speed_y,
1259 int number_reflect)
1260 {
1261 tenm_primitive **p = NULL;
1262 tenm_object *new = NULL;
1263 int *count = NULL;
1264 double *count_d = NULL;
1265
1266 /* sanity check */
1267 if (number_reflect < 0)
1268 {
1269 fprintf(stderr, "hatsuda_wall_reflect_new: number_reflect is negative "
1270 "(%d)\n", number_reflect);
1271 return NULL;
1272 }
1273
1274 p = (tenm_primitive **) malloc(sizeof(tenm_primitive *) * 1);
1275 if (p == NULL)
1276 {
1277 fprintf(stderr, "hatsuda_wall_reflect_new: malloc(p) failed\n");
1278 return NULL;
1279 }
1280
1281 p[0] = (tenm_primitive *) tenm_polygon_new(4,
1282 x + 20.0, y + 20.0,
1283 x - 20.0, y + 20.0,
1284 x - 20.0, y - 20.0,
1285 x + 20.0, y - 20.0);
1286 if (p[0] == NULL)
1287 {
1288 fprintf(stderr, "hatsuda_wall_reflect_new: cannot set p[0]\n");
1289 free(p);
1290 return NULL;
1291 }
1292
1293 count = (int *) malloc(sizeof(int) * 1);
1294 if (count == NULL)
1295 {
1296 fprintf(stderr, "hatsuda_wall_reflect_new: malloc(count) failed\n");
1297 (p[0])->delete(p[0]);
1298 free(p);
1299 return NULL;
1300 }
1301 count_d = (double *) malloc(sizeof(double) * 2);
1302 if (count_d == NULL)
1303 {
1304 fprintf(stderr, "hatsuda_wall_reflect_new: malloc(count_d) failed\n");
1305 free(count);
1306 (p[0])->delete(p[0]);
1307 free(p);
1308 return NULL;
1309 }
1310
1311 /* list of count
1312 * [0] number_reflect
1313 */
1314 /* list of count_d
1315 * [0] speed x
1316 * [1] speed y
1317 */
1318
1319 count[0] = number_reflect;
1320
1321 count_d[0] = speed_x;
1322 count_d[1] = speed_y;
1323
1324 new = tenm_object_new("0x82da3104 wall reflect",
1325 ATTR_ENEMY | ATTR_OPAQUE, 0,
1326 1, x, y,
1327 1, count, 2, count_d, 1, p,
1328 (int (*)(tenm_object *, double))
1329 (&hatsuda_wall_reflect_move),
1330 (int (*)(tenm_object *, tenm_object *))
1331 NULL,
1332 (int (*)(tenm_object *, const tenm_object *))
1333 (&hatsuda_wall_reflect_act),
1334 (int (*)(tenm_object *, int))
1335 (&hatsuda_wall_reflect_draw));
1336 if (new == NULL)
1337 {
1338 fprintf(stderr, "hatsuda_wall_reflect_new: tenm_object_new failed\n");
1339 if (count_d != NULL)
1340 free(count_d);
1341 if (count != NULL)
1342 free(count);
1343 (p[0])->delete(p[0]);
1344 free(p);
1345 return NULL;
1346 }
1347
1348 return new;
1349 }
1350
1351 static int
hatsuda_wall_reflect_move(tenm_object * my,double turn_per_frame)1352 hatsuda_wall_reflect_move(tenm_object *my, double turn_per_frame)
1353 {
1354 double dx_temp;
1355 double dy_temp;
1356
1357 /* sanity check */
1358 if (my == NULL)
1359 {
1360 fprintf(stderr, "hatsuda_wall_reflect_move: my is NULL\n");
1361 return 0;
1362 }
1363 if (turn_per_frame <= 0.5)
1364 {
1365 fprintf(stderr, "hatsuda_wall_reflect_move: "
1366 "strange turn_per_frame (%f)\n",
1367 turn_per_frame);
1368 return 0;
1369 }
1370
1371 dx_temp = my->count_d[0] / turn_per_frame;
1372 dy_temp = my->count_d[1] / turn_per_frame;
1373 my->x += dx_temp;
1374 my->y += dy_temp;
1375 if (my->mass != NULL)
1376 tenm_move_mass(my->mass, dx_temp, dy_temp);
1377
1378 if (!in_window_object(my))
1379 return 1;
1380
1381 return 0;
1382 }
1383
1384 static int
hatsuda_wall_reflect_act(tenm_object * my,const tenm_object * player)1385 hatsuda_wall_reflect_act(tenm_object *my, const tenm_object *player)
1386 {
1387 int reflected = 0;
1388
1389 /* sanity check */
1390 if (my == NULL)
1391 {
1392 fprintf(stderr, "hatsuda_wall_reflect_act: my is NULL\n");
1393 return 0;
1394 }
1395 if (player == NULL)
1396 return 0;
1397
1398 /* don't reflect if the player is immutable */
1399 if ((get_ship() < 0) || (player->count[1] > 0))
1400 my->count[0] = 0;
1401
1402 if (my->count[0] > 0)
1403 {
1404 if ((my->x < 0.0) || (my->x > ((double) WINDOW_WIDTH)))
1405 {
1406 my->count_d[0] *= -1.0;
1407 reflected = 1;
1408 }
1409 if ((my->y < 0.0) || (my->y > ((double) WINDOW_HEIGHT)))
1410 {
1411 my->count_d[1] *= -1.0;
1412 reflected = 1;
1413 }
1414 if (reflected != 0)
1415 (my->count[0])--;
1416 }
1417
1418 return 0;
1419 }
1420
1421 static int
hatsuda_wall_reflect_draw(tenm_object * my,int priority)1422 hatsuda_wall_reflect_draw(tenm_object *my, int priority)
1423 {
1424 int status = 0;
1425 tenm_color color;
1426
1427 /* sanity check */
1428 if (my == NULL)
1429 {
1430 fprintf(stderr, "hatsuda_wall_reflect_draw: my is NULL\n");
1431 return 0;
1432 }
1433
1434 if (priority != 0)
1435 return 0;
1436
1437 /* body */
1438 color = tenm_map_color(95, 13, 68);
1439
1440 if (tenm_draw_line((int) (my->x + 20.0), (int) (my->y + 20.0),
1441 (int) (my->x - 20.0), (int) (my->y + 20.0),
1442 3, color))
1443 status = 1;
1444 if (tenm_draw_line((int) (my->x - 20.0), (int) (my->y + 20.0),
1445 (int) (my->x - 20.0), (int) (my->y - 20.0),
1446 3, color))
1447 status = 1;
1448 if (tenm_draw_line((int) (my->x - 20.0), (int) (my->y - 20.0),
1449 (int) (my->x + 20.0), (int) (my->y - 20.0),
1450 3, color))
1451 status = 1;
1452 if (tenm_draw_line((int) (my->x + 20.0), (int) (my->y - 20.0),
1453 (int) (my->x + 20.0), (int) (my->y + 20.0),
1454 3, color))
1455 status = 1;
1456
1457 return status;
1458 }
1459
1460 static tenm_object *
hatsuda_shroud_new(int n)1461 hatsuda_shroud_new(int n)
1462 {
1463 tenm_primitive **p = NULL;
1464 tenm_object *new = NULL;
1465 int *count = NULL;
1466 double *count_d = NULL;
1467 double x;
1468 double y;
1469 double dx_a;
1470 double dy_a;
1471 double dx_b;
1472 double dy_b;
1473
1474 /* sanity check */
1475 if ((n < 0) || (n > 2))
1476 {
1477 fprintf(stderr, "hatsuda_shroud_new: strange n (%d)\n", n);
1478 return NULL;
1479 }
1480
1481 x = (double) (WINDOW_WIDTH / 2);
1482 y = (double) (WINDOW_HEIGHT / 2);
1483 x += 200.0 * tenm_cos(n * 120);
1484 y += 200.0 * tenm_sin(n * 120);
1485 dx_a = 150.0 * tenm_cos(n * 120);
1486 dy_a = 150.0 * tenm_sin(n * 120);
1487 dx_b = 5.0 * tenm_cos(n * 120 + 90);
1488 dy_b = 5.0 * tenm_sin(n * 120 + 90);
1489
1490 p = (tenm_primitive **) malloc(sizeof(tenm_primitive *) * 1);
1491 if (p == NULL)
1492 {
1493 fprintf(stderr, "hatsuda_shroud_new: malloc(p) failed\n");
1494 return NULL;
1495 }
1496
1497 p[0] = (tenm_primitive *) tenm_polygon_new(4,
1498 x + dx_a + dx_b,
1499 y + dy_a + dy_b,
1500 x - dx_a + dx_b,
1501 y - dy_a + dy_b,
1502 x - dx_a - dx_b,
1503 y - dy_a - dy_b,
1504 x + dx_a - dx_b,
1505 y + dy_a - dy_b);
1506 if (p[0] == NULL)
1507 {
1508 fprintf(stderr, "hatsuda_shroud_new: cannot set p[0]\n");
1509 free(p);
1510 return NULL;
1511 }
1512
1513 count = (int *) malloc(sizeof(int) * 10);
1514 if (count == NULL)
1515 {
1516 fprintf(stderr, "hatsuda_shroud_new: malloc(count) failed\n");
1517 (p[0])->delete(p[0]);
1518 free(p);
1519 return NULL;
1520 }
1521 count_d = (double *) malloc(sizeof(double) * 2);
1522 if (count_d == NULL)
1523 {
1524 fprintf(stderr, "hatsuda_shroud_new: malloc(count_d) failed\n");
1525 free(count);
1526 (p[0])->delete(p[0]);
1527 free(p);
1528 return NULL;
1529 }
1530
1531 /* list of count
1532 * [0] n
1533 * [1] move mode
1534 * [2] move timer
1535 */
1536 /* list of count_d
1537 * [0] speed x
1538 * [1] speed y
1539 */
1540
1541 count[0] = n;
1542 count[1] = 0;
1543 count[2] = 0;
1544
1545 count_d[0] = 0.0;
1546 count_d[1] = 0.0;
1547
1548 new = tenm_object_new("0x82da3104 shroud",
1549 0, 0,
1550 1, x, y,
1551 10, count, 2, count_d, 1, p,
1552 (int (*)(tenm_object *, double))
1553 (&hatsuda_shroud_move),
1554 (int (*)(tenm_object *, tenm_object *))
1555 NULL,
1556 (int (*)(tenm_object *, const tenm_object *))
1557 (&hatsuda_shroud_act),
1558 (int (*)(tenm_object *, int))
1559 (&hatsuda_shroud_draw));
1560 if (new == NULL)
1561 {
1562 fprintf(stderr, "hatsuda_shroud_new: tenm_object_new failed\n");
1563 if (count_d != NULL)
1564 free(count_d);
1565 if (count != NULL)
1566 free(count);
1567 (p[0])->delete(p[0]);
1568 free(p);
1569 return NULL;
1570 }
1571
1572 return new;
1573 }
1574
1575 static int
hatsuda_shroud_move(tenm_object * my,double turn_per_frame)1576 hatsuda_shroud_move(tenm_object *my, double turn_per_frame)
1577 {
1578 double dx_temp;
1579 double dy_temp;
1580
1581 /* sanity check */
1582 if (my == NULL)
1583 {
1584 fprintf(stderr, "hatsuda_shroud_move: my is NULL\n");
1585 return 0;
1586 }
1587 if (turn_per_frame <= 0.5)
1588 {
1589 fprintf(stderr, "hatsuda_shroud_move: strange turn_per_frame (%f)\n",
1590 turn_per_frame);
1591 return 0;
1592 }
1593
1594 dx_temp = my->count_d[0] / turn_per_frame;
1595 dy_temp = my->count_d[1] / turn_per_frame;
1596 my->x += dx_temp;
1597 my->y += dy_temp;
1598 if (my->mass != NULL)
1599 tenm_move_mass(my->mass, dx_temp, dy_temp);
1600
1601 if (!in_window_object(my))
1602 return 1;
1603
1604 return 0;
1605 }
1606
1607 static int
hatsuda_shroud_act(tenm_object * my,const tenm_object * player)1608 hatsuda_shroud_act(tenm_object *my, const tenm_object *player)
1609 {
1610 double x;
1611 double y;
1612 int i;
1613 double dx_a;
1614 double dy_a;
1615 int theta;
1616
1617 /* sanity check */
1618 if (my == NULL)
1619 {
1620 fprintf(stderr, "hatsuda_shroud_act: my is NULL\n");
1621 return 0;
1622 }
1623 if (player == NULL)
1624 return 0;
1625
1626 /* speed change */
1627 (my->count[2])++;
1628 if (my->count[1] == 1)
1629 {
1630 if (my->count[2] < 200)
1631 {
1632 my->count_d[0] = 0.0;
1633 my->count_d[1] = 0.0;
1634 }
1635 else
1636 {
1637 if (my->count[2] < 1100)
1638 theta = my->count[0] * 120 + my->count[2] - 200;
1639 else if (my->count[2] < 1200)
1640 theta = my->count[0] * 120 + 1100 - 200;
1641 else
1642 theta = my->count[0] * 120 + 1100 - 200 - (my->count[2] - 1200);
1643 x = (double) (WINDOW_WIDTH / 2);
1644 y = (double) (WINDOW_HEIGHT / 2);
1645 x += 200.0 * tenm_cos(theta);
1646 y += 200.0 * tenm_sin(theta);
1647 my->count_d[0] = x - my->x;
1648 my->count_d[1] = y - my->y;
1649 }
1650 }
1651
1652 /* encounter */
1653 if (my->count[1] == 0)
1654 {
1655 my->count_d[0] = 0.0;
1656 my->count_d[1] = 0.0;
1657 if (my->count[2] > 60)
1658 {
1659 my->attr = ATTR_BOSS | ATTR_OPAQUE;
1660 my->hit_mask = 0;
1661 my->count[1] = 1;
1662 my->count[2] = 0;
1663 return 0;
1664 }
1665 return 0;
1666 }
1667
1668 if (my->count[1] != 1)
1669 return 0;
1670
1671 /* shoot */
1672 if ((my->count[2] <= 2010)
1673 && (((my->count[2] >= 132) && (my->count[2] % 11 == 0))
1674 || (my->count[2] % 33 == 0)))
1675 {
1676 dx_a = 150.0 * tenm_cos(my->count[0] * 120);
1677 dy_a = 150.0 * tenm_sin(my->count[0] * 120);
1678 for (i = -60; i <= 60; i += 60)
1679 {
1680 tenm_table_add(laser_angle_new(my->x + dx_a,
1681 my->y + dy_a,
1682 6.0, my->count[0] * 120 + i,
1683 25.0, 1));
1684 tenm_table_add(laser_angle_new(my->x - dx_a,
1685 my->y - dy_a,
1686 6.0, my->count[0] * 120 + i + 180,
1687 25.0, 1));
1688 }
1689 }
1690
1691 return 0;
1692 }
1693
1694 static int
hatsuda_shroud_draw(tenm_object * my,int priority)1695 hatsuda_shroud_draw(tenm_object *my, int priority)
1696 {
1697 int status = 0;
1698 tenm_color color;
1699 int width;
1700 double dx_a;
1701 double dy_a;
1702 double dx_b;
1703 double dy_b;
1704
1705 /* sanity check */
1706 if (my == NULL)
1707 {
1708 fprintf(stderr, "hatsuda_shroud_draw: my is NULL\n");
1709 return 0;
1710 }
1711
1712 if (priority != 0)
1713 return 0;
1714
1715 /* body */
1716 if (my->count[1] == 0)
1717 width = 1;
1718 else
1719 width = 3;
1720 if ((my->count[1] == 0) && (my->count[2] < 30))
1721 color = tenm_map_color(182, 123, 162);
1722 else
1723 color = tenm_map_color(95, 13, 68);
1724 dx_a = 150.0 * tenm_cos(my->count[0] * 120);
1725 dy_a = 150.0 * tenm_sin(my->count[0] * 120);
1726 dx_b = 5.0 * tenm_cos(my->count[0] * 120 + 90);
1727 dy_b = 5.0 * tenm_sin(my->count[0] * 120 + 90);
1728
1729 if (tenm_draw_line((int) (my->x + dx_a + dx_b),
1730 (int) (my->y + dy_a + dy_b),
1731 (int) (my->x - dx_a + dx_b),
1732 (int) (my->y - dy_a + dy_b),
1733 width, color))
1734 status = 1;
1735 if (tenm_draw_line((int) (my->x - dx_a + dx_b),
1736 (int) (my->y - dy_a + dy_b),
1737 (int) (my->x - dx_a - dx_b),
1738 (int) (my->y - dy_a - dy_b),
1739 width, color))
1740 status = 1;
1741 if (tenm_draw_line((int) (my->x - dx_a - dx_b),
1742 (int) (my->y - dy_a - dy_b),
1743 (int) (my->x + dx_a - dx_b),
1744 (int) (my->y + dy_a - dy_b),
1745 width, color))
1746 status = 1;
1747 if (tenm_draw_line((int) (my->x + dx_a - dx_b),
1748 (int) (my->y + dy_a - dy_b),
1749 (int) (my->x + dx_a + dx_b),
1750 (int) (my->y + dy_a + dy_b),
1751 width, color))
1752 status = 1;
1753
1754 return status;
1755 }
1756