~ubuntu-branches/ubuntu/raring/powermanga/raring

« back to all changes in this revision

Viewing changes to src/guardians.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese, Gonéri Le Bouder, Cyril Brulebois, Barry deFreese
  • Date: 2008-03-19 21:32:41 UTC
  • mfrom: (1.2.4 upstream) (3.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20080319213241-sn6w3z75uppm22eq
Tags: 0.90-dfsg-1
[ Gonéri Le Bouder ]
* add desktop file, thanks Adrien Cunin (Closes: #402168)
 - powermanga.xpm moved in /usr/share/pixmaps
* call dh_desktop to run update-desktop-database

[ Cyril Brulebois ]
* Added XS-Vcs-Svn and XS-Vcs-Browser fields in the control file.

[ Barry deFreese ]
* Bump debhelper build-dep version to match compat
* Fix substvar source:Version
* Make distclean not ignore errors
* Add watch file
* Add Homepage field in control
* Remove XS- from VCS fields in control
* New Upstream Release (Closes: #447415)
  + Should now be dfsg free
  + Adds joystick support (Closes: #442322)
  + STILL NOT SURE ABOUT tlk.fnt
* Revert patches except fixing scoredir path and copyright for manpage
* Remove deprecated Encoding tag from desktop file
* Remove file extension from icon tag in desktop file
* Replace evil 'pwd' with $(CURDIR)
* Removing config.log config.status in clean target
* Convert copyright to UTF-8.
* Remove order/ dir from upstream tarball.
* Remove empty dirs from powermanga package.
* Bump Standards Version to 3.7.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @file guardians.c 
 
3
 * @brief handle the guardians 
 
4
 * @created 1998-04-21
 
5
 * @date 2007-08-30
 
6
 * @author Jean-Michel Martin de Santero
 
7
 * @author Bruno Ethvignot
 
8
 */
 
9
/*
 
10
 * copyright (c) 1998-2007 TLK Games all rights reserved
 
11
 * $Id: guardians.c,v 1.49 2007/08/31 20:46:43 gurumeditation Exp $
 
12
 *
 
13
 * Powermanga is free software; you can redistribute it and/or modify
 
14
 * it under the terms of the GNU General Public License as published by
 
15
 * the Free Software Foundation; either version 3 of the License, or
 
16
 * (at your option) any later version.
 
17
 *
 
18
 * Powermanga is distributed in the hope that it will be useful, but
 
19
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
21
 * GNU General Public License for more details.
 
22
 *
 
23
 * You should have received a copy of the GNU General Public License
 
24
 * along with this program; if not, write to the Free Software
 
25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
26
 * MA  02110-1301, USA.
 
27
 */
 
28
#include <stdbool.h>
 
29
#include "powermanga.h"
 
30
#include "tools.h"
 
31
#include "images.h"
 
32
#include "config_file.h"
 
33
#include "congratulations.h"
 
34
#include "curve_phase.h"
 
35
#include "display.h"
 
36
#include "electrical_shock.h"
 
37
#include "enemies.h"
 
38
#include "bonus.h"
 
39
#include "energy_gauge.h"
 
40
#include "explosions.h"
 
41
#include "shots.h"
 
42
#include "extra_gun.h"
 
43
#include "gfx_wrapper.h"
 
44
#include "grid_phase.h"
 
45
#include "guardians.h"
 
46
#include "images.h"
 
47
#include "menu.h"
 
48
#include "menu_sections.h"
 
49
#include "meteors_phase.h"
 
50
#include "lonely_foes.h"
 
51
#include "options_panel.h"
 
52
#include "satellite_protections.h"
 
53
#include "sdl_mixer.h"
 
54
#include "spaceship.h"
 
55
#include "starfield.h"
 
56
#include "texts.h"
 
57
 
 
58
/** Data structure for the sprites images of the guardian */
 
59
image gardi[GUARDIAN_MAX_OF_ANIMS][ENEMIES_SPECIAL_NUM_OF_IMAGES];
 
60
const Sint32 clip_gard10 = 16;
 
61
guardian_struct *guardian;
 
62
 
 
63
/**
 
64
 * Initialization guardian that is only run once
 
65
 * @return TRUE if it completed successfully or FALSE otherwise
 
66
 */
 
67
bool
 
68
guardians_once_init (void)
 
69
{
 
70
  meteors_free ();
 
71
  if (guardian == NULL)
 
72
    {
 
73
      guardian =
 
74
        (guardian_struct *) memory_allocation (sizeof (guardian_struct));
 
75
      if (guardian == NULL)
 
76
        {
 
77
          fprintf (stderr, "(!)guardians.c/guardians_once_init():"
 
78
                   "not enough memory to allocate 'guardian_struct'!\n");
 
79
          return FALSE;
 
80
        }
 
81
    }
 
82
  return TRUE;
 
83
}
 
84
 
 
85
/**
 
86
 * Release memory used by the current guardian
 
87
 */
 
88
static void
 
89
guardian_images_free (void)
 
90
{
 
91
  Uint32 i, j;
 
92
  for (i = 0; i < GUARDIAN_MAX_OF_ANIMS; i++)
 
93
    {
 
94
      for (j = 0; j < ENEMIES_SPECIAL_NUM_OF_IMAGES; j++)
 
95
        {
 
96
          if (gardi[i][j].img != NULL)
 
97
            {
 
98
              free_memory (gardi[i][j].img);
 
99
              gardi[i][j].img = NULL;
 
100
            }
 
101
          if (gardi[i][j].compress != NULL)
 
102
            {
 
103
              free_memory (gardi[i][j].compress);
 
104
              gardi[i][j].compress = NULL;
 
105
            }
 
106
        }
 
107
    }
 
108
}
 
109
 
 
110
/**
 
111
 * Release memory used by the guardians
 
112
 */
 
113
void
 
114
guardians_free (void)
 
115
{
 
116
  guardian_images_free ();
 
117
  if (guardian != NULL)
 
118
    {
 
119
      free_memory ((char *) guardian);
 
120
      guardian = NULL;
 
121
    }
 
122
}
 
123
 
 
124
/**
 
125
 * Initialize a new guardian
 
126
 * @param type Guardian identifier
 
127
 * @param current_image Current image index
 
128
 * @param energy_level Energy level of guardian
 
129
 * @param anim_speed Time delay before next image 
 
130
 * @param fire_rate Counter of delay between two shots
 
131
 * @param speed Speed of the sprite
 
132
 */
 
133
static enemy *
 
134
guardian_init (Uint32 index, Uint32 type, Sint32 current_image,
 
135
               Uint32 energy_level, Uint32 anim_speed, Uint32 fire_rate,
 
136
               float speed)
 
137
{
 
138
  Sint32 i;
 
139
  enemy *guard;
 
140
  spaceship_struct *ship = spaceship_get ();
 
141
  guard = enemy_get ();
 
142
  if (guard == NULL)
 
143
    {
 
144
      return NULL;
 
145
    }
 
146
  guard->spr.pow_of_dest = (Sint16) ((ship->type << 1) + type);
 
147
  guard->spr.energy_level =
 
148
    (ship->type << 2) + (guard->spr.pow_of_dest << 3) / 3 + energy_level;
 
149
  guard->spr.max_energy_level = guard->spr.energy_level;
 
150
  guard->spr.numof_images = 32;
 
151
  guard->spr.current_image = current_image;
 
152
  guard->spr.anim_count = 0;
 
153
  guard->spr.anim_speed = anim_speed;
 
154
  for (i = 0; i < guard->spr.numof_images; i++)
 
155
    {
 
156
      guard->spr.img[i] = (image *) & gardi[index][i];
 
157
    }
 
158
  guard->fire_rate = fire_rate;
 
159
  guard->fire_rate_count = guard->fire_rate;
 
160
  guard->displacement = DISPLACEMENT_GUARDIAN;
 
161
  guard->spr.speed = speed;
 
162
  guard->type = type;
 
163
  guard->dead = FALSE;
 
164
  guard->visible = TRUE;
 
165
  guardian->enemy[index] = guard;
 
166
  return guard;
 
167
}
 
168
 
 
169
/**
 
170
 * Add a guardian displacement
 
171
 * @param direction Direction of this displacement
 
172
 * @param delay Time delay of this displacement
 
173
 * @param speed Speed of this displacement
 
174
 */
 
175
static void
 
176
guardian_add_move (Uint32 direction, Sint32 delay, Uint32 speed)
 
177
{
 
178
  guardian->move_direction[guardian->move_max] = direction;
 
179
  guardian->move_delay[guardian->move_max] = delay;
 
180
  guardian->move_speed[guardian->move_max++] = speed;
 
181
}
 
182
 
 
183
/**
 
184
 * Initialize a direction toward left 
 
185
 */
 
186
static void
 
187
guardian_set_direction_toward_left (void)
 
188
{
 
189
  guardian_add_move (GUARD_IMMOBILE, 100, 0);
 
190
  guardian_add_move (GUARD_MOVEMENT_TOWARD_LEFT, 400, 1);
 
191
}
 
192
 
 
193
/**
 
194
 * Initialize a direction toward right
 
195
 */
 
196
static void
 
197
guardian_set_direction_toward_right (void)
 
198
{
 
199
  guardian_add_move (GUARD_IMMOBILE, 100, 0);
 
200
  guardian_add_move (GUARD_MOVEMENT_TOWARD_RIGHT, 400, 1);
 
201
}
 
202
 
 
203
/**
 
204
 * Initialize a direction toward top 
 
205
 */
 
206
static void
 
207
guardian_set_direction_toward_top (void)
 
208
{
 
209
  guardian_add_move (GUARD_IMMOBILE, 100, 0);
 
210
  guardian_add_move (GUARD_MOVEMENT_TOWARD_TOP, 400, 3);
 
211
}
 
212
 
 
213
/**
 
214
 * Initialize a direction toward bottom 
 
215
 */
 
216
static void
 
217
guardian_set_direction_toward_bottom (void)
 
218
{
 
219
  guardian_add_move (GUARD_IMMOBILE, 100, 0);
 
220
  guardian_add_move (GUARD_MOVEMENT_TOWARD_BOTTOM, 400, 3);
 
221
}
 
222
 
 
223
/**
 
224
 * Intialize guardian 01 
 
225
 * @return TRUE if it completed successfully or FALSE otherwise
 
226
 */
 
227
static bool
 
228
guardian_01_init (void)
 
229
{
 
230
  enemy *guard = guardian_init (0, THANIKEE, 15, 30, 4, 85, 0.5);
 
231
  if (guard == NULL)
 
232
    {
 
233
      return FALSE;
 
234
    }
 
235
  guard->spr.xcoord =
 
236
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
237
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[17]->h);
 
238
  guardian_set_direction_toward_right ();
 
239
  guardian_set_direction_toward_left ();
 
240
  return TRUE;
 
241
}
 
242
 
 
243
/**
 
244
 * Intialize guardian 02
 
245
 * @return TRUE if it completed successfully or FALSE otherwise
 
246
 */
 
247
static bool
 
248
guardian_02_init (void)
 
249
{
 
250
  enemy *guard = guardian_init (0, BARYBOOG, 15, 50, 4, 50, 1.0);
 
251
  if (guard == NULL)
 
252
    {
 
253
      return FALSE;
 
254
    }
 
255
  guard->spr.xcoord =
 
256
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
257
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
258
  guardian_set_direction_toward_left ();
 
259
  guardian_set_direction_toward_right ();
 
260
  guardian_set_direction_toward_bottom ();
 
261
  guardian_set_direction_toward_top ();
 
262
  guardian_set_direction_toward_left ();
 
263
  guardian_set_direction_toward_right ();
 
264
  guardian_set_direction_toward_left ();
 
265
  guardian_set_direction_toward_bottom ();
 
266
  guardian_set_direction_toward_top ();
 
267
  guardian_set_direction_toward_right ();
 
268
  guardian->x_min = offscreen_clipsize - 10;
 
269
  guardian->x_max = offscreen_clipsize + offscreen_width_visible + 40;
 
270
  guardian->y_min = offscreen_clipsize - 15;
 
271
  guardian->y_max = offscreen_clipsize + offscreen_height_visible + 40;
 
272
  return TRUE;
 
273
}
 
274
 
 
275
/**
 
276
 * Intialize guardian 03
 
277
 * @return TRUE if it completed successfully or FALSE otherwise
 
278
 */
 
279
static bool
 
280
guardian_03_init (void)
 
281
{
 
282
  enemy *guard = guardian_init (0, PIKKIOU, 15, 70, 4, 75, 0.5);
 
283
  if (guard == NULL)
 
284
    {
 
285
      return FALSE;
 
286
    }
 
287
  guard->spr.xcoord =
 
288
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
289
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
290
  guardian_set_direction_toward_right ();
 
291
  guardian_set_direction_toward_left ();
 
292
  guardian->lonely_foe_delay = 16;
 
293
  return TRUE;
 
294
}
 
295
 
 
296
/**
 
297
 * Intialize guardian 04
 
298
 * @return TRUE if it completed successfully or FALSE otherwise
 
299
 */
 
300
static bool
 
301
guardian_04_init (void)
 
302
{
 
303
  enemy *guard = guardian_init (0, NEGDEIS, 15, 90, 4, 75, 0.5);
 
304
  if (guard == NULL)
 
305
    {
 
306
      return FALSE;
 
307
    }
 
308
  guard->spr.xcoord =
 
309
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
310
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
311
  guardian_set_direction_toward_right ();
 
312
  guardian_set_direction_toward_left ();
 
313
  guardian_set_direction_toward_bottom ();
 
314
  guardian_add_move (GUARD_MOVEMENT_TOWARD_TOP, 400, 3);
 
315
  guardian_set_direction_toward_right ();
 
316
  guardian_set_direction_toward_left ();
 
317
  guardian_set_direction_toward_right ();
 
318
  guardian_set_direction_toward_bottom ();
 
319
  guardian_add_move (GUARD_MOVEMENT_TOWARD_TOP, 400, 3);
 
320
  guardian_set_direction_toward_left ();
 
321
  /* clear time delay of launch of SAPOUCH */
 
322
  guardian->lonely_foe_delay = 0;
 
323
  guardian->devilians_counter = 0;
 
324
  guardian->devilians_enable = FALSE;
 
325
  guardian->devilians_delay = 0;
 
326
  /* generate Naggys to amuse player before the appearance of guardian */
 
327
  lonely_foe_add (NAGGYS);
 
328
  return TRUE;
 
329
}
 
330
 
 
331
/**
 
332
 * Intialize guardian 05
 
333
 * @return TRUE if it completed successfully or FALSE otherwise
 
334
 */
 
335
static bool
 
336
guardian_05_init (void)
 
337
{
 
338
  enemy *guard = guardian_init (0, FLASHY, 15, 110, 4, 80, 0.5);
 
339
  if (guard == NULL)
 
340
    {
 
341
      return FALSE;
 
342
    }
 
343
  guard->spr.xcoord =
 
344
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
345
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
346
  guardian_set_direction_toward_right ();
 
347
  guardian_set_direction_toward_left ();
 
348
  guardian_set_direction_toward_bottom ();
 
349
  guardian_add_move (GUARD_MOVEMENT_TOWARD_TOP, 400, 3);
 
350
  guardian_set_direction_toward_right ();
 
351
  guardian_set_direction_toward_left ();
 
352
  guardian_set_direction_toward_right ();
 
353
  guardian_set_direction_toward_bottom ();
 
354
  guardian_add_move (GUARD_MOVEMENT_TOWARD_TOP, 400, 3);
 
355
  guardian_set_direction_toward_left ();
 
356
  guardian->soukee_delay = 0;
 
357
  return TRUE;
 
358
}
 
359
 
 
360
/**
 
361
 * Intialize guardian 06
 
362
 * @return TRUE if it completed successfully or FALSE otherwise
 
363
 */
 
364
static bool
 
365
guardian_06_init (void)
 
366
{
 
367
  enemy *guard = guardian_init (0, MEECKY, 15, 130, 4, 80, 0.5);
 
368
  if (guard == NULL)
 
369
    {
 
370
      return FALSE;
 
371
    }
 
372
  guard->spr.xcoord =
 
373
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
374
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
375
  guard = guardian_init (1, MEECKY, 15, 0, 4, 80, 0.5);
 
376
  if (guard == NULL)
 
377
    {
 
378
      return FALSE;
 
379
    }
 
380
  guard->spr.xcoord = guardian->enemy[0]->spr.xcoord;
 
381
  guard->spr.ycoord = guardian->enemy[0]->spr.ycoord + 63;
 
382
  guard->spr.energy_level = (guard->spr.pow_of_dest << 3) / 3;
 
383
  guard->spr.max_energy_level = guard->spr.energy_level;
 
384
  guardian_set_direction_toward_right ();
 
385
  guardian_set_direction_toward_left ();
 
386
  guardian->missile_delay = 0;
 
387
  guardian->x_min = (float) offscreen_clipsize - 16;
 
388
  guardian->x_max =
 
389
    (float) (offscreen_clipsize + offscreen_width_visible + 48);
 
390
  guardian->y_max =
 
391
    (float) (offscreen_clipsize + offscreen_height_visible + 40);
 
392
  guardian->y_inc = 1.0;
 
393
  return TRUE;
 
394
}
 
395
 
 
396
/**
 
397
 * Intialize guardian 07 (wheel with double reverse rotation)
 
398
 * @return TRUE if it completed successfully or FALSE otherwise
 
399
 */
 
400
static bool
 
401
guardian_07_init (void)
 
402
{
 
403
  enemy *guard = guardian_init (0, TYPYBOON, 0, 150, 4, 55, 0.5);
 
404
  if (guard == NULL)
 
405
    {
 
406
      return FALSE;
 
407
    }
 
408
  guard->spr.xcoord =
 
409
    (float) (offscreen_width_visible - guard->spr.img[0]->w / 2);
 
410
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[0]->h);
 
411
  guardian_set_direction_toward_right ();
 
412
  guardian_set_direction_toward_left ();
 
413
  guardian->quibouly_delay = 0;
 
414
  if (num_of_enemies < (MAX_OF_ENEMIES - 2))
 
415
    {
 
416
      lonely_foe_add (NAGGYS);
 
417
    }
 
418
  return TRUE;
 
419
}
 
420
 
 
421
/**
 
422
 * Intialize guardian 08
 
423
 * @return TRUE if it completed successfully or FALSE otherwise
 
424
 */
 
425
static bool
 
426
guardian_08_init (void)
 
427
{
 
428
  enemy *guard = guardian_init (0, MATHYDEE, 0, 170, 4, 65, 0.5);
 
429
  if (guard == NULL)
 
430
    {
 
431
      return FALSE;
 
432
    }
 
433
  guard->spr.xcoord =
 
434
    (float) (offscreen_width_visible - guard->spr.img[0]->w / 2);
 
435
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[0]->h);
 
436
  guardian_set_direction_toward_right ();
 
437
  guardian_set_direction_toward_left ();
 
438
  guardian->tournadee_delay = 0;
 
439
  if (num_of_enemies < (MAX_OF_ENEMIES - 2))
 
440
    {
 
441
      lonely_foe_add (NAGGYS);
 
442
    }
 
443
  return TRUE;
 
444
}
 
445
 
 
446
/**
 
447
 * Intialize guardian 09
 
448
 * @return TRUE if it completed successfully or FALSE otherwise
 
449
 */
 
450
static bool
 
451
guardian_09_init (void)
 
452
{
 
453
  enemy *guard = guardian_init (0, OVYDOON, 15, 190, 4, 60, 0.5);
 
454
  if (guard == NULL)
 
455
    {
 
456
      return FALSE;
 
457
    }
 
458
  guard->spr.xcoord =
 
459
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
460
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
461
  guard = guardian_init (1, OVYDOON, 15, 0, 4, 75, 0.5);
 
462
  if (guard == NULL)
 
463
    {
 
464
      return FALSE;
 
465
    }
 
466
  guard->spr.energy_level = (guard->spr.pow_of_dest * 3) / 2;
 
467
  guard->spr.max_energy_level = guard->spr.energy_level;
 
468
  guard->spr.xcoord = guardian->enemy[0]->spr.xcoord;
 
469
  guard->spr.ycoord = guardian->enemy[0]->spr.ycoord;
 
470
  guardian_set_direction_toward_right ();
 
471
  guardian_set_direction_toward_left ();
 
472
  guardian->lonely_foe_delay = 0;
 
473
  if (num_of_enemies < (MAX_OF_ENEMIES - 2))
 
474
    {
 
475
      lonely_foe_add (NAGGYS);
 
476
    }
 
477
  return TRUE;
 
478
}
 
479
 
 
480
/**
 
481
 * Intialize guardian 10
 
482
 * @return TRUE if it completed successfully or FALSE otherwise
 
483
 */
 
484
static bool
 
485
guardian_10_init (void)
 
486
{
 
487
  enemy *guard = guardian_init (0, GATLEENY, 15, 210, 1, 50, 0.5);
 
488
  if (guard == NULL)
 
489
    {
 
490
      return FALSE;
 
491
    }
 
492
  guard->spr.xcoord =
 
493
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
494
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
495
  guard = guardian_init (1, GATLEENY, 8, 210, 20, 65, 0.5);
 
496
  if (guard == NULL)
 
497
    {
 
498
      return FALSE;
 
499
    }
 
500
  guard->spr.xcoord = guardian->enemy[0]->spr.xcoord;
 
501
  guard->spr.ycoord = guardian->enemy[0]->spr.ycoord;
 
502
  guardian->move_current = GUARD_MOVEMENT_TOWARD_BOTTOM;
 
503
  guardian->lonely_foe_delay = 0;
 
504
  if (num_of_enemies < (MAX_OF_ENEMIES - 2))
 
505
    {
 
506
      lonely_foe_add (NAGGYS);
 
507
    }
 
508
 
 
509
  return TRUE;
 
510
}
 
511
 
 
512
/**
 
513
 * Intialize guardian 11
 
514
 * @return TRUE if it completed successfully or FALSE otherwise
 
515
 */
 
516
static bool
 
517
guardian_11_init (void)
 
518
{
 
519
  enemy *guard = guardian_init (0, NAUTEE, 15, 230, 4, 60, 0.5);
 
520
  if (guard == NULL)
 
521
    {
 
522
      return FALSE;
 
523
    }
 
524
  guard->spr.xcoord =
 
525
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
526
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
527
  guardian_set_direction_toward_right ();
 
528
  guardian_set_direction_toward_left ();
 
529
  guardian->missile_delay = 0;
 
530
  guardian->sapouch_delay = 0;
 
531
  if (num_of_enemies < (MAX_OF_ENEMIES - 2))
 
532
    {
 
533
      lonely_foe_add (NAGGYS);
 
534
    }
 
535
  return TRUE;
 
536
}
 
537
 
 
538
/**
 
539
 * Intialize guardian 12
 
540
 * @return TRUE if it completed successfully or FALSE otherwise
 
541
 */
 
542
static bool
 
543
guardian_12_init (void)
 
544
{
 
545
  enemy *guard = guardian_init (0, KAMEAMEA, 15, 250, 4, 60, 0.5);
 
546
  if (guard == NULL)
 
547
    {
 
548
      return FALSE;
 
549
    }
 
550
  guard->spr.xcoord =
 
551
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
552
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
553
  guardian_add_move (GUARD_IMMOBILE, 100, 0);
 
554
  guardian_add_move (GUARD_MOVEMENT_TOWARD_LEFT, 50, 2);
 
555
  guardian_add_move (GUARD_IMMOBILE, 50, 0);
 
556
  guardian_add_move (GUARD_MOVEMENT_TOWARD_RIGHT, 50, 2);
 
557
  guardian_add_move (GUARD_IMMOBILE, 400, 0);
 
558
  guardian_add_move (GUARD_MOVEMENT_TOWARD_BOTTOM, 500, 4);
 
559
  guardian_add_move (GUARD_MOVEMENT_TOWARD_TOP, 500, 4);
 
560
  guardian_add_move (GUARD_IMMOBILE, 50, 0);
 
561
  guardian_add_move (GUARD_MOVEMENT_TOWARD_RIGHT, 50, 2);
 
562
  guardian_add_move (GUARD_IMMOBILE, 50, 0);
 
563
  guardian_add_move (GUARD_MOVEMENT_TOWARD_LEFT, 50, 2);
 
564
  guardian->y_min = offscreen_clipsize;
 
565
  guardian->y_max = offscreen_clipsize + offscreen_height_visible + 30;
 
566
  return TRUE;
 
567
}
 
568
 
 
569
/**
 
570
 * Initialize guardian 13
 
571
 * @return TRUE if it completed successfully or FALSE otherwise
 
572
 */
 
573
static bool
 
574
guardian_13_init (void)
 
575
{
 
576
  enemy *guard;
 
577
  guard = guardian_init (0, SUPRALIS, 8, 250, 4, 60, 0.5);
 
578
  if (guard == NULL)
 
579
    {
 
580
      return FALSE;
 
581
    }
 
582
  guard->spr.xcoord =
 
583
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
584
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
585
  guardian->y_inc = 2.0;
 
586
  guardian_add_move (GUARD_IMMOBILE, 10, 0);
 
587
  guardian_add_move (GUARD_MOVEMENT_TOWARD_RIGHT, 400, 3);
 
588
  guardian_add_move (GUARD_IMMOBILE, 10, 0);
 
589
  guardian_add_move (GUARD_MOVEMENT_TOWARD_LEFT, 400, 3);
 
590
  guardian->x_min = offscreen_clipsize - 20;
 
591
  guardian->x_max = offscreen_clipsize + offscreen_width_visible + 20;
 
592
  guardian->y_min = offscreen_clipsize;
 
593
  guardian->y_max = offscreen_clipsize + offscreen_height_visible;
 
594
  return TRUE;
 
595
}
 
596
 
 
597
/**
 
598
 * Intialize guardian 14, guardian with long trunk
 
599
 * @return TRUE if it completed successfully or FALSE otherwise
 
600
 */
 
601
static bool
 
602
guardian_14_init (void)
 
603
{
 
604
  enemy *guard;
 
605
  guard = guardian_init (0, GHOTTEN, 31, 250, 4, 60, 0.5);
 
606
  if (guard == NULL)
 
607
    {
 
608
      return FALSE;
 
609
    }
 
610
  guard->spr.xcoord =
 
611
    (float) (offscreen_width_visible - guard->spr.img[15]->w / 2);
 
612
  guard->spr.ycoord = (float) (offscreen_starty - guard->spr.img[15]->h);
 
613
  guardian_add_move (GUARD_MOVEMENT_TOWARD_RIGHT, 400, 2);
 
614
  guardian_add_move (GUARD_MOVEMENT_TOWARD_LEFT, 400, 2);
 
615
  guardian->x_min = offscreen_clipsize + 10;
 
616
  guardian->x_max = offscreen_clipsize + offscreen_width_visible - 10;
 
617
  guardian->perturbians_delay = 0;
 
618
  guardian->saakamin_delay = 0;
 
619
  return TRUE;
 
620
}
 
621
 
 
622
/** 
 
623
 *  Meteors storm finished: initialize a new guardian 
 
624
 *  @param guardian_num number of the guardian 1 to 14, 15=congratulations
 
625
 *  @return TRUE if it completed successfully or FALSE otherwise
 
626
 */
 
627
bool
 
628
guardian_new (Uint32 guardian_num)
 
629
{
 
630
  bool result = TRUE;
 
631
  guardian->number = guardian_num;
 
632
  guardian->is_appearing = TRUE;
 
633
  courbe.activity = FALSE;
 
634
  grid.is_enable = FALSE;
 
635
  meteor_activity = FALSE;
 
636
  energy_gauge_guard_is_update = TRUE;
 
637
  guardian->is_enabled = TRUE;
 
638
  guardian->current_images_set = 0;
 
639
  guardian->move_current = 0;
 
640
  guardian->move_max = 0;
 
641
  guardian->x_min = offscreen_clipsize;
 
642
  guardian->x_max = offscreen_clipsize + offscreen_width_visible;
 
643
  guardian->y_min = offscreen_clipsize;
 
644
  guardian->y_max = offscreen_clipsize + offscreen_height_visible;
 
645
  guardian->y_inc = 0;
 
646
  switch (guardian_num)
 
647
    {
 
648
    case 1:
 
649
      result = guardian_01_init ();
 
650
      break;
 
651
    case 2:
 
652
      result = guardian_02_init ();
 
653
      break;
 
654
    case 3:
 
655
      result = guardian_03_init ();
 
656
      break;
 
657
    case 4:
 
658
      result = guardian_04_init ();
 
659
      break;
 
660
    case 5:
 
661
      result = guardian_05_init ();
 
662
      break;
 
663
    case 6:
 
664
      result = guardian_06_init ();
 
665
      break;
 
666
    case 7:
 
667
      result = guardian_07_init ();
 
668
      break;
 
669
    case 8:
 
670
      result = guardian_08_init ();
 
671
      break;
 
672
    case 9:
 
673
      result = guardian_09_init ();
 
674
      break;
 
675
    case 10:
 
676
      result = guardian_10_init ();
 
677
      break;
 
678
    case 11:
 
679
      result = guardian_11_init ();
 
680
      break;
 
681
    case 12:
 
682
      result = guardian_12_init ();
 
683
      break;
 
684
    case 13:
 
685
      result = guardian_13_init ();
 
686
      break;
 
687
    case 14:
 
688
      result = guardian_14_init ();
 
689
      break;
 
690
    case 15:
 
691
      congratulations_initialize ();
 
692
      break;
 
693
    default:
 
694
      result = TRUE;
 
695
    }
 
696
  if (!result)
 
697
    {
 
698
      return FALSE;
 
699
    }
 
700
  return TRUE;
 
701
}
 
702
 
 
703
/**
 
704
 * The guardian appears from the screen top
 
705
 * @param guard Pointer to a enemy structure
 
706
 */
 
707
static void
 
708
guardian_appears_from_top (enemy * guard)
 
709
{
 
710
  guard->spr.ycoord += guard->spr.speed;
 
711
  if (guard->spr.ycoord >= offscreen_clipsize)
 
712
    {
 
713
      guard->spr.ycoord = (float) offscreen_clipsize;
 
714
      guardian->is_appearing = FALSE;
 
715
      guardian->move_current = 0;
 
716
      guardian->move_time_delay =
 
717
        guardian->move_delay[guardian->move_current];
 
718
    }
 
719
}
 
720
 
 
721
/**
 
722
 * Add a new shot (type bullet) in guardian phase
 
723
 * @param guard Pointer to the enemy guardian
 
724
 * @param power Power of the destruction 
 
725
 * @param speed Speed of the displacement
 
726
 * @return Number of bullets fired
 
727
 */
 
728
static Uint32
 
729
guardian_fire (enemy * guard, Sint32 power, float speed)
 
730
{
 
731
  Uint32 cannon_num, numof_bullets;
 
732
  if (player_pause || menu_status != MENU_OFF
 
733
      || menu_section != NO_SECTION_SELECTED)
 
734
    {
 
735
      return 0;
 
736
    }
 
737
  guard->fire_rate_count--;
 
738
  if (guard->fire_rate_count > 0 || num_of_shots >= (MAX_OF_SHOTS - 1))
 
739
    {
 
740
      return 0;
 
741
    }
 
742
  guard->fire_rate_count = guard->fire_rate;
 
743
  numof_bullets = 0;
 
744
  for (cannon_num = 0;
 
745
       cannon_num < guard->spr.img[guard->spr.current_image]->numof_cannons;
 
746
       cannon_num++)
 
747
    {
 
748
      shot_guardian_add (guard, cannon_num, power, speed);
 
749
      numof_bullets++;
 
750
    }
 
751
#ifdef USE_SDLMIXER
 
752
  sound_play (SOUND_GUARDIAN_FIRE_1);
 
753
#endif
 
754
  return numof_bullets;
 
755
}
 
756
 
 
757
/**
 
758
 * Add one missile
 
759
 * @param type Type of foe 
 
760
 * @param current_image Current image index 
 
761
 * @param img_angle Angle of displacement
 
762
 * @param angle_tir 
 
763
 * @return Pointer to the new enemy element
 
764
 */
 
765
static enemy *
 
766
guardian_add_missile (Uint32 type, Uint32 current_image, Sint32 img_angle,
 
767
                      float angle_tir)
 
768
{
 
769
  Uint32 i;
 
770
  enemy *foe;
 
771
  spaceship_struct *ship = spaceship_get ();
 
772
  foe = enemy_get ();
 
773
  if (foe == NULL)
 
774
    {
 
775
      return NULL;
 
776
    }
 
777
  foe->spr.pow_of_dest = (Sint16) ((ship->type << 1) + 5);
 
778
  foe->spr.energy_level = foe->spr.pow_of_dest >> 2;
 
779
  foe->spr.numof_images = 32;
 
780
  foe->spr.current_image = current_image;
 
781
  foe->spr.anim_count = 0;
 
782
  foe->spr.anim_speed = 2;
 
783
  for (i = 0; i < foe->spr.numof_images; i++)
 
784
    {
 
785
      foe->spr.img[i] = (image *) & fire[MISSx4][i];
 
786
    }
 
787
  foe->fire_rate = 70;
 
788
  foe->fire_rate_count = foe->fire_rate;
 
789
  foe->displacement = DISPLACEMENT_LONELY_FOE;
 
790
  foe->spr.speed = 2.0f;
 
791
  foe->type = type;
 
792
  foe->dead = FALSE;
 
793
  foe->visible = TRUE;
 
794
  foe->img_angle = img_angle;
 
795
  foe->angle_tir = angle_tir;
 
796
  foe->img_old_angle = foe->img_angle;
 
797
  foe->agilite = 0.028f;
 
798
  return foe;
 
799
}
 
800
 
 
801
/**
 
802
 * Add one or more missiles homing head
 
803
 * @param guard Pointer the main enemy structure of the guardian
 
804
 * @param inc Counter step
 
805
 * @param max_counter Delay before send the missiles 
 
806
 * @param numof_miss Number of missiles to add from 1 to n
 
807
 * @return TRUE if at least one missile was added or FALSE otherwise
 
808
 */
 
809
static void
 
810
guardian_add_missiles (enemy * guard, Uint32 inc, Uint32 max_counter,
 
811
                       Uint32 numof_miss)
 
812
{
 
813
  Sint32 img_angle;
 
814
  float angle_tir;
 
815
  Uint32 i;
 
816
  enemy *foe;
 
817
  guardian->missile_delay += inc;
 
818
  while (guardian->missile_delay >= max_counter && !spaceship_is_dead)
 
819
    {
 
820
      guardian->missile_delay -= max_counter;
 
821
      if (guardian->missile_delay < 0)
 
822
        {
 
823
          guardian->missile_delay = 0;
 
824
        }
 
825
      img_angle = 0;
 
826
      for (i = 0; i < numof_miss; i++)
 
827
        {
 
828
          if (img_angle == 16)
 
829
            {
 
830
              img_angle = 0;
 
831
              angle_tir = 0.0;
 
832
            }
 
833
          else
 
834
            {
 
835
              img_angle = 16;
 
836
              angle_tir = PI;
 
837
            }
 
838
          foe = guardian_add_missile (SOUKEE, 16, img_angle, angle_tir);
 
839
          if (foe == NULL)
 
840
            {
 
841
              return;
 
842
            }
 
843
          foe->spr.xcoord =
 
844
            guard->spr.xcoord +
 
845
            guard->spr.img[guard->spr.current_image]->
 
846
            cannons_coords[i][XCOORD] - foe->spr.img[foe->img_angle]->x_gc;
 
847
          foe->spr.ycoord =
 
848
            guard->spr.ycoord +
 
849
            guard->spr.img[guard->spr.current_image]->
 
850
            cannons_coords[i][YCOORD] - foe->spr.img[foe->img_angle]->y_gc;
 
851
#ifdef USE_SDLMIXER
 
852
          if (img_angle == 16)
 
853
            {
 
854
              sound_play (SOUND_GUARDIAN_FIRE_2);
 
855
            }
 
856
          else
 
857
            {
 
858
              sound_play (SOUND_GUARDIAN_FIRE_3);
 
859
            }
 
860
#endif
 
861
        }
 
862
    }
 
863
}
 
864
 
 
865
/**
 
866
 * Add an enemy who is specific in the guardian
 
867
 * @param type Type of foe 
 
868
 * @param pow_of_des Power of destruction
 
869
 * @param energy_level Energy level  (<= 0 destroyed foe)
 
870
 * @param current_image Current image index 
 
871
 * @param anim_speed Time delay before next image (animation speed)
 
872
 * @param fire_rate Counter of delay between two shots
 
873
 * @param speed Speed of the sprite
 
874
 * @return Pointer to the new enemy element
 
875
 */
 
876
static enemy *
 
877
guardian_add_foe (Uint32 type, Uint32 pow_of_des, Uint32 energy_level,
 
878
                  Uint32 current_image, Uint32 anim_speed, Uint32 fire_rate,
 
879
                  float speed)
 
880
{
 
881
  Uint32 i;
 
882
  enemy *foe;
 
883
  spaceship_struct *ship = spaceship_get ();
 
884
  foe = enemy_get ();
 
885
  if (foe == NULL)
 
886
    {
 
887
      return NULL;
 
888
    }
 
889
  foe->spr.pow_of_dest = (ship->type << 1) + pow_of_des;
 
890
  foe->spr.energy_level = energy_level;
 
891
  foe->spr.numof_images = 32;
 
892
  foe->spr.current_image = current_image;
 
893
  foe->spr.anim_count = 0;
 
894
  foe->spr.anim_speed = anim_speed;
 
895
  for (i = 0; i < foe->spr.numof_images; i++)
 
896
    {
 
897
      foe->spr.img[i] = (image *) & enemi[type][i];
 
898
    }
 
899
  foe->fire_rate = fire_rate;
 
900
  foe->fire_rate_count = foe->fire_rate;
 
901
  foe->displacement = DISPLACEMENT_LONELY_FOE;
 
902
  foe->spr.speed = speed;
 
903
  foe->type = type;
 
904
  foe->dead = FALSE;
 
905
  foe->visible = TRUE;
 
906
  return foe;
 
907
}
 
908
 
 
909
/**
 
910
 * Add a lonely foe to the enemies list
 
911
 * @param max_counter delay before send a lonely foe
 
912
 * @param foe_num Foe number of -1 if foe is automatically selected  
 
913
 */
 
914
static void
 
915
guardian_add_lonely_foe (Uint32 max_counter, Sint32 foe_num)
 
916
{
 
917
  guardian->lonely_foe_delay++;
 
918
  if (guardian->lonely_foe_delay < max_counter)
 
919
    {
 
920
      return;
 
921
    }
 
922
  lonely_foe_add (foe_num);
 
923
#ifdef USE_SDLMIXER
 
924
  sound_play (SOUND_GUARDIAN_FIRE_2);
 
925
#endif
 
926
  guardian->lonely_foe_delay = 0;
 
927
}
 
928
 
 
929
/**
 
930
 * Add a Soukee foe to the enemies list
 
931
 * @param guard Pointer the main enemy structure of the guardian
 
932
 * @param inc Counter step
 
933
 * @param max_counter Delay before send a Soukee 
 
934
 */
 
935
static void
 
936
guardian_add_soukee (enemy * guard, Uint32 inc, Uint32 max_counter)
 
937
{
 
938
  enemy *foe;
 
939
  spaceship_struct *ship = spaceship_get ();
 
940
  guardian->soukee_delay += inc;
 
941
  while (guardian->soukee_delay >= max_counter && !spaceship_is_dead)
 
942
    {
 
943
      guardian->soukee_delay -= max_counter;
 
944
      if (guardian->soukee_delay < 0)
 
945
        {
 
946
          guardian->soukee_delay = 0;
 
947
        }
 
948
      foe =
 
949
        guardian_add_foe (SOUKEE, 14, (ship->type << 1) + 14, 8, 2, 70, 2.0f);
 
950
      if (foe == NULL)
 
951
        {
 
952
          return;
 
953
        }
 
954
      foe->spr.xcoord =
 
955
        guard->spr.xcoord + guard->spr.img[guard->spr.current_image]->x_gc -
 
956
        foe->spr.img[0]->w / 2;
 
957
      foe->spr.ycoord =
 
958
        guard->spr.ycoord + guard->spr.img[guard->spr.current_image]->y_gc -
 
959
        foe->spr.img[0]->h / 2;
 
960
      foe->img_angle = 8;
 
961
      foe->angle_tir = PI_SUR_2;
 
962
      foe->img_old_angle = foe->img_angle;
 
963
      foe->agilite = 0.018f;
 
964
#ifdef USE_SDLMIXER
 
965
      sound_play (SOUND_GUARDIAN_FIRE_2);
 
966
#endif
 
967
    }
 
968
}
 
969
 
 
970
/**
 
971
 * Add a Shuriky foe to the enemies list
 
972
 * @param guard Pointer the main enemy structure of the guardian
 
973
 * @param max_counter Delay before send a Shuriky 
 
974
 */
 
975
void
 
976
guardian_add_shuriky (enemy * guard, Uint32 max_counter)
 
977
{
 
978
  enemy *foe;
 
979
  spaceship_struct *ship = spaceship_get ();
 
980
  guardian->shuriky_delay++;
 
981
  if (guardian->shuriky_delay < max_counter)
 
982
    {
 
983
      return;
 
984
    }
 
985
  guardian->shuriky_delay = 0;
 
986
  foe =
 
987
    guardian_add_foe (SHURIKY, 10, (ship->type << 1) + 10, 0, 2, 70, 0.3f);
 
988
  if (foe == NULL)
 
989
    {
 
990
      return;
 
991
    }
 
992
  foe->spr.xcoord =
 
993
    guard->spr.xcoord + guard->spr.img[guard->spr.current_image]->x_gc -
 
994
    foe->spr.img[0]->w / 2;
 
995
  foe->spr.ycoord =
 
996
    guard->spr.ycoord + guard->spr.img[guard->spr.current_image]->y_gc -
 
997
    foe->spr.img[0]->h / 2;
 
998
#ifdef USE_SDLMIXER
 
999
  sound_play (SOUND_GUARDIAN_FIRE_3);
 
1000
#endif
 
1001
}
 
1002
 
 
1003
/**
 
1004
 * Add a Devilians foe to the enemies list
 
1005
 * @param guard Pointer the main enemy structure of the guardian
 
1006
 * @param max_counter Delay before send a Quibouly 
 
1007
 * @param max_foes Number of foes launched before disable
 
1008
 */
 
1009
void
 
1010
guardian_add_devilians (enemy * guard, Uint32 max_counter, Uint32 max_foes)
 
1011
{
 
1012
  if (!guardian->devilians_enable)
 
1013
    {
 
1014
      return;
 
1015
    }
 
1016
  guardian->devilians_delay++;
 
1017
  if (guardian->devilians_delay < max_counter)
 
1018
    {
 
1019
      return;
 
1020
    }
 
1021
  lonely_foe_add (DEVILIANS);
 
1022
  guardian->devilians_delay = 0;
 
1023
  guardian->devilians_counter++;
 
1024
  if (guardian->devilians_counter >= max_foes)
 
1025
    {
 
1026
      guardian->devilians_counter = 0;
 
1027
      guardian->devilians_enable = FALSE;
 
1028
    }
 
1029
}
 
1030
 
 
1031
/**
 
1032
 * Add a Quibouly foe to the enemies list
 
1033
 * @param guard Pointer the main enemy structure of the guardian
 
1034
 * @param max_counter Delay before send a Quibouly 
 
1035
 */
 
1036
void
 
1037
guardian_add_quibouly (enemy * guard, Uint32 max_counter)
 
1038
{
 
1039
  enemy *foe;
 
1040
  spaceship_struct *ship = spaceship_get ();
 
1041
  guardian->quibouly_delay++;
 
1042
  if (guardian->quibouly_delay < max_counter)
 
1043
    {
 
1044
      return;
 
1045
    }
 
1046
  guardian->quibouly_delay = 0;
 
1047
  foe =
 
1048
    guardian_add_foe (QUIBOULY, 10, QUIBOULY + (ship->type << 1) + 10, 0, 2,
 
1049
                      50, 0.25f);
 
1050
  if (foe == NULL)
 
1051
    {
 
1052
      return;
 
1053
    }
 
1054
#ifdef USE_SDLMIXER
 
1055
  sound_play (SOUND_GUARDIAN_FIRE_2);
 
1056
#endif
 
1057
  foe->spr.xcoord =
 
1058
    guard->spr.xcoord + guard->spr.img[guard->spr.current_image]->x_gc -
 
1059
    foe->spr.img[0]->w / 2;
 
1060
  foe->spr.ycoord = guard->spr.ycoord + 96;
 
1061
}
 
1062
 
 
1063
/**
 
1064
 * Add a Shuriky foe to the enemies list
 
1065
 * @param guard Pointer the main enemy structure of the guardian
 
1066
 * @param max_counter Delay before send a Shuriky 
 
1067
 */
 
1068
void
 
1069
guardian_add_tournadee (enemy * guard, Uint32 max_counter)
 
1070
{
 
1071
  enemy *foe;
 
1072
  spaceship_struct *ship = spaceship_get ();
 
1073
  guardian->tournadee_delay++;
 
1074
  if (guardian->tournadee_delay < max_counter)
 
1075
    {
 
1076
      return;
 
1077
    }
 
1078
  guardian->tournadee_delay = 0;
 
1079
  foe =
 
1080
    guardian_add_foe (TOURNADEE, 10, TOURNADEE + (ship->type << 1) + 10, 0, 3,
 
1081
                      20, -0.2f);
 
1082
  if (foe == NULL)
 
1083
    {
 
1084
      return;
 
1085
    }
 
1086
  if (guardian->is_tournadee_left_pos)
 
1087
    {
 
1088
      guardian->is_tournadee_left_pos = FALSE;
 
1089
      foe->spr.xcoord = offscreen_startx - 2;
 
1090
    }
 
1091
  else
 
1092
    {
 
1093
      guardian->is_tournadee_left_pos = TRUE;
 
1094
      foe->spr.xcoord =
 
1095
        (float) (offscreen_startx + offscreen_width_visible -
 
1096
                 foe->spr.img[0]->w + 2);
 
1097
    }
 
1098
  foe->spr.ycoord = offscreen_starty + 32 + offscreen_height_visible;
 
1099
#ifdef USE_SDLMIXER
 
1100
  sound_play (SOUND_GUARDIAN_FIRE_2);
 
1101
#endif
 
1102
}
 
1103
 
 
1104
/**
 
1105
 * Add a Sapouch foe to the enemies list
 
1106
 * @param guard Pointer the main enemy structure of the guardian
 
1107
 * @param numof Number of Sapouch launched 1 or 2
 
1108
 * @param max_counter Delay before send a Sapouch 
 
1109
 * @param is_left TRUE if first Sapouch will be launched on left side
 
1110
 */
 
1111
static void
 
1112
guardian_add_sapouch (enemy * guard, Uint32 numof, Uint32 max_counter,
 
1113
                      bool is_left)
 
1114
{
 
1115
  float ycoord, speed;
 
1116
  Uint32 i;
 
1117
  enemy *foe;
 
1118
  spaceship_struct *ship = spaceship_get ();
 
1119
  guardian->sapouch_delay++;
 
1120
  if (guardian->sapouch_delay < max_counter)
 
1121
    {
 
1122
      return;
 
1123
    }
 
1124
  guardian->sapouch_delay = 0;
 
1125
  ycoord = offscreen_starty - 64;
 
1126
  speed = 2.5f + (float) (((long) rand () % (100))) / 100.0f;
 
1127
  for (i = 0; i < numof; i++)
 
1128
    {
 
1129
      foe =
 
1130
        guardian_add_foe (SAPOUCH, 10, SAPOUCH + (ship->type << 1) + 10, 0, 4,
 
1131
                          50 + (Sint32) ((long) rand () % (50)), speed);
 
1132
      if (foe == NULL)
 
1133
        {
 
1134
          return;
 
1135
        }
 
1136
      if (is_left)
 
1137
        {
 
1138
          foe->spr.xcoord = offscreen_startx;
 
1139
        }
 
1140
      else
 
1141
        {
 
1142
          foe->spr.xcoord =
 
1143
            offscreen_startx + offscreen_width_visible - foe->spr.img[0]->w;
 
1144
        }
 
1145
      foe->spr.ycoord = ycoord - foe->spr.img[0]->h;
 
1146
      foe->retournement = FALSE;
 
1147
      foe->change_dir = FALSE;
 
1148
#ifdef USE_SDLMIXER
 
1149
      sound_play (SOUND_GUARDIAN_FIRE_2);
 
1150
#endif
 
1151
      is_left = is_left ? FALSE : TRUE;
 
1152
    }
 
1153
}
 
1154
 
 
1155
/**
 
1156
 * Add a Perturbians foe to the enemies list
 
1157
 * @param guard Pointer the main enemy structure of the guardian
 
1158
 * @param numof Number of Perturbians launched 1 or 2
 
1159
 * @param max_counter Delay before send a Perturbians 
 
1160
 * @param is_left TRUE if first Perturbians will be launched on left side
 
1161
 */
 
1162
static void
 
1163
guardian_add_perturbians (enemy * guard, Uint32 numof, Uint32 max_counter,
 
1164
                          bool is_left)
 
1165
{
 
1166
  Uint32 i, fire_rate, power;
 
1167
  enemy *foe;
 
1168
  spaceship_struct *ship = spaceship_get ();
 
1169
  guardian->perturbians_delay++;
 
1170
  if (guardian->perturbians_delay < max_counter)
 
1171
    {
 
1172
      return;
 
1173
    }
 
1174
  guardian->perturbians_delay = 0;
 
1175
  fire_rate = 200 + (Sint32) ((long) rand () % (50));
 
1176
  power = (Sint32) ((ship->type << 1) + PERTURBIANS - 40);
 
1177
  for (i = 0; i < numof; i++)
 
1178
    {
 
1179
      foe =
 
1180
        guardian_add_foe (PERTURBIANS,
 
1181
                          (Sint32) ((ship->type << 1) + PERTURBIANS - 40),
 
1182
                          (Sint32) ((ship->type << 2) + (power << 3) / 3 +
 
1183
                                    10), 0, 6, fire_rate, 0.2f);
 
1184
      if (foe == NULL)
 
1185
        {
 
1186
          return;
 
1187
        }
 
1188
      if (is_left)
 
1189
        {
 
1190
          foe->spr.xcoord = offscreen_startx;
 
1191
        }
 
1192
      else
 
1193
        {
 
1194
          foe->spr.xcoord =
 
1195
            offscreen_startx + offscreen_width_visible - foe->spr.img[0]->w;
 
1196
        }
 
1197
      foe->spr.ycoord = (float) (offscreen_starty - 64 - foe->spr.img[0]->h);
 
1198
#ifdef USE_SDLMIXER
 
1199
      sound_play (SOUND_GUARDIAN_FIRE_2);
 
1200
#endif
 
1201
      is_left = is_left ? FALSE : TRUE;
 
1202
    }
 
1203
}
 
1204
 
 
1205
/**
 
1206
 * Add a Perturbians foe to the enemies list
 
1207
 * @param guard Pointer the main enemy structure of the guardian
 
1208
 * @param max_counter Delay before send a Perturbians 
 
1209
 */
 
1210
static void
 
1211
guardian_add_saakamin (enemy * guard, Uint32 max_counter, Uint32 numof)
 
1212
{
 
1213
  enemy *foe;
 
1214
  spaceship_struct *ship = spaceship_get ();
 
1215
  guardian->saakamin_delay++;
 
1216
  if (guardian->saakamin_delay < max_counter)
 
1217
    {
 
1218
      return;
 
1219
    }
 
1220
  guardian->saakamin_delay = 0;
 
1221
  while (--numof > 0)
 
1222
    {
 
1223
      foe =
 
1224
        guardian_add_foe (SAAKAMIN,
 
1225
                          14, (ship->type << 1) + 14, 8, 2, 70, 2.0f);
 
1226
      if (foe == NULL)
 
1227
        {
 
1228
          return;
 
1229
        }
 
1230
      foe->num_courbe = (Sint32) (((long) rand () % (121)));
 
1231
      foe->pos_vaiss[POS_CURVE] = 0;
 
1232
      foe->spr.xcoord =
 
1233
        (guard->spr.xcoord +
 
1234
         guard->spr.img[guard->spr.current_image]->
 
1235
         cannons_coords[0][XCOORD]) - foe->spr.img[0]->w / 2;
 
1236
      foe->spr.ycoord =
 
1237
        (guard->spr.ycoord +
 
1238
         guard->spr.img[guard->spr.current_image]->
 
1239
         cannons_coords[0][YCOORD]) - foe->spr.img[0]->h / 2;
 
1240
    }
 
1241
}
 
1242
 
 
1243
/**
 
1244
 * Guadian go to next trajectory
 
1245
 */
 
1246
static void
 
1247
guardian_next_trajectory (void)
 
1248
{
 
1249
  /* go to next trajectory */
 
1250
  guardian->move_current++;
 
1251
  /* maximum of displacements reached? */
 
1252
  if (guardian->move_current >= guardian->move_max)
 
1253
    {
 
1254
      guardian->move_current = 0;
 
1255
    }
 
1256
  guardian->has_changed_direction = TRUE;
 
1257
  guardian->move_time_delay = guardian->move_delay[guardian->move_current];
 
1258
}
 
1259
 
 
1260
/**
 
1261
 * Guadian get next trajectory identifier
 
1262
 */
 
1263
static Uint32
 
1264
guardian_get_next_trajectory (void)
 
1265
{
 
1266
  Uint32 move = guardian->move_current + 1;
 
1267
  if (move >= guardian->move_max)
 
1268
    {
 
1269
      move = 0;
 
1270
    }
 
1271
  return guardian->move_direction[move];
 
1272
}
 
1273
 
 
1274
/**
 
1275
 * Flip to next image. The animation is played once
 
1276
 * @param guard Pointer the main enemy structure of the guardian
 
1277
 * @param delay Time delay before next image
 
1278
 * @param reach Image number to reach
 
1279
 */
 
1280
static void
 
1281
guardian_flip_image (enemy * guard, Sint32 delay, Sint32 reach)
 
1282
{
 
1283
  guardian->anim_delay_count++;
 
1284
  if (guardian->anim_delay_count < delay)
 
1285
    {
 
1286
      return;
 
1287
    }
 
1288
  guardian->anim_delay_count = 0;
 
1289
  if (guard->spr.current_image == reach)
 
1290
    {
 
1291
      return;
 
1292
    }
 
1293
  if (guard->spr.current_image < reach)
 
1294
    {
 
1295
      guard->spr.current_image++;
 
1296
    }
 
1297
  else
 
1298
    {
 
1299
      guard->spr.current_image--;
 
1300
    }
 
1301
}
 
1302
 
 
1303
/**
 
1304
 * Flip to next image. The animation is played in loop-mode 
 
1305
 * @param guard Pointer the main enemy structure of the guardian
 
1306
 * @param delay Time delay before next image
 
1307
 * @param inc Step value 1 or -1
 
1308
 * @param limit Image number of the last image
 
1309
 * @param first Image number of the first image 
 
1310
 */
 
1311
static void
 
1312
guardian_loop_flip (enemy * guard, Sint32 delay, Sint32 inc, Sint32 limit,
 
1313
                    Sint32 first)
 
1314
{
 
1315
  guardian->anim_delay_count++;
 
1316
  if (guardian->anim_delay_count < delay)
 
1317
    {
 
1318
      return;
 
1319
    }
 
1320
  guardian->anim_delay_count = 0;
 
1321
  guard->spr.current_image += inc;
 
1322
  if ((inc > 0 && guard->spr.current_image > limit)
 
1323
      || (inc < 0 && guard->spr.current_image < limit))
 
1324
    {
 
1325
      guard->spr.current_image = first;
 
1326
    }
 
1327
}
 
1328
 
 
1329
/**
 
1330
 * Change images set of a guadian 
 
1331
 * @param guard Pointer the main enemy structure of the guardian
 
1332
 * @param images_num Images set number
 
1333
 */
 
1334
static void
 
1335
guardian_change_images_set (enemy * guard, Uint32 images_num)
 
1336
{
 
1337
  Uint32 i;
 
1338
  for (i = 0; i < guard->spr.numof_images; i++)
 
1339
    {
 
1340
      guard->spr.img[i] = (image *) & gardi[images_num][i];
 
1341
    }
 
1342
  guardian->current_images_set = images_num;
 
1343
}
 
1344
 
 
1345
/**
 
1346
 * Change images set of a guadian and the current image
 
1347
 * @param guard Pointer the main enemy structure of the guardian
 
1348
 * @param images_num Images set number
 
1349
 * @param current Current image number
 
1350
 */
 
1351
static void
 
1352
guardian_change_images (enemy * guard, Uint32 images_num, Uint32 current)
 
1353
{
 
1354
  guard->spr.current_image = current;
 
1355
  guardian_change_images_set (guard, images_num);
 
1356
}
 
1357
 
 
1358
/**
 
1359
 * Move the guardian follow a straightline
 
1360
 * @param guard Pointer to a enemy structure
 
1361
 */
 
1362
static void
 
1363
guardian_line_moving (enemy * guard)
 
1364
{
 
1365
  Uint32 move, speed, dir;
 
1366
  if (player_pause || menu_status != MENU_OFF
 
1367
      || menu_section != NO_SECTION_SELECTED)
 
1368
    {
 
1369
      return;
 
1370
    }
 
1371
  move = guardian->move_current;
 
1372
  speed = guardian->move_speed[move];
 
1373
  dir = guardian->move_direction[move];
 
1374
  /* update coordinates */
 
1375
  guard->spr.xcoord += depix[speed][dir];
 
1376
  guard->spr.ycoord += depiy[speed][dir];
 
1377
 
 
1378
  if (guard->spr.xcoord < guardian->x_min - EPS)
 
1379
    {
 
1380
      guard->spr.xcoord = guardian->x_min;
 
1381
      guardian->move_time_delay = 0;
 
1382
      guard->spr.ycoord += guardian->y_inc;
 
1383
    }
 
1384
  if (guard->spr.xcoord + guard->spr.img[guard->spr.current_image]->w >
 
1385
      guardian->x_max + EPS)
 
1386
    {
 
1387
      guard->spr.xcoord =
 
1388
        guardian->x_max - guard->spr.img[guard->spr.current_image]->w;
 
1389
      guardian->move_time_delay = 0;
 
1390
      guard->spr.ycoord += guardian->y_inc;
 
1391
    }
 
1392
  if (guard->spr.ycoord < guardian->y_min - EPS)
 
1393
    {
 
1394
      guard->spr.ycoord = guardian->y_min;
 
1395
      guardian->move_time_delay = 0;
 
1396
    }
 
1397
  if (guard->spr.ycoord + guard->spr.img[guard->spr.current_image]->h >
 
1398
      guardian->y_max + EPS)
 
1399
    {
 
1400
      guard->spr.ycoord =
 
1401
        guardian->y_max - guard->spr.img[guard->spr.current_image]->h;
 
1402
      guardian->move_time_delay = 0;
 
1403
    }
 
1404
}
 
1405
 
 
1406
/**
 
1407
 * Move the guardian follow sinus curve 
 
1408
 */
 
1409
static void
 
1410
guardian_move_sinus (enemy * guard)
 
1411
{
 
1412
  if (player_pause || menu_status != MENU_OFF
 
1413
      || menu_section != NO_SECTION_SELECTED)
 
1414
    {
 
1415
      return;
 
1416
    }
 
1417
 
 
1418
  /* move horizontally the guardian follow a straightline */
 
1419
  guard->spr.xcoord +=
 
1420
    depix[guardian->move_speed[guardian->move_current]][guardian->
 
1421
                                                        move_direction
 
1422
                                                        [guardian->
 
1423
                                                         move_current]];
 
1424
  guard->spr.ycoord += precalc_sin[guardian->move_time_delay & 0x001f] * 4;
 
1425
  if (guard->spr.ycoord > (float) (offscreen_clipsize + 40 + EPS))
 
1426
    {
 
1427
      guard->spr.ycoord = (float) (offscreen_clipsize + 40);
 
1428
    }
 
1429
  if (guard->spr.xcoord < (float) offscreen_clipsize - EPS)
 
1430
    {
 
1431
      guard->spr.xcoord = (float) offscreen_clipsize;
 
1432
      guardian->move_time_delay = 0;
 
1433
    }
 
1434
  if ((guard->spr.xcoord + guard->spr.img[guard->spr.current_image]->w) >
 
1435
      (float) (offscreen_clipsize + offscreen_width_visible + EPS))
 
1436
    {
 
1437
      guard->spr.xcoord =
 
1438
        (float) (offscreen_clipsize + offscreen_width_visible) -
 
1439
        guard->spr.img[guard->spr.current_image]->w;
 
1440
      guardian->move_time_delay = 0;
 
1441
    }
 
1442
}
 
1443
 
 
1444
/**
 
1445
 * Handle the guardian 1 
 
1446
 * @param guard Pointer to the enemy structure of the guardian
 
1447
 */
 
1448
static void
 
1449
guardian_01 (enemy * guard)
 
1450
{
 
1451
  if (guardian->is_appearing)
 
1452
    {
 
1453
      guardian_appears_from_top (guard);
 
1454
    }
 
1455
  else
 
1456
    {
 
1457
      if (--guardian->move_time_delay > 0)
 
1458
        {
 
1459
          if (guardian->move_direction[guardian->move_current] <
 
1460
              GUARD_IMMOBILE)
 
1461
            {
 
1462
              guardian_line_moving (guard);
 
1463
            }
 
1464
          switch (guardian->move_direction[guardian->move_current])
 
1465
            {
 
1466
            case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1467
              guardian_flip_image (guard, 3, 31);
 
1468
              break;
 
1469
 
 
1470
            case GUARD_MOVEMENT_TOWARD_LEFT:
 
1471
              guardian_flip_image (guard, 3, 0);
 
1472
              break;
 
1473
 
 
1474
            case GUARD_IMMOBILE:
 
1475
              guardian_flip_image (guard, 3, 15);
 
1476
              break;
 
1477
            }
 
1478
        }
 
1479
      else
 
1480
        {
 
1481
          guardian_next_trajectory ();
 
1482
        }
 
1483
    }
 
1484
  guardian_fire (guard, 8, 2.0);
 
1485
}
 
1486
 
 
1487
/**
 
1488
 * Handle the guardian 2 
 
1489
 * @param guard Pointer to the enemy structure of the guardian
 
1490
 */
 
1491
static void
 
1492
guardian_02 (enemy * guard)
 
1493
{
 
1494
  if (guardian->is_appearing)
 
1495
    {
 
1496
      guard->spr.ycoord += guard->spr.speed;
 
1497
      if (guard->spr.ycoord >= (float) (offscreen_clipsize - 15))
 
1498
        {
 
1499
          guard->spr.ycoord = (float) (offscreen_clipsize - 15);
 
1500
          guardian->is_appearing = FALSE;
 
1501
          guardian->move_current = 0;
 
1502
          guardian->move_time_delay =
 
1503
            guardian->move_delay[guardian->move_current];
 
1504
        }
 
1505
    }
 
1506
  else
 
1507
    {
 
1508
      /* next trajectory? */
 
1509
      if (--guardian->move_time_delay > 0)
 
1510
        {
 
1511
          if (guardian->move_direction[guardian->move_current] <
 
1512
              GUARD_IMMOBILE && !player_pause && menu_status == MENU_OFF
 
1513
              && menu_section == NO_SECTION_SELECTED)
 
1514
            {
 
1515
              guardian_line_moving (guard);
 
1516
            }
 
1517
          switch (guardian->move_direction[guardian->move_current])
 
1518
            {
 
1519
            case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1520
              if (guardian->has_changed_direction)
 
1521
                {
 
1522
                  guardian_change_images (guard, 0, 15);
 
1523
                  guardian->has_changed_direction = FALSE;
 
1524
                }
 
1525
              guardian_flip_image (guard, 4, 31);
 
1526
              break;
 
1527
 
 
1528
            case GUARD_MOVEMENT_TOWARD_LEFT:
 
1529
              if (guardian->has_changed_direction)
 
1530
                {
 
1531
                  guardian_change_images (guard, 0, 15);
 
1532
                  guardian->has_changed_direction = FALSE;
 
1533
                }
 
1534
              /* flip to the previous image */
 
1535
              guardian_flip_image (guard, 4, 0);
 
1536
              break;
 
1537
 
 
1538
            case GUARD_MOVEMENT_TOWARD_TOP:
 
1539
            case GUARD_MOVEMENT_TOWARD_BOTTOM:
 
1540
              if (guardian->has_changed_direction)
 
1541
                {
 
1542
                  guardian_change_images (guard, 1, 0);
 
1543
                  guardian->has_changed_direction = FALSE;
 
1544
                }
 
1545
              guardian_flip_image (guard, 2, 31);
 
1546
              break;
 
1547
 
 
1548
            case GUARD_IMMOBILE:
 
1549
              if (guardian->has_changed_direction)
 
1550
                {
 
1551
                  guardian->has_changed_direction = FALSE;
 
1552
                  guardian_change_images_set (guard, 0);
 
1553
                  if (guardian->is_vertical_trajectory)
 
1554
                    {
 
1555
                      guard->spr.current_image = 15;
 
1556
                      guardian->is_vertical_trajectory = FALSE;
 
1557
                    }
 
1558
                }
 
1559
              /* set image's guardian of central position */
 
1560
              guardian_flip_image (guard, 3, 15);
 
1561
              break;
 
1562
            }
 
1563
        }
 
1564
      else
 
1565
        {
 
1566
          if (guardian->move_direction[guardian->move_current] ==
 
1567
              GUARD_MOVEMENT_TOWARD_BOTTOM
 
1568
              || guardian->move_direction[guardian->move_current] ==
 
1569
              GUARD_MOVEMENT_TOWARD_TOP)
 
1570
            {
 
1571
              guardian->is_vertical_trajectory = TRUE;
 
1572
            }
 
1573
          guardian_next_trajectory ();
 
1574
        }
 
1575
    }
 
1576
  if (guardian_fire (guard, 10, 3.0) > 0)
 
1577
    {
 
1578
      guardian_add_shuriky (guard, 4);
 
1579
    }
 
1580
}
 
1581
 
 
1582
/**
 
1583
 * Handle the guardian 3 
 
1584
 * @param guard Pointer to the enemy structure of the guardian
 
1585
 */
 
1586
static void
 
1587
guardian_03 (enemy * guard)
 
1588
{
 
1589
  if (guardian->is_appearing)
 
1590
    {
 
1591
      guardian_appears_from_top (guard);
 
1592
    }
 
1593
  else
 
1594
    {
 
1595
      if (--guardian->move_time_delay > 0)
 
1596
        {
 
1597
          if (guardian->move_direction[guardian->move_current] <
 
1598
              GUARD_IMMOBILE)
 
1599
            {
 
1600
              guardian_line_moving (guard);
 
1601
            }
 
1602
          switch (guardian->move_direction[guardian->move_current])
 
1603
            {
 
1604
            case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1605
            case GUARD_MOVEMENT_TOWARD_LEFT:
 
1606
            case GUARD_IMMOBILE:
 
1607
              guardian_loop_flip (guard, 3, 1, 31, 0);
 
1608
              break;
 
1609
            }
 
1610
        }
 
1611
      else
 
1612
        {
 
1613
          guardian_next_trajectory ();
 
1614
        }
 
1615
    }
 
1616
  if (guardian_fire (guard, 8, 2.0) > 0)
 
1617
    {
 
1618
      guardian_add_lonely_foe (16, NAGGYS);
 
1619
    }
 
1620
}
 
1621
 
 
1622
/**
 
1623
 * Handle the guardian 4 
 
1624
 * @param guard Pointer to the enemy structure of the guardian
 
1625
 */
 
1626
static void
 
1627
guardian_04 (enemy * guard)
 
1628
{
 
1629
  if (guardian->is_appearing)
 
1630
    {
 
1631
      guardian_appears_from_top (guard);
 
1632
    }
 
1633
  else
 
1634
    {
 
1635
      guardian_add_devilians (guard, 141, 3);
 
1636
      if (--guardian->move_time_delay > 0)
 
1637
        {
 
1638
          if (guardian->move_direction[guardian->move_current] ==
 
1639
              GUARD_MOVEMENT_TOWARD_RIGHT
 
1640
              || guardian->move_direction[guardian->move_current] ==
 
1641
              GUARD_MOVEMENT_TOWARD_LEFT)
 
1642
            {
 
1643
              guardian_line_moving (guard);
 
1644
            }
 
1645
          switch (guardian->move_direction[guardian->move_current])
 
1646
            {
 
1647
            case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1648
              if (guardian->has_changed_direction)
 
1649
                {
 
1650
                  guardian->has_changed_direction = FALSE;
 
1651
                  guardian_change_images (guard, 0, 15);
 
1652
                }
 
1653
              guardian_flip_image (guard, 4, 31);
 
1654
              break;
 
1655
 
 
1656
            case GUARD_MOVEMENT_TOWARD_LEFT:
 
1657
              if (guardian->has_changed_direction)
 
1658
                {
 
1659
                  guardian->has_changed_direction = FALSE;
 
1660
                  guardian_change_images (guard, 0, 15);
 
1661
                }
 
1662
              guardian_flip_image (guard, 4, 0);
 
1663
              break;
 
1664
 
 
1665
            case GUARD_MOVEMENT_TOWARD_BOTTOM:
 
1666
              if (guardian->has_changed_direction)
 
1667
                {
 
1668
                  guardian->has_changed_direction = FALSE;
 
1669
                  guardian_change_images (guard, 1, 0);
 
1670
                  guardian->devilians_enable = TRUE;
 
1671
                  guardian->devilians_counter = 0;
 
1672
                }
 
1673
              guardian_flip_image (guard, 2, 31);
 
1674
              break;
 
1675
 
 
1676
            case GUARD_MOVEMENT_TOWARD_TOP:
 
1677
              guardian_flip_image (guard, 2, 0);
 
1678
              break;
 
1679
 
 
1680
            case GUARD_IMMOBILE:
 
1681
              if (guardian->has_changed_direction)
 
1682
                {
 
1683
                  guardian->has_changed_direction = FALSE;
 
1684
                  guardian_change_images_set (guard, 0);
 
1685
                  if (guardian->is_vertical_trajectory)
 
1686
                    {
 
1687
                      guard->spr.current_image = 15;
 
1688
                      guardian->is_vertical_trajectory = FALSE;
 
1689
                    }
 
1690
                }
 
1691
              guardian_flip_image (guard, 3, 15);
 
1692
              break;
 
1693
            }
 
1694
        }
 
1695
      else
 
1696
        {
 
1697
          if (guardian->move_direction[guardian->move_current] ==
 
1698
              GUARD_MOVEMENT_TOWARD_BOTTOM
 
1699
              || guardian->move_direction[guardian->move_current] ==
 
1700
              GUARD_MOVEMENT_TOWARD_TOP)
 
1701
            {
 
1702
              guardian->is_vertical_trajectory = TRUE;
 
1703
            }
 
1704
          guardian_next_trajectory ();
 
1705
        }
 
1706
    }
 
1707
  if (guardian_fire (guard, 8, 2.0) > 0)
 
1708
    {
 
1709
      guardian_add_lonely_foe (8, SAPOUCH);
 
1710
    }
 
1711
}
 
1712
 
 
1713
/**
 
1714
 * Handle the guardian 5
 
1715
 * @param guard Pointer to the enemy structure of the guardian
 
1716
 */
 
1717
static void
 
1718
guardian_05 (enemy * guard)
 
1719
{
 
1720
  Uint32 numof_bullets;
 
1721
  if (guardian->is_appearing)
 
1722
    {
 
1723
      guardian_appears_from_top (guard);
 
1724
    }
 
1725
  else
 
1726
    {
 
1727
      if (!player_pause && menu_status == MENU_OFF
 
1728
          && menu_section == NO_SECTION_SELECTED)
 
1729
        {
 
1730
          if (--guardian->move_time_delay > 0)
 
1731
            {
 
1732
              if (guardian->move_direction[guardian->move_current] ==
 
1733
                  GUARD_MOVEMENT_TOWARD_RIGHT
 
1734
                  || guardian->move_direction[guardian->move_current] ==
 
1735
                  GUARD_MOVEMENT_TOWARD_LEFT)
 
1736
                {
 
1737
                  guardian_move_sinus (guard);
 
1738
                }
 
1739
              switch (guardian->move_direction[guardian->move_current])
 
1740
                {
 
1741
                case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1742
                  if (guardian->has_changed_direction)
 
1743
                    {
 
1744
                      guardian->has_changed_direction = FALSE;
 
1745
                      guardian_change_images (guard, 0, 15);
 
1746
                    }
 
1747
                  guardian_flip_image (guard, 4, 31);
 
1748
                  break;
 
1749
 
 
1750
                case GUARD_MOVEMENT_TOWARD_LEFT:
 
1751
                  if (guardian->has_changed_direction)
 
1752
                    {
 
1753
                      guardian->has_changed_direction = FALSE;
 
1754
                      guardian_change_images (guard, 0, 15);
 
1755
                    }
 
1756
                  guardian_flip_image (guard, 4, 0);
 
1757
                  break;
 
1758
 
 
1759
                case GUARD_MOVEMENT_TOWARD_BOTTOM:
 
1760
                  if (guardian->has_changed_direction)
 
1761
                    {
 
1762
                      guardian->has_changed_direction = FALSE;
 
1763
                      guardian_change_images (guard, 1, 0);
 
1764
                    }
 
1765
                  guardian_loop_flip (guard, 2, 1, 31, 0);
 
1766
                  break;
 
1767
 
 
1768
                case GUARD_IMMOBILE:
 
1769
                  if (guardian->has_changed_direction)
 
1770
                    {
 
1771
                      guardian->has_changed_direction = FALSE;
 
1772
                      guardian_change_images_set (guard, 0);
 
1773
                      if (guardian->is_vertical_trajectory)
 
1774
                        {
 
1775
                          guard->spr.current_image = 15;
 
1776
                          guardian->is_vertical_trajectory = FALSE;
 
1777
                        }
 
1778
                    }
 
1779
                  guardian_flip_image (guard, 3, 15);
 
1780
                  break;
 
1781
                }
 
1782
            }
 
1783
          else
 
1784
            {
 
1785
              if (guardian->move_direction[guardian->move_current] ==
 
1786
                  GUARD_MOVEMENT_TOWARD_BOTTOM
 
1787
                  || guardian->move_direction[guardian->move_current] ==
 
1788
                  GUARD_MOVEMENT_TOWARD_TOP)
 
1789
                {
 
1790
                  guardian->is_vertical_trajectory = TRUE;
 
1791
                }
 
1792
              guardian_next_trajectory ();
 
1793
            }
 
1794
        }
 
1795
    }
 
1796
 
 
1797
  numof_bullets = guardian_fire (guard, 8, 2.0);
 
1798
  guardian_add_soukee (guard, numof_bullets, 16);
 
1799
}
 
1800
 
 
1801
/**
 
1802
 * Handle the guardian 6
 
1803
 * Guardian with a articulated arm (2 sprites used)
 
1804
 * @param guard Pointer to the enemy structure of the guardian
 
1805
 */
 
1806
static void
 
1807
guardian_06 (enemy * guard)
 
1808
{
 
1809
  Uint32 numof_bullets;
 
1810
  if (guardian->is_appearing)
 
1811
    {
 
1812
      if (guard == guardian->enemy[0])
 
1813
        {
 
1814
          guardian_appears_from_top (guard);
 
1815
          guardian->enemy[1]->spr.xcoord = guard->spr.xcoord;
 
1816
          guardian->enemy[1]->spr.ycoord = guard->spr.ycoord + 63;
 
1817
        }
 
1818
    }
 
1819
  else
 
1820
    {
 
1821
      if (!player_pause && menu_status == MENU_OFF
 
1822
          && guard == guardian->enemy[0]
 
1823
          && menu_section == NO_SECTION_SELECTED)
 
1824
        {
 
1825
          guardian->move_time_delay--;
 
1826
          if (guardian->move_time_delay > 0)
 
1827
            {
 
1828
              if (guardian->move_direction[guardian->move_current] <
 
1829
                  GUARD_IMMOBILE)
 
1830
                {
 
1831
                  guardian_line_moving (guard);
 
1832
                }
 
1833
              switch (guardian->move_direction[guardian->move_current])
 
1834
                {
 
1835
                case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1836
                  if (guardian->has_changed_direction)
 
1837
                    {
 
1838
                      guardian->has_changed_direction = FALSE;
 
1839
                      guardian_change_images (guard, 0, 15);
 
1840
                    }
 
1841
                  guardian_flip_image (guard, 4, 31);
 
1842
                  break;
 
1843
 
 
1844
                case GUARD_MOVEMENT_TOWARD_LEFT:
 
1845
                  if (guardian->has_changed_direction)
 
1846
                    {
 
1847
                      guardian->has_changed_direction = FALSE;
 
1848
                      guardian_change_images (guard, 0, 15);
 
1849
                    }
 
1850
                  guardian_flip_image (guard, 4, 0);
 
1851
                  break;
 
1852
 
 
1853
                case GUARD_IMMOBILE:
 
1854
                  if (guardian->has_changed_direction)
 
1855
                    {
 
1856
                      guardian->has_changed_direction = FALSE;
 
1857
                      guardian_change_images_set (guard, 0);
 
1858
                      if (guardian->is_vertical_trajectory)
 
1859
                        {
 
1860
                          guard->spr.current_image = 15;
 
1861
                          guardian->is_vertical_trajectory = FALSE;
 
1862
                        }
 
1863
                    }
 
1864
                  guardian_flip_image (guard, 3, 15);
 
1865
                  break;
 
1866
                }
 
1867
            }
 
1868
          else
 
1869
            {
 
1870
              guardian_next_trajectory ();
 
1871
            }
 
1872
        }
 
1873
      /* articulated arm enable? */
 
1874
      if (guard == guardian->enemy[1]
 
1875
          && guard->displacement == DISPLACEMENT_GUARDIAN
 
1876
          && guard->is_enabled)
 
1877
        {
 
1878
          guard->spr.xcoord = guardian->enemy[0]->spr.xcoord;
 
1879
          guard->spr.ycoord = guardian->enemy[0]->spr.ycoord + 63;
 
1880
          guard->spr.anim_count++;
 
1881
          if (!(guard->spr.anim_count &= (guard->spr.anim_speed - 1)))
 
1882
            {
 
1883
              guard->spr.current_image++;
 
1884
              guard->spr.current_image &= 31;
 
1885
            }
 
1886
        }
 
1887
    }
 
1888
  numof_bullets = guardian_fire (guard, 8, 2.0);
 
1889
  guardian_add_missiles (guard, numof_bullets, 8, 2);
 
1890
}
 
1891
 
 
1892
/**
 
1893
 * Handle the guardian 7
 
1894
 * wheel with double reverse rotation
 
1895
 * @param guard Pointer to the enemy structure of the guardian
 
1896
 */
 
1897
static void
 
1898
guardian_07 (enemy * guard)
 
1899
{
 
1900
  if (guardian->is_appearing)
 
1901
    {
 
1902
      guardian_appears_from_top (guard);
 
1903
    }
 
1904
  else
 
1905
    {
 
1906
      if (--guardian->move_time_delay > 0)
 
1907
        {
 
1908
          if (guardian->move_direction[guardian->move_current] <
 
1909
              GUARD_IMMOBILE)
 
1910
            {
 
1911
              guardian_line_moving (guard);
 
1912
            }
 
1913
          switch (guardian->move_direction[guardian->move_current])
 
1914
            {
 
1915
            case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1916
            case GUARD_MOVEMENT_TOWARD_LEFT:
 
1917
            case GUARD_IMMOBILE:
 
1918
              guardian_loop_flip (guard, 3, 1, 31, 0);
 
1919
              break;
 
1920
            }
 
1921
        }
 
1922
      else
 
1923
        {
 
1924
          guardian_next_trajectory ();
 
1925
        }
 
1926
    }
 
1927
  if (guardian_fire (guard, 8, 2.0) > 0)
 
1928
    {
 
1929
      guardian_add_lonely_foe (50, -1);
 
1930
      guardian_add_quibouly (guard, 6);
 
1931
    }
 
1932
}
 
1933
 
 
1934
/**
 
1935
 * Handle the guardian 8
 
1936
 * @param guard Pointer to the enemy structure of the guardian
 
1937
 */
 
1938
static void
 
1939
guardian_08 (enemy * guard)
 
1940
{
 
1941
  if (guardian->is_appearing)
 
1942
    {
 
1943
      guardian_appears_from_top (guard);
 
1944
    }
 
1945
  else
 
1946
    {
 
1947
      if (--guardian->move_time_delay > 0)
 
1948
        {
 
1949
          if (guardian->move_direction[guardian->move_current] <
 
1950
              GUARD_IMMOBILE)
 
1951
            {
 
1952
              guardian_line_moving (guard);
 
1953
            }
 
1954
          switch (guardian->move_direction[guardian->move_current])
 
1955
            {
 
1956
            case GUARD_MOVEMENT_TOWARD_RIGHT:
 
1957
            case GUARD_MOVEMENT_TOWARD_LEFT:
 
1958
            case GUARD_IMMOBILE:
 
1959
              guardian_loop_flip (guard, 3, 1, 31, 0);
 
1960
              break;
 
1961
            }
 
1962
        }
 
1963
      else
 
1964
        {
 
1965
          guardian_next_trajectory ();
 
1966
        }
 
1967
    }
 
1968
  if (guardian_fire (guard, 8, 2.0) > 0)
 
1969
    {
 
1970
      guardian_add_lonely_foe (40, -1);
 
1971
      guardian_add_tournadee (guard, 12);
 
1972
    }
 
1973
}
 
1974
 
 
1975
/**
 
1976
 * Handle the guardian 9
 
1977
 * Aircraft with rotary nose (2 sprites)
 
1978
 * @param guard Pointer to the enemy structure of the guardian
 
1979
 */
 
1980
static void
 
1981
guardian_09 (enemy * guard)
 
1982
{
 
1983
  if (guardian->is_appearing)
 
1984
    {
 
1985
      if (guard == guardian->enemy[0])
 
1986
        {
 
1987
          guardian_appears_from_top (guard);
 
1988
          guardian->enemy[1]->spr.xcoord = guard->spr.xcoord;
 
1989
          guardian->enemy[1]->spr.ycoord = guard->spr.ycoord;
 
1990
        }
 
1991
    }
 
1992
  else
 
1993
    {
 
1994
      if (!player_pause && menu_status == MENU_OFF
 
1995
          && guard == guardian->enemy[0]
 
1996
          && menu_section == NO_SECTION_SELECTED)
 
1997
        {
 
1998
          if (--guardian->move_time_delay > 0)
 
1999
            {
 
2000
              if (guardian->move_direction[guardian->move_current] <
 
2001
                  GUARD_IMMOBILE)
 
2002
                {
 
2003
                  guardian_line_moving (guard);
 
2004
                }
 
2005
              switch (guardian->move_direction[guardian->move_current])
 
2006
                {
 
2007
                case GUARD_MOVEMENT_TOWARD_RIGHT:
 
2008
                  if (guardian->has_changed_direction)
 
2009
                    {
 
2010
                      guardian->has_changed_direction = FALSE;
 
2011
                      guardian_change_images (guard, 0, 15);
 
2012
                    }
 
2013
                  guardian_flip_image (guard, 4, 31);
 
2014
                  break;
 
2015
 
 
2016
                case GUARD_MOVEMENT_TOWARD_LEFT:
 
2017
                  if (guardian->has_changed_direction)
 
2018
                    {
 
2019
                      guardian->has_changed_direction = FALSE;
 
2020
                      guardian_change_images (guard, 0, 15);
 
2021
                    }
 
2022
                  guardian_flip_image (guard, 4, 0);
 
2023
                  break;
 
2024
 
 
2025
                case GUARD_IMMOBILE:
 
2026
                  if (guardian->has_changed_direction)
 
2027
                    {
 
2028
                      guardian->has_changed_direction = FALSE;
 
2029
                      guardian_change_images_set (guard, 0);
 
2030
                      /* check if one were previously on a vertical trajectory 
 
2031
                       * so set the fair image */
 
2032
                      if (guardian->is_vertical_trajectory)
 
2033
                        {
 
2034
                          guard->spr.current_image = 15;
 
2035
                          guardian->is_vertical_trajectory = FALSE;
 
2036
                        }
 
2037
                    }
 
2038
                  guardian_flip_image (guard, 3, 15);
 
2039
                  break;
 
2040
                }
 
2041
            }
 
2042
          else
 
2043
            {
 
2044
              guardian_next_trajectory ();
 
2045
            }
 
2046
        }
 
2047
 
 
2048
      if (guard == guardian->enemy[1]
 
2049
          && guard->displacement == DISPLACEMENT_GUARDIAN
 
2050
          && guard->is_enabled)
 
2051
        {
 
2052
          guard->spr.xcoord = guardian->enemy[0]->spr.xcoord;
 
2053
          guard->spr.ycoord = guardian->enemy[0]->spr.ycoord;
 
2054
          guard->spr.anim_count++;
 
2055
          if (!(guard->spr.anim_count &= (guard->spr.anim_speed - 1)))
 
2056
            {
 
2057
              guard->spr.current_image++;
 
2058
            }
 
2059
          guard->spr.current_image &= 31;
 
2060
        }
 
2061
    }
 
2062
  if (guardian_fire (guard, 8, 2.0) > 0)
 
2063
    {
 
2064
      guardian_add_lonely_foe (40, -1);
 
2065
    }
 
2066
}
 
2067
 
 
2068
/**
 
2069
 * Handle the guardian 10 
 
2070
 * Disk with a big adjustable canon 
 
2071
 * @param guard Pointer to the enemy structure of the guardian
 
2072
 */
 
2073
static void
 
2074
guardian_10 (enemy * guard)
 
2075
{
 
2076
  float angle;
 
2077
  Uint32 i;
 
2078
  Sint32 anim_count, length1, length2;
 
2079
  enemy *guard2 = guardian->enemy[1];
 
2080
  spaceship_struct *ship = spaceship_get ();
 
2081
  if (guardian->is_appearing)
 
2082
    {
 
2083
      if (guard == guardian->enemy[0])
 
2084
        {
 
2085
          guardian_appears_from_top (guard);
 
2086
          guardian->enemy[1]->spr.xcoord = guard->spr.xcoord;
 
2087
          guardian->enemy[1]->spr.ycoord = guard->spr.ycoord;
 
2088
        }
 
2089
    }
 
2090
  else
 
2091
    {
 
2092
      if (!player_pause && menu_status == MENU_OFF
 
2093
          && guard == guardian->enemy[0]
 
2094
          && menu_section == NO_SECTION_SELECTED)
 
2095
        {
 
2096
          if (guardian->move_current == GUARD_MOVEMENT_TOWARD_RIGHT)
 
2097
            {
 
2098
              guard->spr.xcoord++;
 
2099
            }
 
2100
          if (guardian->move_current == GUARD_MOVEMENT_TOWARD_BOTTOM)
 
2101
            {
 
2102
              guard->spr.ycoord++;
 
2103
            }
 
2104
          if (guardian->move_current == GUARD_MOVEMENT_TOWARD_LEFT)
 
2105
            {
 
2106
              guard->spr.xcoord--;
 
2107
            }
 
2108
          if (guardian->move_current == GUARD_MOVEMENT_TOWARD_TOP)
 
2109
            {
 
2110
              guard->spr.ycoord--;
 
2111
            }
 
2112
          if (guard->spr.xcoord < (float) offscreen_clipsize - clip_gard10)
 
2113
            {
 
2114
              guard->spr.xcoord = (float) (offscreen_clipsize - clip_gard10);
 
2115
              guardian->move_current = GUARD_MOVEMENT_TOWARD_TOP;
 
2116
            }
 
2117
          if ((guard->spr.xcoord +
 
2118
               guard->spr.img[guard->spr.current_image]->w) >
 
2119
              (float) (offscreen_clipsize + offscreen_width_visible +
 
2120
                       clip_gard10))
 
2121
            {
 
2122
              guard->spr.xcoord =
 
2123
                (float) (offscreen_clipsize + offscreen_width_visible +
 
2124
                         clip_gard10) -
 
2125
                guard->spr.img[guard->spr.current_image]->w;
 
2126
              guardian->move_current = GUARD_MOVEMENT_TOWARD_BOTTOM;
 
2127
            }
 
2128
          if (guard->spr.ycoord < (float) offscreen_clipsize - clip_gard10)
 
2129
            {
 
2130
              guard->spr.ycoord = (float) (offscreen_clipsize - clip_gard10);
 
2131
              guardian->move_current = GUARD_MOVEMENT_TOWARD_RIGHT;
 
2132
            }
 
2133
          if ((guard->spr.ycoord +
 
2134
               guard->spr.img[guard->spr.current_image]->h) >
 
2135
              (float) (offscreen_clipsize + offscreen_height_visible +
 
2136
                       clip_gard10))
 
2137
            {
 
2138
              guard->spr.ycoord =
 
2139
                (float) (offscreen_clipsize + offscreen_height_visible +
 
2140
                         clip_gard10) -
 
2141
                guard->spr.img[guard->spr.current_image]->h;
 
2142
              guardian->move_current = GUARD_MOVEMENT_TOWARD_LEFT;
 
2143
            }
 
2144
        }
 
2145
 
 
2146
      if (guard == guardian->enemy[0])
 
2147
        {
 
2148
          guard->spr.anim_count++;
 
2149
          if (guard->spr.anim_count >= guard->spr.anim_speed)
 
2150
            {
 
2151
              guard->spr.anim_count = 0;
 
2152
              guard->spr.current_image++;
 
2153
              if (guard->spr.current_image > 31)
 
2154
                {
 
2155
                  guard->spr.current_image = 0;
 
2156
                }
 
2157
            }
 
2158
        }
 
2159
 
 
2160
      /* check if second part of the guardian existing */
 
2161
      if (guard2->displacement == DISPLACEMENT_GUARDIAN)
 
2162
        {
 
2163
          guard2->spr.xcoord = guardian->enemy[0]->spr.xcoord;
 
2164
          guard2->spr.ycoord = guardian->enemy[0]->spr.ycoord;
 
2165
          /* cannon rotation to follow the player's spaceship */
 
2166
          if (guard2->img_angle != guard2->spr.current_image)
 
2167
            {
 
2168
              if (guard2->sens_anim)
 
2169
                {
 
2170
                  guard2->spr.anim_count++;
 
2171
                  if (guard2->spr.anim_count >= guard2->spr.anim_speed)
 
2172
                    {
 
2173
                      guard2->spr.anim_count = 0;
 
2174
                      guard2->spr.current_image--;
 
2175
                      if (guard2->spr.current_image < 0)
 
2176
                        {
 
2177
                          guard2->spr.current_image =
 
2178
                            (Sint16) (guard2->spr.numof_images - 1);
 
2179
                        }
 
2180
                    }
 
2181
                }
 
2182
              else
 
2183
                {
 
2184
                  guard2->spr.anim_count++;
 
2185
                  if (guard2->spr.anim_count >= guard2->spr.anim_speed)
 
2186
                    {
 
2187
                      guard2->spr.anim_count = 0;
 
2188
                      guard2->spr.current_image++;
 
2189
                      if (guard2->spr.current_image >=
 
2190
                          guard2->spr.numof_images)
 
2191
                        {
 
2192
                          guard2->spr.current_image = 0;
 
2193
                        }
 
2194
                    }
 
2195
                }
 
2196
              /* count length in the oposite trigonometrical direction */
 
2197
              anim_count = guard2->spr.current_image;
 
2198
              length1 = 0;
 
2199
              for (i = 0; i < 32; i++)
 
2200
                {
 
2201
                  length1++;
 
2202
                  anim_count++;
 
2203
                  if (anim_count > 31)
 
2204
                    {
 
2205
                      anim_count = 0;
 
2206
                    }
 
2207
                  if (guard2->img_angle == anim_count)
 
2208
                    {
 
2209
                      i = 32;
 
2210
                    }
 
2211
                }
 
2212
              /* count length in the trigonometrical direction */
 
2213
              anim_count = guard2->spr.current_image;
 
2214
              length2 = 0;
 
2215
              for (i = 0; i < 32; i++)
 
2216
                {
 
2217
                  length2++;
 
2218
                  anim_count--;
 
2219
                  if (anim_count < 0)
 
2220
                    {
 
2221
                      anim_count = 31;
 
2222
                    }
 
2223
                  if (guard2->img_angle == anim_count)
 
2224
                    {
 
2225
                      i = 32;
 
2226
                    }
 
2227
                }
 
2228
              if (length1 < length2)
 
2229
                {
 
2230
                  guard2->sens_anim = 0;
 
2231
                }
 
2232
              else
 
2233
                {
 
2234
                  guard2->sens_anim = 1;
 
2235
                }
 
2236
            }
 
2237
          /* search cannon position compared to the direction of spaceship  */
 
2238
          angle =
 
2239
            calc_target_angle ((Sint16)
 
2240
                               (guard2->spr.xcoord +
 
2241
                                guard2->spr.img[guard2->spr.current_image]->
 
2242
                                x_gc),
 
2243
                               (Sint16) (guard2->spr.ycoord +
 
2244
                                         guard2->spr.img[guard2->spr.
 
2245
                                                         current_image]->
 
2246
                                         y_gc),
 
2247
                               (Sint16) (ship->spr.xcoord +
 
2248
                                         ship->spr.img[ship->spr.
 
2249
                                                       current_image]->x_gc),
 
2250
                               (Sint16) (ship->spr.ycoord +
 
2251
                                         ship->spr.img[ship->spr.
 
2252
                                                       current_image]->y_gc));
 
2253
          /* search image to draw determined upon angle */
 
2254
          if (sign (angle < 0))
 
2255
            {
 
2256
              guard2->img_angle = (Sint16) ((angle + DEUX_PI) / PI_SUR_16);
 
2257
            }
 
2258
          else
 
2259
            {
 
2260
              guard2->img_angle = (Sint16) (angle / PI_SUR_16);
 
2261
            }
 
2262
          /* avoid a negative table index */
 
2263
          guard2->img_angle = (Sint16) abs (guard2->img_angle);
 
2264
          /* avoid shot angle higher than the number of images of the sprite */
 
2265
          if (guard2->img_angle >= guard2->spr.numof_images)
 
2266
            {
 
2267
              guard2->img_angle = (Sint16) (guard2->spr.numof_images - 1);
 
2268
            }
 
2269
 
 
2270
        }
 
2271
    }
 
2272
  if (guardian_fire (guard, 8, 2.0) > 0)
 
2273
    {
 
2274
      guardian_add_lonely_foe (40, -1);
 
2275
    }
 
2276
}
 
2277
 
 
2278
/**
 
2279
 * Handle the guardian 11 
 
2280
 * @param guard Pointer to the enemy structure of the guardian
 
2281
 */
 
2282
static void
 
2283
guardian_11 (enemy * guard)
 
2284
{
 
2285
  Uint32 numof_bullets;
 
2286
  if (guardian->is_appearing)
 
2287
    {
 
2288
      guardian_appears_from_top (guard);
 
2289
    }
 
2290
  else
 
2291
    {
 
2292
      if (!player_pause && menu_status == MENU_OFF
 
2293
          && menu_section == NO_SECTION_SELECTED)
 
2294
        {
 
2295
          if (--guardian->move_time_delay > 0)
 
2296
            {
 
2297
              if (guardian->move_direction[guardian->move_current] <
 
2298
                  GUARD_IMMOBILE)
 
2299
                {
 
2300
                  guardian_line_moving (guard);
 
2301
                }
 
2302
              switch (guardian->move_direction[guardian->move_current])
 
2303
                {
 
2304
                case GUARD_MOVEMENT_TOWARD_RIGHT:
 
2305
                  if (guardian->has_changed_direction)
 
2306
                    {
 
2307
                      guardian_change_images (guard, 0, 15);
 
2308
                      guardian->has_changed_direction = FALSE;
 
2309
                    }
 
2310
                  guardian_flip_image (guard, 4, 31);
 
2311
                  break;
 
2312
 
 
2313
                case GUARD_MOVEMENT_TOWARD_LEFT:
 
2314
                  if (guardian->has_changed_direction)
 
2315
                    {
 
2316
                      guardian->has_changed_direction = FALSE;
 
2317
                      guardian_change_images (guard, 0, 15);
 
2318
                    }
 
2319
                  guardian_flip_image (guard, 4, 0);
 
2320
                  break;
 
2321
 
 
2322
                case GUARD_IMMOBILE:
 
2323
                  if (guardian->has_changed_direction)
 
2324
                    {
 
2325
                      guardian->has_changed_direction = FALSE;
 
2326
                      guardian_change_images_set (guard, 0);
 
2327
                      if (guardian->is_vertical_trajectory)
 
2328
                        {
 
2329
                          guard->spr.current_image = 15;
 
2330
                          guardian->is_vertical_trajectory = FALSE;
 
2331
                        }
 
2332
                    }
 
2333
                  guardian_flip_image (guard, 3, 15);
 
2334
                  break;
 
2335
                }
 
2336
            }
 
2337
          else
 
2338
            {
 
2339
              guardian_next_trajectory ();
 
2340
            }
 
2341
        }
 
2342
    }
 
2343
  numof_bullets = guardian_fire (guard, 8, 2.0);
 
2344
  guardian_add_missiles (guard, numof_bullets, 8, 2);
 
2345
}
 
2346
 
 
2347
/**
 
2348
 * Handle the guardian 12 
 
2349
 * @param guard Pointer to the enemy structure of the guardian
 
2350
 */
 
2351
static void
 
2352
guardian_12 (enemy * guard)
 
2353
{
 
2354
  Uint32 numof_bullets;
 
2355
  bool add_shuriky = FALSE;
 
2356
  bool add_missiles = FALSE;
 
2357
  if (guardian->is_appearing)
 
2358
    {
 
2359
      guardian_appears_from_top (guard);
 
2360
    }
 
2361
  else
 
2362
    {
 
2363
      if (!player_pause && menu_status == MENU_OFF
 
2364
          && menu_section == NO_SECTION_SELECTED)
 
2365
        {
 
2366
          if (--guardian->move_time_delay > 0)
 
2367
            {
 
2368
              switch (guardian->move_direction[guardian->move_current])
 
2369
                {
 
2370
                case GUARD_MOVEMENT_TOWARD_RIGHT:
 
2371
                  guardian_line_moving (guard);
 
2372
                  guardian_flip_image (guard, 4, 31);
 
2373
                  add_shuriky = TRUE;
 
2374
                  break;
 
2375
 
 
2376
                case GUARD_MOVEMENT_TOWARD_LEFT:
 
2377
                  guardian_line_moving (guard);
 
2378
                  guardian_flip_image (guard, 4, 0);
 
2379
                  add_shuriky = TRUE;
 
2380
                  break;
 
2381
 
 
2382
                case GUARD_MOVEMENT_TOWARD_BOTTOM:
 
2383
                  guardian->is_vertical_trajectory = TRUE;
 
2384
                  /* from  8 to 14: bottom to up
 
2385
                   * from 15 to 31: up to bottom */
 
2386
                  guardian_flip_image (guard, 3, 31);
 
2387
                  if (guard->spr.current_image >= 15)
 
2388
                    {
 
2389
                      guardian_line_moving (guard);
 
2390
                    }
 
2391
                  break;
 
2392
 
 
2393
                case GUARD_MOVEMENT_TOWARD_TOP:
 
2394
                  guardian_line_moving (guard);
 
2395
                  guardian_flip_image (guard, 2, 31);
 
2396
                  break;
 
2397
 
 
2398
                case GUARD_IMMOBILE:
 
2399
                  if (guardian->current_images_set == 0)
 
2400
                    {
 
2401
                      add_shuriky = TRUE;
 
2402
                      if (guard->spr.current_image != 15)
 
2403
                        {
 
2404
                          guardian_flip_image (guard, 3, 15);
 
2405
                        }
 
2406
                      else if (guardian_get_next_trajectory () ==
 
2407
                               GUARD_MOVEMENT_TOWARD_BOTTOM)
 
2408
                        {
 
2409
                          guardian_change_images (guard, 1, 0);
 
2410
                        }
 
2411
                      else if (guardian_get_next_trajectory () ==
 
2412
                               GUARD_MOVEMENT_TOWARD_LEFT)
 
2413
                        {
 
2414
                          guardian_add_sapouch (guard, 2, 80, TRUE);
 
2415
                        }
 
2416
                    }
 
2417
                  else
 
2418
                    {
 
2419
                      if (guardian->is_vertical_trajectory)
 
2420
                        {
 
2421
                          if (guard->spr.current_image < 31)
 
2422
                            {
 
2423
                              guardian_flip_image (guard, 3, 31);
 
2424
                            }
 
2425
                          else
 
2426
                            {
 
2427
                              guardian_change_images (guard, 0, 15);
 
2428
                              guardian->is_vertical_trajectory = FALSE;
 
2429
                            }
 
2430
                        }
 
2431
                      else
 
2432
                        {
 
2433
                          /* lamps of the guardian wink */
 
2434
                          /*  image from O to 7 */
 
2435
                          guardian_loop_flip (guard, 1, 1, 7, 0);
 
2436
                          add_missiles = TRUE;
 
2437
                        }
 
2438
                    }
 
2439
                }
 
2440
              if (guardian->has_changed_direction)
 
2441
                {
 
2442
                  guardian->has_changed_direction = FALSE;
 
2443
                }
 
2444
            }
 
2445
          else
 
2446
            {
 
2447
              guardian_next_trajectory ();
 
2448
            }
 
2449
 
 
2450
          numof_bullets = guardian_fire (guard, 8, 2.0);
 
2451
          if (numof_bullets > 0)
 
2452
            {
 
2453
              if (add_shuriky)
 
2454
                {
 
2455
                  guardian_add_shuriky (guard, 6);
 
2456
                }
 
2457
              if (add_missiles)
 
2458
                {
 
2459
                  guardian_add_missiles (guard, numof_bullets, 24, 4);
 
2460
                }
 
2461
            }
 
2462
        }
 
2463
    }
 
2464
}
 
2465
 
 
2466
/**
 
2467
 * Handle the guardian 13
 
2468
 * @param guard Pointer to the enemy structure of the guardian
 
2469
 */
 
2470
static void
 
2471
guardian_13 (enemy * guard)
 
2472
{
 
2473
  bool add_missiles = FALSE;
 
2474
  Uint32 numof_bullets;
 
2475
  if (guardian->is_appearing)
 
2476
    {
 
2477
      guardian_appears_from_top (guard);
 
2478
    }
 
2479
  else
 
2480
    {
 
2481
      if (!player_pause && menu_status == MENU_OFF
 
2482
          && menu_section == NO_SECTION_SELECTED)
 
2483
        {
 
2484
          if (--guardian->move_time_delay > 0)
 
2485
            {
 
2486
              guardian_add_devilians (guard, 121, 3);
 
2487
              if (guardian->move_direction[guardian->move_current] <
 
2488
                  GUARD_IMMOBILE)
 
2489
                {
 
2490
                  guardian_line_moving (guard);
 
2491
                }
 
2492
 
 
2493
              if (guardian->current_images_set == 0)
 
2494
                {
 
2495
                  /* change sprite if level of the life of the guardian is has its half */
 
2496
                  if (guard->spr.energy_level <=
 
2497
                      guard->spr.max_energy_level / 2)
 
2498
                    {
 
2499
                      guardian_change_images (guard, 1, 16);
 
2500
                      guardian->y_inc = 3.0;
 
2501
                      guardian->devilians_enable = TRUE;
 
2502
                    }
 
2503
                  else
 
2504
                    {
 
2505
                      guardian_loop_flip (guard, 2, 1, 31, 0);
 
2506
                    }
 
2507
                }
 
2508
              else
 
2509
                /* guardian weakened, low part destroyed: animation 2 */
 
2510
                {
 
2511
                  add_missiles = TRUE;
 
2512
                  switch (guardian->move_direction[guardian->move_current])
 
2513
                    {
 
2514
                    case GUARD_MOVEMENT_TOWARD_RIGHT:
 
2515
                      guardian_flip_image (guard, 4, 31);
 
2516
                      break;
 
2517
 
 
2518
                    case GUARD_MOVEMENT_TOWARD_LEFT:
 
2519
                      guardian_flip_image (guard, 0, 0);
 
2520
                      break;
 
2521
 
 
2522
                    case GUARD_IMMOBILE:
 
2523
                      guardian_flip_image (guard, 0, 15);
 
2524
                      guardian->devilians_enable = TRUE;
 
2525
                      break;
 
2526
                    }
 
2527
                }
 
2528
            }
 
2529
          else
 
2530
            {
 
2531
              guardian_next_trajectory ();
 
2532
            }
 
2533
        }
 
2534
    }
 
2535
  numof_bullets = guardian_fire (guard, 8, 2.0);
 
2536
  if (add_missiles)
 
2537
    {
 
2538
      guardian_add_missiles (guard, numof_bullets, 6, 2);
 
2539
    }
 
2540
}
 
2541
 
 
2542
/**
 
2543
 * Handle the guardian 14
 
2544
 * @param guard Pointer to the enemy structure of the guardian
 
2545
 */
 
2546
static void
 
2547
guardian_14 (enemy * guard)
 
2548
{
 
2549
  Uint32 numof_bullets;
 
2550
  if (guardian->is_appearing)
 
2551
    {
 
2552
      guardian_appears_from_top (guard);
 
2553
    }
 
2554
  else
 
2555
    {
 
2556
      if (!player_pause && menu_status == MENU_OFF
 
2557
          && menu_section == NO_SECTION_SELECTED)
 
2558
        {
 
2559
          if (--guardian->move_time_delay > 0)
 
2560
            {
 
2561
              if (guardian->move_direction[guardian->move_current] <
 
2562
                  GUARD_IMMOBILE)
 
2563
                {
 
2564
                  guardian_line_moving (guard);
 
2565
                }
 
2566
 
 
2567
              if (guardian->anim_delay_count >= 1
 
2568
                  && guard->spr.current_image == 31)
 
2569
                {
 
2570
                  guardian->anim_delay_count = 0;
 
2571
                  if (guardian->current_images_set == 0)
 
2572
                    {
 
2573
                      guardian_change_images (guard, 1, 0);
 
2574
                    }
 
2575
                  else
 
2576
                    {
 
2577
                      guardian_change_images (guard, 0, 0);
 
2578
                    }
 
2579
                }
 
2580
              else
 
2581
                {
 
2582
                  guardian_flip_image (guard, 2, 31);
 
2583
                }
 
2584
 
 
2585
              switch (guardian->move_direction[guardian->move_current])
 
2586
                {
 
2587
                case GUARD_MOVEMENT_TOWARD_RIGHT:
 
2588
                  break;
 
2589
                case GUARD_MOVEMENT_TOWARD_LEFT:
 
2590
                  break;
 
2591
                }
 
2592
            }
 
2593
          else
 
2594
            {
 
2595
              guardian_next_trajectory ();
 
2596
            }
 
2597
        }
 
2598
      guardian_add_perturbians (guard, 2, 210, TRUE);
 
2599
    }
 
2600
  numof_bullets = guardian_fire (guard, 4, 2.0);
 
2601
  if (numof_bullets > 0)
 
2602
    {
 
2603
      guardian_add_saakamin (guard, 6, 7);
 
2604
    }
 
2605
}
 
2606
 
 
2607
/**
 
2608
 * Draw a guardian vessel enemy
 
2609
 * @param guard Pointer to enemy structure 
 
2610
 */
 
2611
static void
 
2612
guardian_draw (enemy * guard)
 
2613
{
 
2614
  Sint16 zon_col;
 
2615
  float x_expl, y_expl;
 
2616
  sprite ve_spr = guard->spr;
 
2617
 
 
2618
  /* display white mask */
 
2619
  if (guard->is_white_mask_displayed)
 
2620
    {
 
2621
      draw_sprite_mask (coulor[WHITE],
 
2622
                        guard->spr.img[guard->spr.current_image],
 
2623
                        (Sint32) (guard->spr.xcoord),
 
2624
                        (Sint32) (guard->spr.ycoord));
 
2625
      guard->is_white_mask_displayed = FALSE;
 
2626
    }
 
2627
  else
 
2628
    {
 
2629
      draw_sprite (guard->spr.img[guard->spr.current_image],
 
2630
                   (Uint32) guard->spr.xcoord, (Uint32) guard->spr.ycoord);
 
2631
      if (rand () % 2
 
2632
          && rand () % (ve_spr.max_energy_level + 1) >
 
2633
          ve_spr.energy_level + (ve_spr.max_energy_level >> 3))
 
2634
        {
 
2635
          zon_col =
 
2636
            (Sint16) (rand () %
 
2637
                      ((Sint32) ve_spr.img[ve_spr.current_image]->
 
2638
                       numof_collisions_zones));
 
2639
          x_expl =
 
2640
            (float) (ve_spr.xcoord +
 
2641
                     ve_spr.img[ve_spr.current_image]->
 
2642
                     collisions_coords[zon_col][XCOORD] +
 
2643
                     rand () %
 
2644
                     ((Sint32) ve_spr.img[ve_spr.current_image]->
 
2645
                      collisions_sizes[zon_col][XCOORD] + 1));
 
2646
          y_expl =
 
2647
            (float) (ve_spr.ycoord +
 
2648
                     ve_spr.img[ve_spr.current_image]->
 
2649
                     collisions_coords[zon_col][YCOORD] +
 
2650
                     rand () %
 
2651
                     ((Sint32) ve_spr.img[ve_spr.current_image]->
 
2652
                      collisions_sizes[zon_col][YCOORD] + 1));
 
2653
          explosion_guardian_add (x_expl, y_expl);
 
2654
        }
 
2655
    }
 
2656
}
 
2657
 
 
2658
/**
 
2659
 * Run all guardians + congratulations
 
2660
 * @param guard Pointer to enemy structure
 
2661
 */
 
2662
void
 
2663
guardian_handle (enemy * guard)
 
2664
{
 
2665
  spaceship_struct *ship = spaceship_get ();
 
2666
  switch (guardian->number)
 
2667
    {
 
2668
    case 1:
 
2669
      guardian_01 (guard);
 
2670
      break;
 
2671
    case 2:
 
2672
      guardian_02 (guard);
 
2673
      break;
 
2674
    case 3:
 
2675
      guardian_03 (guard);
 
2676
      break;
 
2677
    case 4:
 
2678
      guardian_04 (guard);
 
2679
      break;
 
2680
    case 5:
 
2681
      guardian_05 (guard);
 
2682
      break;
 
2683
    case 6:
 
2684
      guardian_06 (guard);
 
2685
      break;
 
2686
    case 7:
 
2687
      guardian_07 (guard);
 
2688
      break;
 
2689
    case 8:
 
2690
      guardian_08 (guard);
 
2691
      break;
 
2692
    case 9:
 
2693
      guardian_09 (guard);
 
2694
      break;
 
2695
    case 10:
 
2696
      guardian_10 (guard);
 
2697
      break;
 
2698
    case 11:
 
2699
      guardian_11 (guard);
 
2700
      break;
 
2701
 
 
2702
      /* guardians 12, 13, 14 and congratulations */
 
2703
    case 12:
 
2704
      guardian_12 (guard);
 
2705
      break;
 
2706
    case 13:
 
2707
      guardian_13 (guard);
 
2708
      break;
 
2709
    case 14:
 
2710
      guardian_14 (guard);
 
2711
      break;
 
2712
    case 15:
 
2713
      congratulations ();
 
2714
      break;
 
2715
    }
 
2716
 
 
2717
  /* common part */
 
2718
  if (guardian->is_appearing)
 
2719
    {
 
2720
      if (guard == guardian->enemy[0])
 
2721
        {
 
2722
          /* guardian blink: display once on two */
 
2723
          if (guardian->is_blinking)
 
2724
            {
 
2725
              /* the guardian consists of two sprites */
 
2726
              if (guardian->number == 6 || guardian->number == 9
 
2727
                  || guardian->number == 10)
 
2728
                {
 
2729
                  guardian_draw (guardian->enemy[0]);
 
2730
                  guardian_draw (guardian->enemy[1]);
 
2731
                }
 
2732
              else
 
2733
                {
 
2734
                  guardian_draw (guard);
 
2735
                }
 
2736
              guardian->is_blinking = FALSE;
 
2737
            }
 
2738
          else
 
2739
            {
 
2740
              guardian->is_blinking = TRUE;
 
2741
            }
 
2742
        }
 
2743
    }
 
2744
  else
 
2745
    {
 
2746
      /* collisions with protections satellite */
 
2747
      enemy_satellites_collisions (guard);
 
2748
      /* collisions with extra guns */
 
2749
      enemy_guns_collisions (guard);
 
2750
      /* collision with player's spaceship */
 
2751
      if (!ship->invincibility_delay)
 
2752
        {
 
2753
          enemy_spaceship_collision (guard);
 
2754
        }
 
2755
      /* display the guardian */
 
2756
      guardian_draw (guard);
 
2757
    }
 
2758
}
 
2759
 
 
2760
/**
 
2761
 * Loading guardian's sprites images in memory 
 
2762
 * @param guardian_num number of the guardian 1 to 14
 
2763
 * @return TRUE if successful
 
2764
 */
 
2765
bool
 
2766
guardian_load (Sint32 guardian_num)
 
2767
{
 
2768
  Uint32 num_of_sprites;
 
2769
#ifdef VERBOSE
 
2770
  if (power_conf->verbose > 0)
 
2771
    {
 
2772
      fprintf (stdout, "> guardians.c/guardian_load(%i)\n", guardian_num);
 
2773
    }
 
2774
#endif
 
2775
  guardian_images_free ();
 
2776
 
 
2777
  switch (guardian_num)
 
2778
    {
 
2779
    case 2:
 
2780
    case 4:
 
2781
    case 5:
 
2782
    case 6:
 
2783
    case 9:
 
2784
    case 10:
 
2785
    case 12:
 
2786
    case 13:
 
2787
    case 14:
 
2788
      num_of_sprites = 2;
 
2789
      break;
 
2790
    default:
 
2791
      num_of_sprites = 1;
 
2792
      break;
 
2793
    }
 
2794
  if (!image_load_num
 
2795
      ("graphics/sprites/guardians/guardian_%02d.spr",
 
2796
       guardian_num - 1, &gardi[0][0], num_of_sprites,
 
2797
       ENEMIES_SPECIAL_NUM_OF_IMAGES))
 
2798
    {
 
2799
      return FALSE;
 
2800
    }
 
2801
  return TRUE;
 
2802
}
 
2803
 
 
2804
/** 
 
2805
 * Prepare next level if end of guardian
 
2806
 */
 
2807
bool
 
2808
guardian_finished (void)
 
2809
{
 
2810
  Uint32 guard_num = 0;
 
2811
  bool is_finished;
 
2812
  if (guardian->number == 0)
 
2813
    {
 
2814
      return TRUE;
 
2815
    }
 
2816
  /* guardian 11, 12, 13 and 14 requiring special handling */
 
2817
  if (num_level == MAX_NUM_OF_LEVELS && guardian->number >= 11
 
2818
      && guardian->number < 15)
 
2819
    {
 
2820
      switch (guardian->number)
 
2821
        {
 
2822
        case 11:
 
2823
          if (!guardian_load (12))
 
2824
            {
 
2825
              return FALSE;
 
2826
            }
 
2827
          guardian_new (12);
 
2828
          break;
 
2829
        case 12:
 
2830
          if (!guardian_load (13))
 
2831
            {
 
2832
              return FALSE;
 
2833
            }
 
2834
          guardian_new (13);
 
2835
          break;
 
2836
        case 13:
 
2837
          if (!guardian_load (14))
 
2838
            {
 
2839
              return FALSE;
 
2840
            }
 
2841
          guardian_new (14);
 
2842
          break;
 
2843
        case 14:
 
2844
          spaceship_disappears = TRUE;
 
2845
          /* congratulations */
 
2846
          if (starfield_speed == 0.0)
 
2847
            {
 
2848
              guardian_new (15);
 
2849
            }
 
2850
          break;
 
2851
        }
 
2852
    }
 
2853
  else
 
2854
    {
 
2855
      /* player's spaceship disappear from the screen */
 
2856
      spaceship_disappears = TRUE;
 
2857
      text_level_move (num_level);
 
2858
      is_finished = text_level_move (num_level);
 
2859
      if (starfield_speed == 0.0 && is_finished)
 
2860
        {
 
2861
          /* next level */
 
2862
          num_level++;
 
2863
          if (num_level > MAX_NUM_OF_LEVELS)
 
2864
            {
 
2865
              num_level = 0;
 
2866
            }
 
2867
 
 
2868
          /* load guardian files in advance */
 
2869
          switch (num_level)
 
2870
            {
 
2871
            case 4:
 
2872
              guard_num = 2;
 
2873
              break;
 
2874
            case 8:
 
2875
              guard_num = 3;
 
2876
              break;
 
2877
            case 12:
 
2878
              guard_num = 4;
 
2879
              break;
 
2880
            case 16:
 
2881
              guard_num = 5;
 
2882
              break;
 
2883
            case 20:
 
2884
              guard_num = 6;
 
2885
              break;
 
2886
            case 24:
 
2887
              guard_num = 7;
 
2888
              break;
 
2889
            case 28:
 
2890
              guard_num = 8;
 
2891
              break;
 
2892
            case 32:
 
2893
              guard_num = 9;
 
2894
              break;
 
2895
            case 36:
 
2896
              guard_num = 10;
 
2897
              break;
 
2898
            case 40:
 
2899
              guard_num = 11;
 
2900
              break;
 
2901
            }
 
2902
          if (guard_num > 0)
 
2903
            {
 
2904
              if (!guardian_load (guard_num))
 
2905
                {
 
2906
                  return FALSE;
 
2907
                }
 
2908
            }
 
2909
 
 
2910
          /* load grid level */
 
2911
          if (!grid_load (num_level))
 
2912
            {
 
2913
              return FALSE;
 
2914
            }
 
2915
          /* load curve phase level file (little skirmish) */
 
2916
          if (!curve_load_level (num_level))
 
2917
            {
 
2918
              return FALSE;
 
2919
            }
 
2920
          if (!meteors_load (num_level))
 
2921
            {
 
2922
              return FALSE;
 
2923
            }
 
2924
          /* enable the curve level file loaded previously */
 
2925
          curve_enable_level ();
 
2926
          courbe.activity = TRUE;
 
2927
          grid.is_enable = FALSE;
 
2928
          meteor_activity = FALSE;
 
2929
          guardian->number = 0;
 
2930
          spaceship_show ();
 
2931
        }
 
2932
    }
 
2933
  return TRUE;
 
2934
}
 
2935
 
 
2936
/*
 
2937
gardien 1 : gauche a droite
 
2938
gardien 2 : gauche a droite + animation descente
 
2939
gardien 3 : gauche a droite
 
2940
gardien 4 : gauche a droite + animation quand il pause
 
2941
gardien 5 : gauche a droite (sinus vertical) + missile
 
2942
gardien 6 : compose de 2 sprites : gauche a droite  (tube vertical)
 
2943
gardien 7 : gauche a droite + mine (tir & anim si mort) + autres vaisseaux
 
2944
gardien 8 : gauche a droite + autres vaisseaux
 
2945
gardien 9 : compose de 2 sprites : gauche a droite (nez du vaisseau) + autres vaisseaux
 
2946
gardien 10 : tourne en rectangle + autres vaisseaux
 
2947
gardien 11 : gauche a droite + autres vaisseaux
 
2948
 
 
2949
lonely foe sympas :
 
2950
-  9 LONELY_HOCKYS:        boule canon va de haut en bas
 
2951
- 20 LONELY_DEMONIANS:     vaisseau va de haut en bas
 
2952
- 22 LONELY_FIDGETINIANS:  vaisseau dentee va de haut en bas
 
2953
- 28 LONELY_DIVERTIZERS    vaisseau tourne va de haut en bas
 
2954
- 31 LONELY_CARRYONIANS    vaisseau bas ailes va de bas en haut
 
2955
- 39 LONELY_MADIRIANS      vaisseau canon gauche a droite
 
2956
 
 
2957
 
 
2958
 
 
2959
 
 
2960
 
 
2961
*/
 
2962
    /* initialize guardian 1 */