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: enemy.c,v 1.16 2002/04/29 03:40:19 oohara Exp $ */
8
9 /* rand */
10 #include <stdlib.h>
11 /* abs */
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 "enemy.h"
26 #include "extern.h"
27 #include "sin.h"
28
29 /* definition of objects
30 * - initialization function
31 * - action function
32 * - hit function
33 *
34 * initialization add action function and display/hit function to the table
35 */
36
37 /* run straight ahead */
NewEnemy1(int x,int y)38 int NewEnemy1(int x, int y)
39 {
40 /* attribute of this object */
41 manage->New.Data.hitAtt = MEnemy;
42 /* what objects should hit this object */
43 manage->New.Data.hitMask = MPlayer | MPShot;
44
45 manage->New.Data.HP = 1;
46 manage->New.Data.Point = 100;
47 manage->New.Data.EnemyAtt = ZakoDel;
48
49 /* size for collision detection */
50 manage->New.Data.Width = 32;
51 manage->New.Data.Height = 32;
52
53 manage->New.Data.X = x;
54 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
55
56 manage->New.Data.Angle = 0;
57 manage->New.Data.Speed = rand()%15 + 1;
58
59 manage->New.Data.Cnt[0] = 0;
60
61 /* pixmap for this object */
62 manage->New.Grp.image = Enemy1Image;
63
64 /* add action function and hit function to the table */
65 return NewObj(MEnemy,EnemyAct1,EnemyHit1,DrawImage);
66 }
67
EnemyAct1(ObjData * my)68 DelAtt EnemyAct1(ObjData *my)
69 {
70 int i;
71 if (manage->Loop > 1)
72 {
73 /* shoot in loop 2 or later */
74 if (my->shotTime >= ShotTiming)
75 {
76 for (i =1; i< manage->Loop; i++)
77 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,5);
78 my->shotTime = my->startTime;
79 }
80 else
81 my->shotTime++;
82 }
83
84 my->image = 4;
85 my->Y += my->Speed;
86
87 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
88 return NullDel;
89 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
90 return NullDel;
91
92 return NoneDel;
93 }
94
95 /* may give you an item */
EnemyHit1(ObjData * my,ObjData * your)96 DelAtt EnemyHit1(ObjData *my, ObjData *your)
97 {
98 int temp = your->Attack;
99 if (my->HP < your->Attack)
100 temp = my->HP;
101
102 my->HP -= temp;
103 player->Rec[0].score += temp;
104
105 if (my->HP <= 0)
106 {
107 player->Rec[0].score -= 1;
108
109 /* always gives you a shot in loop 3 or later */
110 if (manage->Loop > 2)
111 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,5);
112
113 if (rand()%100 < 20)
114 NewEnemy10(my->X,my->Y);
115 NewBomb(my->X,my->Y);
116
117 my->showDamegeTime = 0;
118 return my->EnemyAtt;
119 }
120 else
121 {
122 my->showDamegeTime = 15;
123 return NoneDel;
124 }
125
126 }
127
128 /* codename "sine curve" (in fact it is a parabola) */
NewEnemy2(int x,int y)129 int NewEnemy2(int x, int y)
130 {
131
132 manage->New.Data.hitAtt = MEnemy;
133 manage->New.Data.hitMask = MPlayer | MPShot;
134
135 manage->New.Data.HP = 1;
136 manage->New.Data.Point = 100;
137 manage->New.Data.EnemyAtt = ZakoDel;
138
139 manage->New.Data.Width = 32;
140 manage->New.Data.Height = 32;
141
142 manage->New.Data.X = x;
143 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
144
145 manage->New.Data.inertX = 0;
146 manage->New.Data.inertY = 1;
147
148 manage->New.Data.Angle = 0;
149 manage->New.Data.Speed = 0;
150 manage->New.Data.Cnt[0] = 0;
151 /* range of x */
152 manage->New.Data.Cnt[1] = rand()%3 + 5;
153 if (x < FieldW/2)
154 manage->New.Data.Cnt[2] = 0;
155 else
156 manage->New.Data.Cnt[2] = 1;
157
158 manage->New.Data.Cnt[3] = 0;
159
160 manage->New.Grp.image = Enemy3Image;
161
162 return NewObj(MEnemy,EnemyAct2,DamageHit,DrawImage);
163 }
164
EnemyAct2(ObjData * my)165 DelAtt EnemyAct2(ObjData *my)
166 {
167 if (my->shotTime >= ShotTiming)
168 {
169 if (manage->Loop > 1)
170 LaserShot(my->X,my->Y,10);
171 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,4);
172 my->shotTime = my->startTime;
173 }
174 else
175 my->shotTime++;
176
177 if (my->Cnt[2] == 0)
178 {
179 my->Cnt[3]++;
180
181 if(my->Cnt[3] >= 2*my->Cnt[1])
182 my->Cnt[2] = 1;
183 }
184 else if (my->Cnt[2] == 1)
185 {
186 my->Cnt[3]--;
187
188 if(my->Cnt[3] <= -2*my->Cnt[1])
189 my->Cnt[2] = 0;
190 }
191
192 my->Y += my->Cnt[1];
193 my->X += my->Cnt[3];
194
195 /* what number of pixmap we use */
196 if (my->Cnt[3] > my->Cnt[1])
197 my->image = 2;
198 else if (my->Cnt[3] > 0)
199 my->image = 3;
200 else if (my->Cnt[3] < -my->Cnt[1])
201 my->image = 6;
202 else if(my->Cnt[3] < 0)
203 my->image = 5;
204 else
205 my->image = 0;
206
207 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
208 return NullDel;
209
210 return NoneDel;
211 }
212
213 /* turns left/right */
NewEnemy3(int x,int y)214 int NewEnemy3(int x, int y)
215 {
216
217 manage->New.Data.hitAtt = MEnemy;
218 manage->New.Data.hitMask = MPlayer | MPShot;
219
220 manage->New.Data.HP = 2;
221 manage->New.Data.Point = 150;
222 manage->New.Data.EnemyAtt = ZakoDel;
223
224 manage->New.Data.Width = 32;
225 manage->New.Data.Height = 32;
226
227 manage->New.Data.X = x;
228 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
229
230 manage->New.Data.Cnt[0] = 0;
231 manage->New.Data.Cnt[1] = 0;
232 manage->New.Data.Cnt[2] = 5;
233
234 manage->New.Grp.image = Enemy1Image;
235 return NewObj(MEnemy,EnemyAct3,EnemyHit1,DrawImage);
236 }
237
EnemyAct3(ObjData * my)238 DelAtt EnemyAct3(ObjData *my)
239 {
240 if (my->shotTime >= ShotTiming)
241 {
242 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,4);
243 my->shotTime = my->startTime;
244 }
245 else
246 my->shotTime++;
247
248 if (my->Cnt[0] == 0)
249 {
250 if (my->Y<manage->player[0]->Data.Y+10 && my->Y>manage->player[0]->Data.Y-10)
251 {
252 if (my->X < manage->player[0]->Data.X)
253 {
254 my->Cnt[0] = 1;
255 if (manage->Loop >2)
256 BoundShot(my->X, my->Y, rand()%30-15, rand()%30-15, 3);
257 }
258
259 if (my->X > manage->player[0]->Data.X)
260 {
261 my->Cnt[0] = 2;
262 if (manage->Loop >2)
263 BoundShot(my->X, my->Y, rand()%30-15, rand()%30-15, 3);
264 }
265 }
266 }
267
268 if (my->Cnt[0] == 0)
269 {
270 my->Y += 2 + manage->Loop * 3;
271 my->image = 4;
272 }
273 else if (my->Cnt[0] == 1)
274 {
275 my->X += 15;
276 my->image = 2;
277 }
278 else if (my->Cnt[0] == 2)
279 {
280 my->X -= 15;
281 my->image = 6;
282 }
283
284 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
285 return NullDel;
286 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
287 return NullDel;
288
289 return NoneDel;
290 }
291
292 /* chases you */
NewEnemy4(int x,int y)293 int NewEnemy4(int x, int y)
294 {
295
296 manage->New.Data.hitAtt = MEnemy;
297 manage->New.Data.hitMask = MPlayer | MPShot;
298
299 manage->New.Data.HP = 2;
300 manage->New.Data.Point = 150;
301 manage->New.Data.EnemyAtt = ZakoDel;
302
303 manage->New.Data.Width = 32;
304 manage->New.Data.Height = 32;
305
306 manage->New.Data.X = x;
307 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
308
309 manage->New.Data.inertX = 0;
310 manage->New.Data.inertY = 0;
311
312 manage->New.Grp.image = Enemy2Image;
313 return NewObj(MEnemy,EnemyAct4,DamageHit,DrawImage);
314 }
315
EnemyAct4(ObjData * my)316 DelAtt EnemyAct4(ObjData *my)
317 {
318 if (my->shotTime >= ShotTiming)
319 {
320 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,4);
321 if (manage->Loop >1)
322 {
323 ShotToAngle(my->X, my->Y, 90, 4);
324 ShotToAngle(my->X, my->Y, 90, 8);
325 ShotToAngle(my->X, my->Y, 90, 12);
326 ShotToAngle(my->X, my->Y, 90, 16);
327 }
328
329 my->shotTime = my->startTime;
330 }
331 else
332 my->shotTime++;
333
334 if (my->X < manage->player[0]->Data.X)
335 {
336 if (my->inertX <= 8)
337 my->inertX++;
338 }
339 else if (my->X > manage->player[0]->Data.X)
340 {
341 if (my->inertX >= -8)
342 my->inertX--;
343 }
344
345 if (my->Y < manage->player[0]->Data.Y)
346 {
347 if (my->inertY <= 8)
348 my->inertY++;
349 }
350 else if (my->Y > manage->player[0]->Data.Y)
351 {
352 if (my->inertY >= -8)
353 my->inertY--;
354 }
355
356 my->X += my->inertX;
357 my->Y += my->inertY;
358
359 my->image = GetDirection(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y);
360
361 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
362 return NullDel;
363 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
364 return NullDel;
365
366 return NoneDel;
367 }
368
369 /* bounce on the left/right side of the window */
NewEnemy5(int x,int y)370 int NewEnemy5(int x, int y)
371 {
372
373 manage->New.Data.hitAtt = MEnemy;
374 manage->New.Data.hitMask = MPlayer | MPShot;
375
376 if (x > FieldW/2)
377 {
378 manage->New.Data.X = FieldW;
379 manage->New.Data.Cnt[0] = - (rand()%10 + 15);
380 }
381 else
382 {
383 manage->New.Data.X = 0;
384 manage->New.Data.Cnt[0] = rand()%10 + 15;
385 }
386
387 manage->New.Data.HP = 9;
388 manage->New.Data.Point = 200;
389 manage->New.Data.EnemyAtt = ZakoDel;
390
391 manage->New.Data.Width = 32;
392 manage->New.Data.Height = 32;
393
394 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
395
396 manage->New.Data.inertX = 0;
397 manage->New.Data.inertY = 0;
398
399 manage->New.Grp.image = Enemy5Image;
400 return NewObj(MEnemy,EnemyAct5,EnemyHit1,DrawImage);
401 }
402
EnemyAct5(ObjData * my)403 DelAtt EnemyAct5(ObjData *my)
404 {
405 if (my->Cnt[0] < 0)
406 {
407 my->inertX++;
408 if (abs(my->inertX+my->Cnt[0]) < 5)
409 my->image = 3;
410 else
411 my->image = 2;
412 }
413 else
414 {
415 my->inertX--;
416 if (abs(my->inertX+my->Cnt[0]) < 5)
417 my->image = 1;
418 else
419 my->image = 0;
420 }
421
422 if (my->Cnt[0]+my->inertX == 0)
423 {
424 RingToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%4+2);
425 RingToAngle(my->X, my->Y, 45, 5);
426 RingToAngle(my->X, my->Y, 90, 5);
427 RingToAngle(my->X, my->Y, 135, 5);
428 RingToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%2+4);
429 if (manage->Loop > 1)
430 {
431 RingToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%3+3);
432 RingToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%4+4);
433 }
434 }
435
436 my->X += (my->Cnt[0] + my->inertX);
437 my->Y += 5;
438
439 if ((my->X < 0) || (my->X > FieldW))
440 my->inertX = 0;
441
442 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
443 return NullDel;
444
445 return NoneDel;
446 }
447
448 /* bounce on any side of the window */
NewEnemy6(int x,int y)449 int NewEnemy6(int x, int y)
450 {
451
452 manage->New.Data.hitAtt = MEnemy;
453 manage->New.Data.hitMask = MPlayer | MPShot;
454
455 manage->New.Data.HP = 4;
456 manage->New.Data.Point = 200;
457 manage->New.Data.EnemyAtt = ZakoDel;
458
459 manage->New.Data.Width = 32;
460 manage->New.Data.Height = 32;
461
462 manage->New.Data.X = x;
463 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
464
465 if (x > FieldW/2)
466 manage->New.Data.inertX = rand()%5 + 10;
467 else
468 manage->New.Data.inertX = rand()%5 - 15;
469
470 manage->New.Data.inertY = rand()%10 + 5;
471
472 manage->New.Data.Cnt[0] = 0;
473 manage->New.Data.Cnt[1] = 8;
474 /* "appeared" counter */
475 manage->New.Data.Cnt[2] = 0;
476
477 manage->New.Grp.image = Enemy4Image;
478 return NewObj(MEnemy,EnemyAct6,DamageHit,DrawImage);
479 }
480
EnemyAct6(ObjData * my)481 DelAtt EnemyAct6(ObjData *my)
482 {
483 if (my->shotTime >= ShotTiming)
484 {
485 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%4+ manage->Loop * 7 -5);
486 my->shotTime = my->startTime;
487 }
488 else
489 my->shotTime++;
490
491 if ((my->Cnt[2] != 0) && (my->Cnt[0] <= my->Cnt[1]))
492 {
493 if ((my->X+my->inertX>FieldW) || (my->X+my->inertX<0))
494 {
495 my->inertX = my->inertX*(-1);
496 my->Cnt[0]++;
497 }
498 if ((my->Y+my->inertY>FieldH) || (my->Y+my->inertY<0))
499 {
500 my->inertY = my->inertY*(-1);
501 my->Cnt[0]++;
502 }
503 }
504
505 my->image++;
506 if (my->image > 7)
507 my->image = 0;
508
509 my->X += my->inertX;
510 my->Y += my->inertY;
511
512 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
513 return NullDel;
514 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
515 return NullDel;
516
517 if ((my->Cnt[2] == 0) && (my->X >= 0) && (my->X <= FieldW)
518 && (my->Y >= 0) && (my->Y < FieldH))
519 my->Cnt[2] = 1;
520
521 return NoneDel;
522 }
523
524 /* appears from the lower side of the window */
NewEnemy7(int x,int y)525 int NewEnemy7(int x, int y)
526 {
527
528 manage->New.Data.hitAtt = MEnemy;
529 manage->New.Data.hitMask = MPlayer | MPShot;
530
531 if (x > FieldW/2)
532 manage->New.Data.X = FieldW -50;
533 else
534 manage->New.Data.X = 50;
535
536 manage->New.Data.HP = 3;
537 manage->New.Data.Point = 250;
538 manage->New.Data.EnemyAtt = ZakoDel;
539
540 manage->New.Data.Width = 32;
541 manage->New.Data.Height = 32;
542
543 manage->New.Data.Y = FieldH - 1 + manage->New.Data.Height/2;
544
545 manage->New.Data.Cnt[1] = 0;
546
547 manage->New.Grp.image = Enemy3Image;
548
549 return NewObj(MEnemy,EnemyAct7,EnemyHit1,DrawImage);
550 }
551
EnemyAct7(ObjData * my)552 DelAtt EnemyAct7(ObjData *my)
553 {
554 if (manage->Loop > 1)
555 {
556 if (my->shotTime >= ShotTiming)
557 {
558 HomingShot(my->X,my->Y,0,0);
559 my->shotTime = my->startTime;
560 }
561 else
562 my->shotTime++;
563 }
564
565 if (my->Cnt[1] > 20)
566 {
567 my->Y -= 9;
568 my->image = 0;
569 }
570 else if (my->Y > FieldH-100)
571 {
572 my->Y -= 6;
573 my->image = 0;
574 }
575 else
576 {
577 my->Cnt[1]++;
578 my->image++;
579 if (my->image > 7)
580 my->image = 0;
581 }
582
583 if (my->Cnt[1] == 20)
584 {
585 ShotToAngle(my->X, my->Y, 144, 10);
586 ShotToAngle(my->X, my->Y, 180, 10);
587 ShotToAngle(my->X, my->Y, 216, 10);
588 ShotToAngle(my->X, my->Y, 252, 10);
589 ShotToAngle(my->X, my->Y, 288, 10);
590 ShotToAngle(my->X, my->Y, 324, 10);
591 ShotToAngle(my->X, my->Y, 360, 10);
592 ShotToAngle(my->X, my->Y, 36, 10);
593 }
594
595 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
596 return NullDel;
597 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
598 return NullDel;
599
600 return NoneDel;
601 }
602
603 /* run straight ahead and shoot homing missiles */
NewEnemy8(int x,int y)604 int NewEnemy8(int x, int y)
605 {
606
607 manage->New.Data.hitAtt = MEnemy;
608 manage->New.Data.hitMask = MPlayer | MPShot;
609
610 manage->New.Data.HP = 15;
611 manage->New.Data.Point = 500;
612 manage->New.Data.EnemyAtt = ZakoDel;
613
614 manage->New.Data.Width = 40;
615 manage->New.Data.Height = 50;
616
617 manage->New.Data.X = x;
618 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
619
620 manage->New.Data.Angle = 0;
621 manage->New.Data.Speed = rand()%5 + 1;
622
623 manage->New.Grp.image = Enemy7Image;
624
625 return NewObj(MEnemy,EnemyAct8,LargeDamageHit,DrawImage);
626 }
627
EnemyAct8(ObjData * my)628 DelAtt EnemyAct8(ObjData *my)
629 {
630 if (my->shotTime >= ShotTiming)
631 {
632 HomingShot(my->X+10,my->Y-20,-10,-5);
633 HomingShot(my->X-10,my->Y-20,10,-5);
634
635 if (manage->Loop > 1)
636 {
637 LaserShot(my->X-15,my->Y-20,10);
638 LaserShot(my->X+15,my->Y-20,10);
639 }
640 my->shotTime = my->startTime;
641 }
642 else
643 my->shotTime++;
644
645 my->Y += my->Speed;
646
647 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
648 return NullDel;
649 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
650 return NullDel;
651
652 return NoneDel;
653 }
654
655 /* "reversed" parabola */
NewEnemy9(int x,int y)656 int NewEnemy9(int x, int y)
657 {
658 manage->New.Data.hitAtt = MEnemy;
659 manage->New.Data.hitMask = MPlayer | MPShot;
660
661 manage->New.Data.HP = 6;
662 manage->New.Data.Point = 300;
663 manage->New.Data.EnemyAtt = ZakoDel;
664
665 manage->New.Data.Width = 32;
666 manage->New.Data.Height = 32;
667
668 manage->New.Data.X = x;
669 manage->New.Data.Y = 1 - manage->New.Data.Height/2;
670
671 if (x > FieldW/2)
672 manage->New.Data.inertX = -(rand()%10+1);
673 else
674 manage->New.Data.inertX = rand()%10+1;
675 manage->New.Data.inertY = rand()%10 + 15;
676
677 manage->New.Data.Cnt[0] = 0;
678
679 manage->New.Grp.image = Enemy6Image;
680 return NewObj(MEnemy,EnemyAct9,DamageHit,DrawImage);
681 }
682
EnemyAct9(ObjData * my)683 DelAtt EnemyAct9(ObjData *my)
684 {
685 if (manage->Loop > 2)
686 {
687 if (my->shotTime >= ShotTiming)
688 {
689 ShotToAngle(my->X, my->Y, 50, 25);
690 ShotToAngle(my->X, my->Y, 70, 25);
691 ShotToAngle(my->X, my->Y, 90, 25);
692 ShotToAngle(my->X, my->Y, 110, 25);
693 ShotToAngle(my->X, my->Y, 130, 25);
694 my->shotTime = my->startTime;
695 }
696 else
697 my->shotTime++;
698 }
699
700 if (my->inertY<0 && my->inertY%2)
701 ShotToPoint(my->X,my->Y,manage->player[0]->Data.X,manage->player[0]->Data.Y,rand()%3+3);
702
703 my->inertY--;
704
705 my->X += my->inertX;
706 my->Y += my->inertY;
707
708 if (my->inertY > 10)
709 my->image = 0;
710 else if (my->inertY > 5)
711 my->image = 1;
712 else if (my->inertY > 0)
713 my->image = 2;
714 else if (my->inertY > -5)
715 my->image = 3;
716 else if (my->inertY > -10)
717 my->image = 4;
718 else
719 my->image = 5;
720
721 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
722 return NullDel;
723 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
724 return NullDel;
725
726 return NoneDel;
727 }
728
729 /* power-up item */
NewEnemy10(int x,int y)730 int NewEnemy10(int x, int y)
731 {
732 manage->New.Data.hitAtt = MItem;
733 manage->New.Data.hitMask = MPlayer;
734
735 manage->New.Data.X = x;
736 manage->New.Data.Y = y;
737
738 manage->New.Data.HP = 0;
739 manage->New.Data.Point = 0;
740 manage->New.Data.EnemyAtt = NoneDel;
741
742 manage->New.Data.Width = 32;
743 manage->New.Data.Height = 32;
744
745 manage->New.Data.inertY = -10 - rand() % 10;
746
747 /* item counter */
748 manage->New.Data.Cnt[0] = 0;
749 /* time counter */
750 manage->New.Data.Cnt[1] = 0;
751 /* max speed */
752 manage->New.Data.Cnt[2] = rand()%6 + 1;
753 if (rand()%100 < 30)
754 {
755 manage->New.Data.Cnt[3] = 1;
756 manage->New.Data.Cnt[0] = 1;
757 }
758 else
759 manage->New.Data.Cnt[3] = 0;
760
761 manage->New.Grp.image = ItemImage;
762 return NewObj(MEnemy,EnemyAct10,NullDelHit,DrawImage);
763 }
764
EnemyAct10(ObjData * my)765 DelAtt EnemyAct10(ObjData *my)
766 {
767 my->Cnt[1]++;
768
769 if (my->inertY < my->Cnt[2])
770 my->inertY++;
771 my->Y += my->inertY;
772
773 if (my->Cnt[3] == 1)
774 {
775 if (my->Cnt[1]%25 == 0)
776 {
777 if (my->Cnt[0] < 3)
778 my->Cnt[0]++;
779 else
780 my->Cnt[0] = 1;
781 }
782 }
783
784 my->image = my->Cnt[0];
785
786 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
787 return NullDel;
788 if (my->Y > FieldH + my->Height/2)
789 return NullDel;
790
791 return NoneDel;
792 }
793