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