1 /***************************************************************************
2 ****************************************************************************
3 ****************************************************************************
4 * Nighthawk
5 * Copyright (C) 1996-2004 Jason Nunn et al
6 * Developed by Jason Nunn et al (see README for Acknowledgements)
7 *
8 * Project head and maintainer--
9 *   Eric Gillespie (The Viking)
10 *   Email: viking667@users.sourceforge.net
11 *   http://night-hawk.sourceforge.net
12 *
13 * Original Author--
14 *   Jason Nunn
15 *   http://jsno.leal.com.au
16 *
17 *   C/- Jason Nunn
18 *   PO Box 15
19 *   Birdwood SA 5234
20 *   Australia
21 *
22 * This software is Open Source GPL. Please read COPYING notice.
23 * ==================================================================
24 * root game routines
25 *
26 ****************************************************************************
27 ****************************************************************************
28 ***************************************************************************/
29 #include "defs.h"
30 #include "protos.p"
31 
32 #include "tship.h"
33 
34 /*
35  * nighthawk is assumed to have a max of 10 ships . no more unless you
36  * make space
37  */
38 PUBLIC tship *ship;
39 PUBLIC char   *ship_table[MAX_SHIPS + 1];
40 PUBLIC int    ship_ptr, ship_start, god_mode, reduced_f;
41 
42 PUBLIC tdroid_stats droid_stats[] = {
43   {
44     "002",
45     "Paradroid",
46     1,
47     1.0,
48     27.0,
49     "Neurologic",
50     LASER_LINARITE,
51     10,
52     10,
53     4.0,
54     0.0
55   },
56   {
57     "108",
58     "Minor Cleaning Droid",
59     1,
60     0.6,
61     38.3,
62     "Embedded Logic",
63     LASER_NONE,
64     1,
65     1,
66     1.0,
67    -1.0
68   },
69   {
70     "176",
71     "Standard Cleaning Droid",
72     1,
73     1.2,
74     80.6,
75     "Embedded Logic",
76     LASER_NONE,
77     5,
78     5,
79     2.0,
80    -1.0
81   },
82   {
83     "261",
84     "Cargo Paletting Droid",
85     2,
86     3,
87     800.75,
88     "Embedded Logic",
89     LASER_NONE,
90     500,
91     500,
92     0.5,
93    -1
94   },
95   {
96     "275",
97     "Servant Droid",
98     2,
99     0.4,
100     15.3,
101     "Embedded Logic",
102     LASER_NONE,
103     15,
104     15,
105     3.0,
106    -1.0
107   },
108   {
109     "355",
110     "Messenger (Class C) Droid",
111     3,
112     0.5,
113     10.0,
114     "Embedded Logic",
115     LASER_NONE,
116     10,
117     10,
118     3.5,
119    -1.0
120   },
121   {
122     "368",
123     "Messenger (Class D) Droid",
124     3,
125     0.76,
126     11.0,
127     "Embedded Logic",
128     LASER_NONE,
129     20,
130     20,
131     3.6,
132    -1.0
133   },
134   {
135     "423",
136     "Standard Maintenance Droid",
137     4,
138     2,
139     60.0,
140     "Embedded Logic",
141     LASER_NONE,
142     20,
143     20,
144     1.8,
145    -1.0
146   },
147   {
148     "467",
149     "Heavy Duty Maintenance Droid",
150     4,
151     1.5,
152     100.0,
153     "Embedded Logic",
154     LASER_CROC_BENZ,
155     25,
156     25,
157     1.3,
158    -1.0
159   },
160   {
161     "489",
162     "Aerial Maintenance Droid",
163     4,
164     0.2,
165     5.0,
166     "Embedded Logic",
167     LASER_LINARITE,
168     25,
169     25,
170     4.6,
171    -1.0
172   },
173   {
174     "513",
175     "Trauma Technician",
176     5,
177     1,
178     40.0,
179     "Neurologic",
180     LASER_CROC_BENZ,
181     30,
182     30,
183     2.3,
184     0.0
185   },
186   {
187     "520",
188     "Nurse Droid",
189     5,
190     0.6,
191     50.0,
192     "Neurologic",
193     LASER_CROC_BENZ,
194     35,
195     35,
196     3.0,
197     0.0
198   },
199   {
200     "599",
201     "Surgeon Droid",
202     5,
203     2,
204     56.80,
205     "Neurologic",
206     LASER_UVAROVITE,
207     45,
208     45,
209     4.0,
210     0.0
211   },
212   {
213     "606",
214     "Guard Monitor",
215     6,
216     1.1,
217     20.0,
218     "Neurologic",
219     LASER_CROC_BENZ,
220     15,
221     15,
222     2.6,
223     50.0
224   },
225   {
226     "691",
227     "Sentinel Droid",
228     6,
229     1.9,
230     45.0,
231     "Neurologic",
232     LASER_CROC_BENZ,
233     40,
234     40,
235     3.9,
236     30.0
237   },
238   {
239     "693",
240     "Centurion Droid",
241     6,
242     2.0,
243     50.0,
244     "Neurologic",
245     LASER_UVAROVITE,
246     50,
247     50,
248     1.9,
249     26.0
250   },
251   {
252     "719",
253     "Battle Droid",
254     7,
255     1.5,
256     40.92,
257     "Neurologic",
258     LASER_CROC_BENZ,
259     40,
260     40,
261     1.4,
262     38.0
263   },
264   {
265     "720",
266     "Flank Droid",
267     7,
268     1.0,
269     30.10,
270     "Neurologic",
271     LASER_CROC_BENZ,
272     30,
273     30,
274     4.8,
275     16.0
276   },
277   {
278     "766",
279     "Attack Droid",
280     7,
281     1.9,
282     67.45,
283     "Neurologic",
284     LASER_UVAROVITE,
285     70,
286     70,
287     2.8,
288     30.0
289   },
290   {
291     "799",
292     "Heavy Battle Droid",
293     7,
294     2.0,
295     90.98,
296     "Neurologic",
297     LASER_UVAROVITE,
298     100,
299     100,
300     2.6,
301     16.0
302   },
303   {
304     "805",
305     "Communications Droid",
306     8,
307     0.8,
308     50.10,
309     "Neurologic",
310     LASER_UVAROVITE,
311     70,
312     70,
313     2.0,
314     22.0
315   },
316   {
317     "810",
318     "Engineer Droid",
319     8,
320     1.74,
321     60.00,
322     "Neurologic",
323     LASER_UVAROVITE,
324     80,
325     80,
326     2.1,
327     30.0
328   },
329   {
330     "820",
331     "Science Droid",
332     8,
333     1.0,
334     40.00,
335     "Neurologic",
336     LASER_UVAROVITE,
337     90,
338     90,
339     2.7,
340     32.0
341   },
342   {
343     "899",
344     "Pilot Droid",
345     8,
346     1.74,
347     60.00,
348     "Neurologic",
349     LASER_UVAROVITE,
350     90,
351     90,
352     2.0,
353     18.0
354   },
355   {
356     "933",
357     "Minor Cyborg",
358     9,
359     3.1,
360     89.0,
361     "Neurologic",
362     LASER_TIGER_EYE,
363     20,
364     20,
365     3.0,
366     34.0
367   },
368   {
369     "949",
370     "Command Cyborg",
371     9,
372     2.6,
373     34.0,
374     "Neurologic",
375     LASER_TIGER_EYE,
376     70,
377     70,
378     4.2,
379     30.0
380   },
381   {
382     "999",
383     "Fleet Cyborg",
384     9,
385     3.1,
386     40.95,
387     "Neurologic",
388     LASER_TIGER_EYE,
389     200,
390     200,
391     5.0,
392     15.0
393   }
394 };
395 
396 PRIVATE GLdouble game_count;
397 PRIVATE void     game_ship_start(void);
398 
399 /***************************************************************************
400 *
401 ***************************************************************************/
get_ctrl_file(void)402 PUBLIC int get_ctrl_file(void)
403 {
404   FILE *fp;
405   int  x = 0;
406   char str[STR_LABEL_LEN + 1];
407 
408   printf("Loading Ship List..\n");
409   fp = fopen(INSTALL_DIR "/data/ctrl.d", "r");
410   if(fp == NULL)
411   {
412     perror("get_ctrl_file()");
413     fprintf(stderr, "Error: get_ctrl_file()::fopen()\n");
414     end_game(-1);
415   }
416 
417   for(;;)
418   {
419     if(fgets(str, STR_LABEL_LEN, fp) == NULL)
420       break;
421     str[strlen(str) - 1] = 0;
422     ship_table[x] = (char *)alloc_mem(strlen(str) + 1);
423     strcpy(ship_table[x], str);
424     x++;
425   }
426 
427   fclose(fp);
428 
429   return 1;
430 }
431 
432 /***************************************************************************
433 *
434 ***************************************************************************/
display_final_score(void)435 void display_final_score(void)
436 {
437   char str[STR_LEN + 1];
438 
439   sprintf(str, "Your Final Score: %d", score);
440   glColor3fv(green_pixel[2]);
441   print_str(str, SCREEN_HSIZE_X - ((strlen(str) << 3) >> 1), 180);
442 }
443 
444 /***************************************************************************
445 * Tanel Kulaots's level continuence patch melded into these routines
446 ***************************************************************************/
447 PRIVATE int game_term_dis_cont;
448 
game_term_calc(void)449 PRIVATE void game_term_calc(void)
450 {
451   game_count += get_time_lapse();
452   if(game_count > 100)
453     game_term_dis_cont = 1;
454 }
455 
game_term_draw(void)456 PRIVATE void game_term_draw(void)
457 {
458   char    str[STR_LEN + 1];
459   tkevent k;
460 
461   glColor4fv(bm_colour);
462   blit_bm(
463     &trans_terminated_bm,
464     SCREEN_HSIZE_X - (trans_terminated_bm.size_x >> 1), 50);
465 
466   display_final_score();
467 
468   if(game_term_dis_cont)
469   {
470     sprintf(str, "Continue: y/n ?");
471     print_str(str, SCREEN_HSIZE_X - ((strlen(str) << 3) >> 1), 150);
472   }
473 
474 //  sound_engine_cmd(SND_CMD_SILENCE,0,0,0);
475 //  sound_engine_cmd(SND_CMD_FX,FX_TRANS_TERM,0xff,0x80);
476 
477   if(!get_kb_event(&k))
478     return;
479 
480   if(k.type == KEYBOARD_EVENT && tolower(k.val) == 'y')
481   {
482     game_ship_start_init();
483     return;
484   }
485 
486   update_score(0);
487   intro_start_init();
488 }
489 
game_term_init(void)490 PRIVATE void game_term_init(void)
491 {
492   game_count = 0.0;
493   game_term_dis_cont = 0;
494   draw_h_hook = game_term_draw;
495   sync_time_lapse();
496   calc_hook = game_term_calc;
497 }
498 
499 /***************************************************************************
500 *
501 ***************************************************************************/
game_noise_calc(void)502 PRIVATE void game_noise_calc(void)
503 {
504   game_count += get_time_lapse();
505   if(game_count > 50)
506     game_term_init();
507 }
508 
game_noise_draw(void)509 PRIVATE void game_noise_draw(void)
510 {
511   int x, y;
512 
513 //  sound_engine_cmd(SND_CMD_RANDOM,0,0,0);
514 
515   for(y = 0; y < 200; y += 10)
516   {
517     for(x = 0; x < 320; x += 10)
518     {
519       glColor3fv(white_pixel[random() & 0x7]);
520       blit_rect(x, y, 10, 10);
521     }
522   }
523 }
524 
game_noise_init(void)525 PRIVATE void game_noise_init(void)
526 {
527   game_count = 0;
528   draw_h_hook = game_noise_draw;
529   sync_time_lapse();
530   calc_hook = game_noise_calc;
531 }
532 
533 /***************************************************************************
534 *
535 ***************************************************************************/
game_finale_draw(void)536 PRIVATE void game_finale_draw(void)
537 {
538   tkevent     k;
539   static char *mess =
540     "You have completed all levels.\n"
541     "WELL DONE !\n"
542     "(Send us a screen dump)\n"
543     "\n"
544     "Thank you for playing Nighthawk.\n";
545 
546   update_score(1);
547 
548   glColor3fv(white_pixel[2]);
549   display_message(mess, 40);
550   display_final_score();
551 
552   if(!get_kb_event(&k))
553     return;
554 
555   intro_start_init();
556 }
557 
game_finale_init(void)558 PRIVATE void game_finale_init(void)
559 {
560   draw_h_hook = game_finale_draw;
561   sync_time_lapse();
562   calc_hook = NULL;
563 }
564 
565 /***************************************************************************
566 *
567 ***************************************************************************/
delete_ship(void)568 PRIVATE void delete_ship(void)
569 {
570   ship->unload();
571   delete(ship);
572 }
573 
game_run_calc(void)574 PRIVATE void game_run_calc(void)
575 {
576   static double ud;
577 
578   if(ship != NULL)
579     ship->level_bg_calc();
580 
581   ud += get_time_lapse();
582   if(ud >= 2.0)
583   {
584     ud = 0.0;
585     if(score != sscore)
586       sscore += ((score - sscore) >> 1) | 1;
587   }
588 }
589 
game_run_draw(void)590 PRIVATE void game_run_draw(void)
591 {
592   ship->level_run();
593 
594   if(ship->state == STATE_END)
595   {
596     delete_ship();
597 
598     game_noise_init();
599     return;
600   }
601 
602   if(ship->state == STATE_COMPLETE)
603   {
604     last_score = score;
605     delete_ship();
606 
607     ship_ptr++;
608     if(ship_table[ship_ptr] != NULL)
609     {
610       game_ship_start();
611       return;
612     }
613 
614     ship_ptr--;
615     game_finale_init();
616   }
617 }
618 
game_run_init(void)619 PRIVATE void game_run_init(void)
620 {
621   draw_h_hook = game_run_draw;
622   calc_hook = game_run_calc;
623 }
624 
625 /***************************************************************************
626 *
627 ***************************************************************************/
game_ship_start(void)628 PRIVATE void game_ship_start(void)
629 {
630   ship = new(tship);
631   if(ship == NULL)
632     malloc_error_h();
633 
634   ship->load(ship_table[ship_ptr]);
635 
636 //  sound_engine_cmd(SND_CMD_FX_INIT,0,0,0);
637 
638   game_run_init();
639 }
640 
game_ship_start_init(void)641 PUBLIC void game_ship_start_init(void)
642 {
643   score = last_score;
644 
645   draw_h_hook = game_ship_start;
646   sync_time_lapse();
647   calc_hook = NULL;
648 }
649