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