1 /* xsoldier, a shoot 'em up game with "not shooting" bonus
2 * Copyright (C) 1997 Yuusuke HASHIMOTO <s945750@educ.info.kanagawa-u.ac.jp>
3 * Copyright (C) 2002 Oohara Yuuma <oohara@libra.interq.or.jp>
4 *
5 * This is a copyleft program. See the file LICENSE for details.
6 */
7 /* $Id: boss.c,v 1.21 2002/05/26 08:31:59 oohara Exp $ */
8
9 /* DEBUG is defined in config.h */
10 #include <config.h>
11 /* rand */
12 #include <stdlib.h>
13
14 /*
15 #include <X11/Xlib.h>
16 #include <X11/xpm.h>
17 */
18
19 #include "image.h"
20 #include "xsoldier.h"
21 #include "manage.h"
22 #include "common.h"
23 #include "enemyshot.h"
24 #include "callback.h"
25 #include "boss.h"
26 #include "enemy.h"
27 #include "extern.h"
28 #include "sin.h"
29
30 /* local functions for the last boss */
31 static DelAtt BossAct8_dead(ObjData *my);
32 static DelAtt BossAct8_rand_shot(ObjData *my);
33 static DelAtt BossAct8_ring_shot(ObjData *my);
34 static DelAtt BossAct8_bound_shot(ObjData *my);
35 static DelAtt BossAct8_homing_shot(ObjData *my);
36 static DelAtt BossAct8_charge_shot(ObjData *my);
37 static DelAtt BossAct8_n_way_shot(ObjData *my);
38 static void BossAct8_next(ObjData *my, int span);
39
40 /* definition of objects
41 * - initialization function
42 * - action function
43 * - hit function
44 *
45 * initialization add action function and display/hit function to the table
46 */
47
NewBoss1(void)48 int NewBoss1(void)
49 {
50 manage->New.Data.hitAtt = MEnemy;
51 manage->New.Data.hitMask = MPlayer | MPShot;
52
53 manage->New.Data.X = FieldW/2;
54 manage->New.Data.Y = -90;
55
56 manage->New.Data.HP = 120;
57 manage->New.Data.Point = 5000;
58 manage->New.Data.EnemyAtt = BossDel;
59
60 manage->New.Data.Width = 150;
61 manage->New.Data.Height = 180;
62
63 manage->New.Data.Cnt[0] = 0;
64 manage->New.Data.Cnt[1] = 200; /* immutable time */
65 manage->New.Data.Cnt[2] = 0; /* image counter*/
66 manage->New.Data.Cnt[3] = 10; /* x move */
67 manage->New.Data.Cnt[4] = 0; /* y move */
68 manage->New.Data.Cnt[5] = 0; /* laser counter */
69 manage->New.Data.Cnt[6] = 0; /* normal shot counter */
70
71 manage->New.Grp.image = Boss1Image;
72 return NewObj(MEnemy,BossAct1,BossHit1,DrawImage);
73 }
74
BossAct1(ObjData * my)75 DelAtt BossAct1(ObjData *my)
76 {
77 int i;
78
79 if (my->Cnt[0] < my->Cnt[1])
80 {/* appears slowly */
81 my->Y++;
82 my->Cnt[0]++;
83 return NoneDel;
84 }
85
86 if (manage->BossTime <= 0)
87 {
88 if (my->Y > 0 - my->Height/2 - 100)
89 (my->Y) -= 4;
90 if (my->Y < 0 - my->Height/2 - 50)
91 {
92 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
93 return NoneDel;
94 else
95 return BossDel;
96 }
97 else
98 return NoneDel;
99 }
100
101 (manage->BossTime)--;
102
103 if (my->Cnt[6] >= (100- (manage->Loop)*10) )
104 {
105 ShotToAngle(my->X, my->Y, 50, 10);
106 ShotToAngle(my->X, my->Y, 70, 10);
107 ShotToAngle(my->X, my->Y, 90, 10);
108 ShotToAngle(my->X, my->Y, 110, 10);
109 ShotToAngle(my->X, my->Y, 130, 10);
110 my->Cnt[6] =0;
111 }
112 else
113 (my->Cnt[6])++;
114
115 if (my->Cnt[5] >= (25-manage->Loop*3))
116 {
117 for (i = 1; i< manage->Loop; i++)
118 ShotToAngle(my->X,my->Y,rand()%180,10);
119 if (manage->Loop >1)
120 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,10);
121 LaserShot(my->X-30,my->Y,20);
122 LaserShot(my->X+30,my->Y,20);
123 LaserShot(my->X-80,my->Y,20);
124 LaserShot(my->X+80,my->Y,20);
125
126 my->Cnt[5] = 0;
127 }
128 else
129 my->Cnt[5]++;
130
131 if ((my->X+my->Cnt[3]>FieldW) || (my->X+my->Cnt[3]<0))
132 my->Cnt[3] = my->Cnt[3]*(-1);
133
134 my->X += my->Cnt[3];
135
136 return NoneDel;
137 }
138
BossHit1(ObjData * my,ObjData * your)139 DelAtt BossHit1(ObjData *my, ObjData *your)
140 {
141 int temp = your->Attack;
142
143 if ((my->Cnt[0] < my->Cnt[1]) || (manage->BossTime <=0))
144 {
145 return NoneDel;
146 }
147
148 if (my->HP < temp)
149 {
150 temp = my->HP;
151 }
152
153 my->HP -= temp;
154 player->Rec[0].score += temp;
155
156 if (my->HP <= 0)
157 {
158 player->Rec[0].score -= 1;
159 NewBomb(my->X,my->Y);
160 NewBomb(my->X+rand()%100-50,my->Y+rand()%100-50);
161 NewBomb(my->X+rand()%100-50,my->Y+rand()%100-50);
162 NewBomb(my->X+rand()%100-50,my->Y+rand()%100-50);
163 NewBomb(my->X+rand()%100-50,my->Y+rand()%100-50);
164 NewBomb(my->X+rand()%100-50,my->Y+rand()%100-50);
165 NewBomb(my->X+rand()%100-50,my->Y+rand()%100-50);
166
167 my->showDamegeTime = 0;
168 return my->EnemyAtt;
169 }
170 else
171 {
172 my->showDamegeTime = 15;
173 return NoneDel;
174 }
175
176 }
177
NewBoss2(void)178 int NewBoss2(void)
179 {
180 manage->New.Data.hitAtt = MEnemy;
181 manage->New.Data.hitMask = MPlayer | MPShot;
182
183 manage->New.Data.X = FieldW/2;
184 manage->New.Data.Y = -60;
185
186 manage->New.Data.HP = 200;
187 manage->New.Data.Point = 5000;
188 manage->New.Data.EnemyAtt = BossDel;
189
190 manage->New.Data.Width = 90;
191 manage->New.Data.Height = 130;
192
193 manage->New.Data.Cnt[0] = 0;
194 manage->New.Data.Cnt[1] = 200; /* immutable time */
195 manage->New.Data.Cnt[2] = 0; /* image counter */
196
197 manage->New.Data.Cnt[3] = 0;
198 manage->New.Data.Cnt[4] = 0;
199 manage->New.Data.Cnt[5] = 0; /* normal shot counter */
200
201 manage->New.Grp.image = Boss2Image;
202 return NewObj(MEnemy,BossAct2,BossHit1,DrawImage);
203 }
204
BossAct2(ObjData * my)205 DelAtt BossAct2(ObjData *my)
206 {
207 if (my->Cnt[0] < my->Cnt[1])
208 {/* appears slowly */
209 my->Y++;
210 my->Cnt[0]++;
211 return NoneDel;
212 }
213
214 if (manage->BossTime <= 0)
215 {
216 if (my->Y > 0 - my->Height/2 - 100)
217 (my->Y) -= 4;
218 if (my->Y < 0 - my->Height/2 - 50)
219 {
220 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
221 return NoneDel;
222 else
223 return BossDel;
224 }
225 else
226 return NoneDel;
227 }
228
229 (manage->BossTime)--;
230
231 if (manage->Loop > 2)
232 {
233 if (my->Cnt[5] >= 90- (manage->Loop)*10)
234 {
235 ShotToPoint(my->X+40,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%3 + 5);
236 ShotToPoint(my->X ,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,8);
237 ShotToPoint(my->X-40,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%5 + 3);
238 my->Cnt[5] = 0;
239 }
240 else
241 (my->Cnt[5])++;
242 }
243
244 if (my->Cnt[3] >= (15-manage->Loop*3))
245 {
246 if (manage->Loop > 1)
247 {
248 if (manage->player[0]->Data.Y < my->Y)
249 ShotToAngle(my->X, my->Y, 270, 10);
250 else
251 ShotToAngle(my->X, my->Y, 90, 10);
252 }
253
254 HomingShot(my->X-20,my->Y-10,-10,-10);
255 HomingShot(my->X+20,my->Y-10, 10,-10);
256 my->Cnt[3] = 0;
257 }
258 else
259 my->Cnt[3]++;
260
261 if (my->X > manage->player[0]->Data.X)
262 {
263 if (my->X - manage->player[0]->Data.X > 20)
264 {
265 my->X -= 10;
266 }
267 else
268 {
269 my->Cnt[4]++;
270 my->X --;
271 }
272
273 if (my->Cnt[4] > 10)
274 {
275 LaserShot(my->X-40,my->Y,30);
276 LaserShot(my->X+40,my->Y,30);
277 my->Cnt[4] = 0;
278 }
279 }
280 else
281 {
282 if (manage->player[0]->Data.X - my->X > 20)
283 {
284 my->X += 10;
285 }
286 else
287 {
288 my->Cnt[4]++;
289 my->X ++;
290 }
291
292 if (my->Cnt[4] > 10)
293 {
294 LaserShot(my->X-40,my->Y,30);
295 LaserShot(my->X+40,my->Y,30);
296 my->Cnt[4] = 0;
297 }
298 }
299
300 return NoneDel;
301 }
302
NewBoss3(void)303 int NewBoss3(void)
304 {
305 manage->New.Data.hitAtt = MEnemy;
306 manage->New.Data.hitMask = MPlayer | MPShot;
307
308 manage->New.Data.X = FieldW/2;
309 manage->New.Data.Y = -80;
310
311 manage->New.Data.HP = 330;
312 manage->New.Data.Point = 6000;
313 manage->New.Data.EnemyAtt = BossDel;
314
315 manage->New.Data.Width = 130;
316 manage->New.Data.Height = 130;
317
318 manage->New.Data.Cnt[0] = 0;
319 manage->New.Data.Cnt[1] = 200; /* immutable time */
320 manage->New.Data.Cnt[2] = 0; /* image counter */
321 manage->New.Data.Cnt[3] = 10; /* x move */
322 manage->New.Data.Cnt[4] = 0; /* y move */
323 manage->New.Data.Cnt[5] = 0; /* laser counter */
324 manage->New.Data.Cnt[6] = 0; /* missile counter */
325
326 manage->New.Grp.image = Boss3Image;
327 return NewObj(MEnemy,BossAct3,BossHit1,DrawImage);
328 }
329
BossAct3(ObjData * my)330 DelAtt BossAct3(ObjData *my)
331 {
332 if (my->Cnt[0] < my->Cnt[1])
333 {/* appears slowly */
334 my->Y++;
335 my->Cnt[0]++;
336 return NoneDel;
337 }
338
339 if (manage->BossTime <= 0)
340 {
341 if (my->Y > 0 - my->Height/2 - 100)
342 (my->Y) -= 4;
343 if (my->Y < 0 - my->Height/2 - 50)
344 {
345 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
346 return NoneDel;
347 else
348 return BossDel;
349 }
350 else
351 return NoneDel;
352 }
353
354 (manage->BossTime)--;
355
356 if (my->Cnt[6] >= (80 - manage->Loop*10))
357 {
358 HomingShot(my->X,my->Y,0,10);
359 HomingShot(my->X,my->Y,10,0);
360 HomingShot(my->X,my->Y,0,-10);
361 HomingShot(my->X,my->Y,-10,0);
362 HomingShot(my->X,my->Y,10,10);
363 HomingShot(my->X,my->Y,-10,10);
364 HomingShot(my->X,my->Y,10,-10);
365 HomingShot(my->X,my->Y,-10,-10);
366
367 my->Cnt[6] = 0;
368 }
369 else
370 my->Cnt[6]++;
371
372 if (my->Cnt[5] >= (25 - manage->Loop*2))
373 {
374 if (manage->Loop >1)
375 LaserShot(my->X- 120+ (rand()%5)*60,my->Y,25);
376 if (manage->Loop >2)
377 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,18);
378 LaserShot(my->X-30,my->Y,25);
379 LaserShot(my->X+30,my->Y,25);
380 LaserShot(my->X-90,my->Y,25);
381 LaserShot(my->X+90,my->Y,25);
382 LaserShot(my->X-150,my->Y,25);
383 LaserShot(my->X+150,my->Y,25);
384
385 my->Cnt[5] = 0;
386 }
387 else
388 my->Cnt[5]++;
389
390 if ((my->X+my->Cnt[3]>FieldW) || (my->X+my->Cnt[3]<0))
391 my->Cnt[3] = my->Cnt[3]*(-1);
392
393 my->X += my->Cnt[3];
394
395 return NoneDel;
396 }
397
NewBoss4(void)398 int NewBoss4(void)
399 {
400 manage->New.Data.hitAtt = MEnemy;
401 manage->New.Data.hitMask = MPlayer | MPShot;
402
403 manage->New.Data.X = FieldW/2;
404 manage->New.Data.Y = -90;
405
406 manage->New.Data.inertX = 0;
407 manage->New.Data.inertY = 0;
408
409 manage->New.Data.HP = 550;
410 manage->New.Data.Point = 6000;
411 manage->New.Data.EnemyAtt = BossDel;
412
413 manage->New.Data.Width = 300;
414 manage->New.Data.Height = 170;
415
416 manage->New.Data.Cnt[0] = 0;
417 manage->New.Data.Cnt[1] = 195; /* immutable time */
418 manage->New.Data.Cnt[2] = 0; /* image counter */
419 manage->New.Data.Cnt[3] = 1; /* x move */
420 manage->New.Data.Cnt[4] = 0; /* y move */
421 manage->New.Data.Cnt[5] = 0; /* laser counter */
422
423 manage->New.Grp.image = Boss4Image;
424 return NewObj(MEnemy,BossAct4,BossHit1,DrawImage);
425 }
426
BossAct4(ObjData * my)427 DelAtt BossAct4(ObjData *my)
428 {
429 if (my->Cnt[0] < my->Cnt[1])
430 {/* appears slowly */
431 my->Y++;
432 my->Cnt[0]++;
433 return NoneDel;
434 }
435
436 if (manage->BossTime <= 0)
437 {
438 if (my->Y > 0 - my->Height/2 - 100)
439 (my->Y) -= 4;
440 if (my->Y < 0 - my->Height/2 - 50)
441 {
442 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
443 return NoneDel;
444 else
445 return BossDel;
446 }
447 else
448 return NoneDel;
449 }
450
451 (manage->BossTime)--;
452
453 if (my->Cnt[5] >= (8-manage->Loop))
454 {
455 LaserShot(my->X + rand()%600-300, my->Y, 11 + rand()%3 + manage->Loop*7);
456 LaserShot(my->X + rand()%600-300, my->Y, 6 + rand()%3 + manage->Loop*7);
457 LaserShot(my->X + rand()%600-300, my->Y, 1 + rand()%3 + manage->Loop*7);
458 LaserShot(my->X + rand()%600-300, my->Y, -4 + rand()%3 + manage->Loop*7);
459 if (manage->Loop >2)
460 LaserShot(my->X + rand()%600-300, my->Y, 6 + rand()%3 + manage->Loop*7);
461 if (manage->Loop >1)
462 LaserShot(my->X + rand()%600-300, my->Y, 1 + rand()%3 + manage->Loop*7);
463 my->Cnt[5] = 0;
464 }
465 else
466 my->Cnt[5]++;
467
468 if (my->X < manage->player[0]->Data.X)
469 {
470 if (my->inertX <= 8)
471 my->inertX++;
472 }
473 if (my->X > manage->player[0]->Data.X)
474 {
475 if (my->inertX >= -8)
476 my->inertX--;
477 }
478
479 my->X += my->inertX;
480
481 return NoneDel;
482 }
483
NewBoss5(void)484 int NewBoss5(void)
485 {
486 manage->New.Data.hitAtt = MEnemy;
487 manage->New.Data.hitMask = MPlayer | MPShot;
488
489 manage->New.Data.X = FieldW/2;
490 manage->New.Data.Y = -128;
491
492 manage->New.Data.HP = 350;
493 manage->New.Data.Point = 7000;
494 manage->New.Data.EnemyAtt = BossDel;
495
496 manage->New.Data.Width = 120;
497 manage->New.Data.Height = 120;
498
499 manage->New.Data.Cnt[0] = 0;
500 manage->New.Data.Cnt[1] = 200; /* immutable time */
501 manage->New.Data.Cnt[2] = 0; /* image counter */
502 manage->New.Data.Cnt[3] = manage->player[0]->Data.X; /* x move */
503 manage->New.Data.Cnt[4] = manage->player[0]->Data.Y; /* y move */
504 manage->New.Data.Cnt[5] = 0; /* shot counter */
505 manage->New.Data.Cnt[6] = 0; /* angle counter */
506
507 manage->New.Grp.image = Boss5Image;
508 return NewObj(MEnemy,BossAct5,BossHit1,DrawImage);
509 }
510
BossAct5(ObjData * my)511 DelAtt BossAct5(ObjData *my)
512 {
513 int i;
514
515 if (my->Cnt[0] < my->Cnt[1])
516 {/* appears slowly */
517 my->Y++;
518 my->Cnt[0]++;
519 return NoneDel;
520 }
521
522 if (manage->BossTime <= 0)
523 {
524 if (my->Y > 0 - my->Height/2 - 100)
525 (my->Y) -= 4;
526 if (my->Y < 0 - my->Height/2 - 50)
527 {
528 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
529 return NoneDel;
530 else
531 return BossDel;
532 }
533 else
534 return NoneDel;
535 }
536
537 (manage->BossTime)--;
538
539 if (my->Cnt[5] > 120)
540 {
541 my->Cnt[3] = manage->player[0]->Data.X;
542 my->Cnt[4] = manage->player[0]->Data.Y;
543 my->Cnt[5] = 0;
544 }
545 else if (abs(my->X-my->Cnt[3]) > 5 || abs(my->Y-my->Cnt[4]) > 5)
546 {
547 if (my->X < my->Cnt[3])
548 {
549 if (my->Cnt[3]-my->X > 50)
550 my->X += 20;
551 else if (my->Cnt[3]-my->X > 30)
552 my->X += 10;
553 else if (my->Cnt[3]-my->X > 20)
554 my->X += 5;
555 else
556 my->X ++;
557 }
558 else
559 {
560 if (my->X-my->Cnt[3] > 50)
561 my->X -= 20;
562 else if (my->X-my->Cnt[3] > 30)
563 my->X -= 10;
564 else if (my->X-my->Cnt[3] > 20)
565 my->X -= 5;
566 else
567 my->X --;
568 }
569
570 if (my->Y < my->Cnt[4])
571 {
572 if (my->Cnt[4]-my->Y > 50)
573 my->Y += 20;
574 else if (my->Cnt[4]-my->Y > 30)
575 my->Y += 10;
576 else if (my->Cnt[4]-my->Y > 20)
577 my->Y += 5;
578 else
579 my->Y ++;
580 }
581 else
582 {
583 if (my->Y-my->Cnt[4] > 50)
584 my->Y -= 20;
585 else if (my->Y-my->Cnt[4] > 30)
586 my->Y -= 10;
587 else if (my->Y-my->Cnt[4] > 20)
588 my->Y -= 5;
589 else
590 my->Y --;
591 }
592 }
593 else
594 {
595 if (manage->Loop >1)
596 {
597 if (my->Cnt[5] % 2 == 0)
598 {
599 for (i =1; i <manage->Loop; i++)
600 ShotToAngle(my->X, my->Y, rand()%360, 3);
601 }
602 }
603
604 my->Cnt[6] += 13;
605 if (my->Cnt[6] >= 360)
606 my->Cnt[6] -= 360;
607 ShotToAngle(my->X,my->Y,my->Cnt[6],4 + manage->Loop * 4);
608
609 my->Cnt[5]++;
610 }
611
612 return NoneDel;
613 }
614
NewBoss6(void)615 int NewBoss6(void)
616 {
617 manage->New.Data.hitAtt = MEnemy;
618 manage->New.Data.hitMask = MPlayer | MPShot;
619
620 manage->New.Data.X = FieldW/2;
621 manage->New.Data.Y = -64;
622
623 manage->New.Data.HP = 400;
624 manage->New.Data.Point = 9000;
625 manage->New.Data.EnemyAtt = BossDel;
626
627 manage->New.Data.Width = 300;
628 manage->New.Data.Height = 100;
629
630 manage->New.Data.Cnt[0] = 0;
631 manage->New.Data.Cnt[1] = 200; /* immutable time */
632 manage->New.Data.Cnt[2] = 0; /* image counter */
633
634 manage->New.Data.Cnt[3] = 0; /* stealth */
635 manage->New.Data.Cnt[4] = 0; /* shot counter */
636
637 manage->New.Grp.image = Boss6Image;
638 return NewObj(MEnemy,BossAct6,BossHit1,DrawImage);
639 }
640
BossAct6(ObjData * my)641 DelAtt BossAct6(ObjData *my)
642 {
643 if (my->Cnt[0] < my->Cnt[1])
644 {/* appears slowly */
645 my->Y++;
646 my->Cnt[0]++;
647 return NoneDel;
648 }
649
650 if (manage->BossTime <= 0)
651 {
652 if (my->Cnt[3] == 50)
653 {
654 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
655 return NoneDel;
656 else
657 return BossDel;
658 }
659 }
660
661 if (manage->BossTime >= 1)
662 (manage->BossTime)--;
663
664 if (my->Cnt[3] == 0)
665 {
666 my->hitAtt = MEnemy;
667 my->hitMask = MPlayer | MPShot;
668 my->image = 0;
669 switch (my->Cnt[4]%10)
670 {
671 case 0:
672 if (manage->Loop > 2)
673 {
674 RingToPoint(my->X-128,my->Y+32,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%5+3);
675 RingToPoint(my->X-128,my->Y+32,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%8+3);
676 RingToPoint(my->X-128,my->Y+32,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%3+5);
677 }
678 RingToAngle(my->X-128,my->Y+32,80,8);
679 RingToAngle(my->X-128,my->Y+32,90,8);
680 RingToAngle(my->X-128,my->Y+32,100,8);
681 break;
682 case 2:
683 RingToAngle(my->X,my->Y+32,80,8);
684 RingToAngle(my->X,my->Y+32,90,8);
685 RingToAngle(my->X,my->Y+32,100,8);
686 break;
687 case 4:
688 if (manage->Loop > 2)
689 {
690 RingToPoint(my->X+128,my->Y+32,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%5+3);
691 RingToPoint(my->X+128,my->Y+32,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%8+3);
692 RingToPoint(my->X+128,my->Y+32,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%3+5);
693 }
694 RingToAngle(my->X+128,my->Y+32,80,8);
695 RingToAngle(my->X+128,my->Y+32,90,8);
696 RingToAngle(my->X+128,my->Y+32,100,8);
697 break;
698 case 6:
699 HomingShot(my->X-90,my->Y-20,-15,-10);
700 HomingShot(my->X-60,my->Y-20,0,-10);
701 HomingShot(my->X+60,my->Y-20,0,-10);
702 HomingShot(my->X+90,my->Y-20,15,-10);
703 break;
704 case 8:
705 LaserShot(my->X-120 +rand()%240,my->Y,20);
706 LaserShot(my->X-120,my->Y,20);
707 LaserShot(my->X+120,my->Y,20);
708 if (manage->Loop == 1)
709 LaserShot(my->X, my->Y, 20);
710 else if (manage->Loop == 2)
711 {
712 LaserShot(my->X-30,my->Y,20);
713 LaserShot(my->X+30,my->Y,20);
714 }
715 else
716 {
717 LaserShot(my->X -60, my->Y, 20);
718 LaserShot(my->X, my->Y, 20);
719 LaserShot(my->X +60,my->Y,20);
720 }
721 break;
722 }
723 if (manage->Loop >2)
724 if (my->Cnt[4] %2 == 0)
725 if ((manage->player[0]->Data.X < my->X -120)
726 ||(manage->player[0]->Data.X > my->X +120)
727 ||(manage->player[0]->Data.Y < my->Y))
728 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y, 18);
729 my->Cnt[4]++;
730 }
731 else
732 {
733 my->Cnt[3]--;
734 if (my->Cnt[3] < 20)
735 {
736 if (my->Cnt[3]%2 == 0)
737 my->image = 0;
738 else
739 my->image = 1;
740 }
741 }
742
743 if (my->Cnt[4] == 45)
744 {
745 ShotToAngle(my->X -120, my->Y, 105, 25);
746 ShotToAngle(my->X -120, my->Y, 115, 25);
747 ShotToAngle(my->X -120, my->Y, 125, 25);
748 ShotToAngle(my->X -120, my->Y, 135, 25);
749 ShotToAngle(my->X -120, my->Y, 145, 25);
750 ShotToAngle(my->X +120, my->Y, 75, 25);
751 ShotToAngle(my->X +120, my->Y, 65, 25);
752 ShotToAngle(my->X +120, my->Y, 55, 25);
753 ShotToAngle(my->X +120, my->Y, 45, 25);
754 ShotToAngle(my->X +120, my->Y, 35, 25);
755 if (manage->Loop >1)
756 {
757 ShotToAngle(my->X -120, my->Y, 155, 25);
758 ShotToAngle(my->X -120, my->Y, 165, 25);
759 ShotToAngle(my->X -120, my->Y, 175, 25);
760 ShotToAngle(my->X +120, my->Y, 25, 25);
761 ShotToAngle(my->X +120, my->Y, 15, 25);
762 ShotToAngle(my->X +120, my->Y, 5, 25);
763 }
764 }
765
766 if (my->Cnt[4] >= 50)
767 {
768 my->Cnt[3] = 50;
769 my->Cnt[4] = 0;
770 my->hitAtt = 0;
771 my->hitMask = 0;
772 my->image = 1;
773 my->showDamegeTime = 0;
774
775 ShotToAngle(my->X -120, my->Y, 100, 25);
776 ShotToAngle(my->X -120, my->Y, 110, 25);
777 ShotToAngle(my->X -120, my->Y, 120, 25);
778 ShotToAngle(my->X -120, my->Y, 130, 25);
779 ShotToAngle(my->X -120, my->Y, 140, 25);
780 ShotToAngle(my->X +120, my->Y, 80, 25);
781 ShotToAngle(my->X +120, my->Y, 70, 25);
782 ShotToAngle(my->X +120, my->Y, 60, 25);
783 ShotToAngle(my->X +120, my->Y, 50, 25);
784 ShotToAngle(my->X +120, my->Y, 40, 25);
785 if (manage->Loop >1)
786 {
787 ShotToAngle(my->X -120, my->Y, 150, 25);
788 ShotToAngle(my->X -120, my->Y, 160, 25);
789 ShotToAngle(my->X -120, my->Y, 170, 25);
790 ShotToAngle(my->X +120, my->Y, 30, 25);
791 ShotToAngle(my->X +120, my->Y, 20, 25);
792 ShotToAngle(my->X +120, my->Y, 10, 25);
793 }
794
795 my->X = rand()%FieldW;
796 my->Y = rand()%((FieldH -(FieldH%2))/2);
797 }
798
799 return NoneDel;
800 }
801
NewBoss7(void)802 int NewBoss7(void)
803 {
804 manage->New.Data.hitAtt = MEnemy;
805 manage->New.Data.hitMask = MPlayer | MPShot;
806
807 manage->New.Data.HP = 150;
808 manage->New.Data.Point = 8000;
809 manage->New.Data.EnemyAtt = BossDel;
810
811 manage->New.Data.Width = 32;
812 manage->New.Data.Height = 32;
813
814 manage->New.Data.X = FieldW/2;
815 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
816
817 manage->New.Data.Cnt[0] = 0;
818 manage->New.Data.Cnt[1] = 0; /* appears slowly */
819 manage->New.Data.Cnt[2] = 0; /* image counter */
820
821 do {
822 manage->New.Data.Cnt[3] = rand()%30 - 15; /* x move */
823 }while (abs(manage->New.Data.Cnt[3]) < 5);
824 do {
825 manage->New.Data.Cnt[4] = rand()% 10 + 5; /* y move */
826 }while (abs(manage->New.Data.Cnt[4]) < 5);
827
828 manage->New.Data.Cnt[5] = 0; /* shot counter */
829
830 /* "appeared" counter */
831 manage->New.Data.Cnt[6] = 0;
832
833 manage->New.Grp.image = EBoundImage;
834 return NewObj(MEnemy,BossAct7,BossHit1,DrawImage);
835 }
836
BossAct7(ObjData * my)837 DelAtt BossAct7(ObjData *my)
838 {
839 int i;
840 if (manage->BossTime >= 1)
841 (manage->BossTime)--;
842
843 my->image++;
844 if (my->image >= 8)
845 my->image = 0;
846
847 if (manage->BossTime >= 1)
848 {
849 if (manage->Loop >1)
850 {
851 if (my->Cnt[5] % 20 == 0)
852 {
853 for (i = 0; i<360; i+= (90 - (90 % manage->Loop))/ manage->Loop)
854 ShotToAngle(my->X, my->Y, i, manage->Loop * 2);
855 }
856 }
857
858 if (my->Cnt[5] % 30 == 0)
859 {
860 BoundShot(my->X,my->Y,rand()%30-15,rand()%30-15, 5);
861 }
862 }
863
864
865 (my->Cnt[5])++;
866
867 if (my->Cnt[5] >= 60)
868 my->Cnt[5] = 0;
869
870 if ((my->Cnt[6] != 0) && (manage->BossTime >= 1))
871 {
872 if ((my->X+my->Cnt[3]>FieldW) || (my->X+my->Cnt[3]<0))
873 my->Cnt[3] = my->Cnt[3]*(-1);
874 if ((my->Y+my->Cnt[4]>FieldH) || (my->Y+my->Cnt[4]<0))
875 my->Cnt[4] = my->Cnt[4]*(-1);
876 }
877
878 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
879 {
880 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
881 return NoneDel;
882 else
883 return BossDel;
884 }
885 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
886 {
887 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
888 return NoneDel;
889 else
890 return BossDel;
891 }
892
893 my->X += my->Cnt[3];
894 my->Y += my->Cnt[4];
895
896 if ((my->Cnt[6] == 0) && (my->X >= 0) && (my->X <= FieldW)
897 && (my->Y >= 0) && (my->Y < FieldH))
898 my->Cnt[6] = 1;
899
900 return NoneDel;
901 }
902
NewBoss8(void)903 int NewBoss8(void)
904 {
905 manage->New.Data.hitAtt = MEnemy;
906 manage->New.Data.hitMask = MPlayer | MPShot;
907
908 manage->New.Data.X = FieldW/2;
909 manage->New.Data.Y = -80;
910
911 manage->New.Data.HP = 600;
912 manage->New.Data.Point = 10000;
913 manage->New.Data.EnemyAtt = BossDel;
914
915 manage->New.Data.Width = 200;
916 manage->New.Data.Height = 180;
917
918 manage->New.Data.Cnt[0] = 0;
919 manage->New.Data.Cnt[1] = 200; /* appears slowly */
920 manage->New.Data.Cnt[2] = 0; /* image counter */
921 manage->New.Data.Cnt[3] = 10; /* x move */
922 manage->New.Data.Cnt[4] = 0; /* y move */
923 manage->New.Data.Cnt[5] = 0; /* shot counter */
924 manage->New.Data.Cnt[6] = rand()%4; /* mode */
925 manage->New.Data.Cnt[7] = 0; /* mode counter */
926 manage->New.Data.Cnt[8] = 0; /* after-death counter */
927
928 manage->New.Grp.image = Boss7Image;
929 return NewObj(MEnemy,BossAct8,BossHit8,DrawImage);
930 }
931
BossAct8(ObjData * my)932 DelAtt BossAct8(ObjData *my)
933 {
934 if (my->Cnt[0] < my->Cnt[1])
935 {/* appears slowly */
936 my->Y++;
937 my->Cnt[0]++;
938 return NoneDel;
939 }
940
941 if (my->kill == True)
942 {
943 /* the boss is dead */
944 return BossAct8_dead(my);
945 }
946
947 /* the boss is alive */
948 if (manage->BossTime <= 0)
949 {
950 if (my->Y < 0 - my->Height/2 - 50)
951 {
952 if ((player->Ships > 0) ||(manage->player[0]->Data.Cnt[3] == 0))
953 return BossDel;
954 else
955 return NoneDel;
956 }
957 else
958 {
959 (my->Y) -= 4;
960 return NoneDel;
961 }
962 }
963
964 (manage->BossTime)--;
965
966 if (my->Cnt[5] > 8)
967 my->Cnt[5] = 0;
968 else
969 my->Cnt[5]++;
970
971 if ((my->Cnt[5]%2==0) && ((my->Cnt[6] ==0) || (my->Cnt[6] == 2)
972 || (my->Cnt[6] == 3)))
973 {
974 RingToAngle(my->X, my->Y-60, rand()%50+70, rand()%15+5);
975 RingToAngle(my->X, my->Y-60, rand()%20+80, rand()%10+10);
976 /*
977 if (manage->Loop > 2)
978 RingToAngle(my->X, my->Y-60, rand()%20+80, rand()%5+15);
979 */
980 }
981
982 if (my->Cnt[6] != 4)
983 {
984 if (my->X>manage->player[0]->Data.X && my->X>my->HarfW)
985 my->X--;
986 else if (my->X<manage->player[0]->Data.X && my->X<(FieldW-my->HarfW))
987 my->X++;
988 }
989
990 if (my->Cnt[6] == 0)
991 {
992 return BossAct8_rand_shot(my);
993 }
994 else if (my->Cnt[6] == 1)
995 {
996 return BossAct8_ring_shot(my);
997 }
998 else if (my->Cnt[6] == 2)
999 {
1000 return BossAct8_bound_shot(my);
1001 }
1002 else if (my->Cnt[6] == 3)
1003 {
1004 return BossAct8_homing_shot(my);
1005 }
1006 else if (my->Cnt[6] == 4)
1007 {
1008 return BossAct8_charge_shot(my);
1009 }
1010 else if (my->Cnt[6] == 5)
1011 {
1012 return BossAct8_n_way_shot(my);
1013 }
1014
1015 return NoneDel;
1016 }
1017
BossHit8(ObjData * my,ObjData * your)1018 DelAtt BossHit8(ObjData *my, ObjData *your)
1019 {
1020 int temp = your->Attack;
1021 if (my->Cnt[0] < my->Cnt[1])
1022 return NoneDel;
1023 /*
1024 if (my->Cnt[6] == 4)
1025 return NoneDel;
1026 */
1027 /* immutable in above cases */
1028 if (my->HP < your->Attack)
1029 temp = my->HP;
1030
1031 my->HP -= temp;
1032 player->Rec[0].score += temp;
1033
1034 if (my->HP <= 0)
1035 {
1036 player->Rec[0].score -= 1;
1037 my->showDamegeTime = 0;
1038
1039 my->kill = True;
1040 }
1041 else
1042 {
1043 my->showDamegeTime = 15;
1044 }
1045
1046 return NoneDel;
1047 }
1048
BossAct8_dead(ObjData * my)1049 static DelAtt BossAct8_dead(ObjData *my)
1050 {
1051 int i;
1052 int j;
1053 /* the boss is dead */
1054 NewLargeBomb(my->X+rand()%230-115,my->Y+rand()%180-90);
1055 NewLargeBomb(my->X+rand()%230-115,my->Y+rand()%180-90);
1056
1057 my->Cnt[8]++;
1058 if ((player->Ships <= 0) && (manage->player[0]->Data.Cnt[3] != 0))
1059 if (my->Cnt[8] >= 300)
1060 my->Cnt[8] = 0;
1061
1062 if (my->Cnt[8] %3 == 0)
1063 {
1064 if (my->X > manage->player[0]->Data.X)
1065 (my->X)--;
1066 else if (my->X < manage->player[0]->Data.X)
1067 (my->X)++;
1068 if (my->Y > manage->player[0]->Data.Y)
1069 (my->Y)--;
1070 else if (my->Y < manage->player[0]->Data.Y)
1071 (my->Y)++;
1072 }
1073
1074 if (my->Cnt[8] %30 == 0)
1075 {
1076 for (i=0; i<24; i++)
1077 ShotToAngle(my->X,my->Y,i*15, 7);
1078 }
1079 else if (my->Cnt[8] %30 == 15)
1080 {
1081 for (i=0; i<24; i++)
1082 ShotToAngle(my->X,my->Y,i*15 + 7,7);
1083 }
1084 if (my->Cnt[8] %13 == 0)
1085 {
1086 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y, manage->Loop *5);
1087 if (manage->Loop >2)
1088 {
1089 BoundShot(my->X, my->Y-60,rand()%20-10,rand()%4+10,4);
1090 }
1091 }
1092 if (my->Cnt[8] %5 == 0)
1093 {
1094 if (manage->Loop >1)
1095 {
1096 for (i=1; i< manage->Loop * 3; i++)
1097 ShotToAngle(my->X,my->Y,rand()%360, manage->Loop *3);
1098 }
1099 }
1100
1101 if (my->Cnt[8] >= 300)
1102 {
1103 for (i=0; i<=10; i++)
1104 for (j=0; j<=10; j++)
1105 NewLargeBomb(50*i,65*j);
1106 return my->EnemyAtt;
1107 }
1108 else
1109 return NoneDel;
1110 }
1111
BossAct8_rand_shot(ObjData * my)1112 static DelAtt BossAct8_rand_shot(ObjData *my)
1113 {
1114 int i;
1115 if (my->Cnt[7]% 10 == 0)
1116 {
1117 for (i = 1; i <= manage->Loop; i++)
1118 {
1119 ShotToAngle(my->X-60, my->Y-60, rand()%50 + 70, rand()%5+5);
1120 ShotToAngle(my->X+60, my->Y-60, rand()%50 + 70, rand()%5+5);
1121 }
1122 ShotToPoint(my->X,my->Y-60,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%5+3);
1123 }
1124
1125 BossAct8_next(my, 100);
1126 return NoneDel;
1127 }
1128
BossAct8_ring_shot(ObjData * my)1129 static DelAtt BossAct8_ring_shot(ObjData *my)
1130 {
1131 if (my->Cnt[7]%2 == 0)
1132 {
1133 RingToPoint(my->X-60, my->Y+10, manage->player[0]->Data.X,manage->player[0]->Data.Y, rand()%10 + 20);
1134 RingToPoint(my->X+60, my->Y+10, manage->player[0]->Data.X,manage->player[0]->Data.Y, rand()%10 + 20);
1135 if (manage->Loop >1)
1136 {
1137 RingToAngle(my->X, my->Y - 60, 90, rand()%10 + 20);
1138 RingToAngle(my->X, my->Y - 60, 90, rand()%10 + 20);
1139 }
1140 if (manage->Loop >2)
1141 {
1142 RingToAngle(my->X-60, my->Y - 60, 90, rand()%10 + 20);
1143 RingToAngle(my->X+60, my->Y - 60, 90, rand()%10 + 20);
1144 }
1145 }
1146
1147 BossAct8_next(my, 70);
1148 return NoneDel;
1149 }
1150
BossAct8_bound_shot(ObjData * my)1151 static DelAtt BossAct8_bound_shot(ObjData *my)
1152 {
1153 if (manage->Loop <=2)
1154 {
1155 if (my->Cnt[7] % 16 == 0)
1156 BoundShot(my->X+60,my->Y-60,rand()%20-10,rand()%4+10,2);
1157 else if (my->Cnt[7] % 16 == 8)
1158 BoundShot(my->X-60,my->Y-60,rand()%20-10,rand()%4+10,2);
1159 }
1160 else
1161 {
1162 if (my->Cnt[7] % 16 == 0)
1163 BoundShot(my->X+60,my->Y-60, (rand()%20-10)*2, (rand()%4+10)*2, 2);
1164 else if (my->Cnt[7] % 16 == 8)
1165 BoundShot(my->X-60,my->Y-60, (rand()%20-10)*2 ,(rand()%4+10)*2, 2);
1166 }
1167
1168 BossAct8_next(my, 100);
1169 return NoneDel;
1170 }
1171
BossAct8_homing_shot(ObjData * my)1172 static DelAtt BossAct8_homing_shot(ObjData *my)
1173 {
1174 if (my->Cnt[7] %8 == 0)
1175 {
1176 HomingShot(my->X-60,my->Y-10,-10, 5);
1177 HomingShot(my->X+60,my->Y-10, 10, 5);
1178 if (manage->Loop > 2)
1179 {
1180 HomingShot(my->X-60,my->Y-10,-3, 10);
1181 HomingShot(my->X+60,my->Y-10, 3, 10);
1182 }
1183 }
1184
1185 BossAct8_next(my, 100);
1186 return NoneDel;
1187 }
1188
BossAct8_charge_shot(ObjData * my)1189 static DelAtt BossAct8_charge_shot(ObjData *my)
1190 {
1191 int i;
1192 if (my->Cnt[7] == 48 - manage->Loop *8)
1193 {
1194 for (i=0; i<24; i++)
1195 ShotToAngle(my->X,my->Y,i*15,15);
1196 }
1197 if (my->Cnt[7] == 53 - manage->Loop *8)
1198 {
1199 for (i=0; i<24; i++)
1200 ShotToAngle(my->X,my->Y,i*15+7,20);
1201 }
1202 if (my->Cnt[7] > 53 - manage->Loop *8)
1203 {
1204 LaserShot(my->X-120,my->Y-60,35);
1205 LaserShot(my->X-80 ,my->Y-60,35);
1206 LaserShot(my->X-40 ,my->Y-60,35);
1207 LaserShot(my->X ,my->Y-60,35);
1208 LaserShot(my->X+40 ,my->Y-60,35);
1209 LaserShot(my->X+80 ,my->Y-60,35);
1210 LaserShot(my->X+120,my->Y-60,35);
1211 }
1212
1213 BossAct8_next(my, 58 - manage->Loop *8);
1214 return NoneDel;
1215 }
1216
BossAct8_n_way_shot(ObjData * my)1217 static DelAtt BossAct8_n_way_shot(ObjData *my)
1218 {
1219 int xtemp;
1220 int ytemp;
1221 int speedtemp;
1222 if (my->Cnt[7] % 13 == 0)
1223 {
1224 xtemp = rand()%FieldW;
1225 ytemp = rand()%((FieldH -(FieldH%2))/2);
1226 speedtemp = rand()%7 + 5;
1227
1228 if (manage->Loop == 1)
1229 {
1230 ShotToAngle(xtemp, ytemp, 50, speedtemp);
1231 ShotToAngle(xtemp, ytemp, 70, speedtemp);
1232 ShotToAngle(xtemp, ytemp, 90, speedtemp);
1233 ShotToAngle(xtemp, ytemp, 110, speedtemp);
1234 ShotToAngle(xtemp, ytemp, 130, speedtemp);
1235 }
1236 else if (manage->Loop == 2)
1237 {
1238 ShotToAngle(xtemp, ytemp, 51, speedtemp);
1239 ShotToAngle(xtemp, ytemp, 64, speedtemp);
1240 ShotToAngle(xtemp, ytemp, 77, speedtemp);
1241 ShotToAngle(xtemp, ytemp, 90, speedtemp);
1242 ShotToAngle(xtemp, ytemp, 103, speedtemp);
1243 ShotToAngle(xtemp, ytemp, 116, speedtemp);
1244 ShotToAngle(xtemp, ytemp, 129, speedtemp);
1245 }
1246 else
1247 {
1248 ShotToAngle(xtemp, ytemp, 50, speedtemp);
1249 ShotToAngle(xtemp, ytemp, 60, speedtemp);
1250 ShotToAngle(xtemp, ytemp, 70, speedtemp);
1251 ShotToAngle(xtemp, ytemp, 80, speedtemp);
1252 ShotToAngle(xtemp, ytemp, 90, speedtemp);
1253 ShotToAngle(xtemp, ytemp, 100, speedtemp);
1254 ShotToAngle(xtemp, ytemp, 110, speedtemp);
1255 ShotToAngle(xtemp, ytemp, 120, speedtemp);
1256 ShotToAngle(xtemp, ytemp, 130, speedtemp);
1257 }
1258 }
1259
1260 BossAct8_next(my, 150);
1261 return NoneDel;
1262 }
1263
BossAct8_next(ObjData * my,int span)1264 static void BossAct8_next(ObjData *my, int span)
1265 {
1266 int modetemp = 0;
1267 if (my->Cnt[7] > span)
1268 {
1269 do
1270 {
1271 modetemp = rand()%6;
1272 }while (modetemp == my->Cnt[6]);
1273 my->Cnt[6] = modetemp;
1274 my->Cnt[7] = 0;
1275 }
1276 else
1277 my->Cnt[7]++;
1278 }
1279