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