This commit was manufactured by cvs2svn to create branch 'pinder'.
[newkind] / docked.c
1 /*
2 * Elite - The New Kind.
3 *
4 * Reverse engineered from the BBC disk version of Elite.
5 * Additional material by C.J.Pinder.
6 *
7 * The original Elite code is (C) I.Bell & D.Braben 1984.
8 * This version re-engineered in C by C.J.Pinder 1999-2001.
9 *
10 * email: <christian@newkind.co.uk>
11 *
12 *
13 */
14
15
16 #include <string.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <math.h>
20 #include <ctype.h>
21
22 #include "config.h"
23 #include "gfx.h"
24 #include "elite.h"
25 #include "planet.h"
26 #include "shipdata.h"
27 #include "space.h"
28
29
30
31
32
33 char *economy_type[] = {"Rich Industrial",
34 "Average Industrial",
35 "Poor Industrial",
36 "Mainly Industrial",
37 "Mainly Agricultural",
38 "Rich Agricultural",
39 "Average Agricultural",
40 "Poor Agricultural"};
41
42 char *government_type[] = { "Anarchy",
43 "Feudal",
44 "Multi-Government",
45 "Dictatorship",
46 "Communist",
47 "Confederacy",
48 "Democracy",
49 "Corporate State"};
50
51
52
53
54
55
56 int cross_x = 0;
57 int cross_y = 0;
58
59
60
61
62
63
64
65 void draw_fuel_limit_circle (int cx, int cy)
66 {
67 int radius;
68 int cross_size;
69
70 if (current_screen == SCR_GALACTIC_CHART)
71 {
72 radius = cmdr.fuel / 4 * GFX_SCALE;
73 cross_size = 7 * GFX_SCALE;
74 }
75 else
76 {
77 radius = cmdr.fuel * GFX_SCALE;
78 cross_size = 16 * GFX_SCALE;
79 }
80
81 gfx_draw_circle (cx, cy, radius, GFX_COL_GREEN_1);
82
83 gfx_draw_line (cx, cy - cross_size, cx, cy + cross_size);
84 gfx_draw_line (cx - cross_size, cy, cx + cross_size, cy);
85 }
86
87
88
89
90
91 int calc_distance_to_planet (struct galaxy_seed from_planet, struct galaxy_seed to_planet)
92 {
93 int dx,dy;
94 int light_years;
95
96 dx = abs(to_planet.d - from_planet.d);
97 dy = abs(to_planet.b - from_planet.b);
98
99 dx = dx * dx;
100 dy = dy / 2;
101 dy = dy * dy;
102
103 light_years = sqrt(dx + dy);
104 light_years *= 4;
105
106 return light_years;
107 }
108
109
110 void show_distance (int ypos, struct galaxy_seed from_planet, struct galaxy_seed to_planet)
111 {
112 char str[100];
113 int light_years;
114
115 light_years = calc_distance_to_planet (from_planet, to_planet);
116
117 if (light_years > 0)
118 sprintf (str, "Distance: %2d.%d Light Years ", light_years / 10, light_years % 10);
119 else
120 strcpy (str," ");
121
122 gfx_display_text (16, ypos, str);
123 }
124
125
126
127 void show_distance_to_planet (void)
128 {
129 int px,py;
130 char planet_name[16];
131 char str[32];
132
133 if (current_screen == SCR_GALACTIC_CHART)
134 {
135 px = cross_x / GFX_SCALE;
136 py = (cross_y - ((18 * GFX_SCALE) + 1)) * (2 / GFX_SCALE);
137 }
138 else
139 {
140 px = ((cross_x - GFX_X_CENTRE) / (4 * GFX_SCALE)) + docked_planet.d;
141 py = ((cross_y - GFX_Y_CENTRE) / (2 * GFX_SCALE)) + docked_planet.b;
142 }
143
144 hyperspace_planet = find_planet (px, py);
145
146 name_planet (planet_name, hyperspace_planet);
147
148 gfx_clear_text_area();
149 sprintf (str, "%-18s", planet_name);
150 gfx_display_text (16, 340, str);
151
152 show_distance (356, docked_planet, hyperspace_planet);
153
154 if (current_screen == SCR_GALACTIC_CHART)
155 {
156 cross_x = hyperspace_planet.d * GFX_SCALE;
157 cross_y = hyperspace_planet.b / (2 / GFX_SCALE) + (18 * GFX_SCALE) + 1;
158 }
159 else
160 {
161 cross_x = ((hyperspace_planet.d - docked_planet.d) * (4 * GFX_SCALE)) + GFX_X_CENTRE;
162 cross_y = ((hyperspace_planet.b - docked_planet.b) * (2 * GFX_SCALE)) + GFX_Y_CENTRE;
163 }
164 }
165
166
167 void move_cursor_to_origin (void)
168 {
169 if (current_screen == SCR_GALACTIC_CHART)
170 {
171 cross_x = docked_planet.d * GFX_SCALE;
172 cross_y = docked_planet.b / (2 / GFX_SCALE) + (18 * GFX_SCALE) + 1;
173 }
174 else
175 {
176 cross_x = GFX_X_CENTRE;
177 cross_y = GFX_Y_CENTRE;
178 }
179
180 show_distance_to_planet();
181 }
182
183
184 void find_planet_by_name (char *find_name)
185 {
186 int i;
187 struct galaxy_seed glx;
188 char planet_name[16];
189 int found;
190 char str[32];
191
192 glx = cmdr.galaxy;
193 found = 0;
194
195 for (i = 0; i < 256; i++)
196 {
197 name_planet (planet_name, glx);
198
199 if (strcmp (planet_name, find_name) == 0)
200 {
201 found = 1;
202 break;
203 }
204
205 waggle_galaxy (&glx);
206 waggle_galaxy (&glx);
207 waggle_galaxy (&glx);
208 waggle_galaxy (&glx);
209 }
210
211 if (!found)
212 {
213 gfx_clear_text_area();
214 gfx_display_text (16, 340, "Unknown Planet");
215 return;
216 }
217
218 hyperspace_planet = glx;
219
220 gfx_clear_text_area ();
221 sprintf (str, "%-18s", planet_name);
222 gfx_display_text (16, 340, str);
223
224 show_distance (356, docked_planet, hyperspace_planet);
225
226 if (current_screen == SCR_GALACTIC_CHART)
227 {
228 cross_x = hyperspace_planet.d * GFX_SCALE;
229 cross_y = hyperspace_planet.b / (2 / GFX_SCALE) + (18 * GFX_SCALE) + 1;
230 }
231 else
232 {
233 cross_x = ((hyperspace_planet.d - docked_planet.d) * (4 * GFX_SCALE)) + GFX_X_CENTRE;
234 cross_y = ((hyperspace_planet.b - docked_planet.b) * (2 * GFX_SCALE)) + GFX_Y_CENTRE;
235 }
236 }
237
238
239
240 void display_short_range_chart (void)
241 {
242 int i;
243 struct galaxy_seed glx;
244 int dx,dy;
245 int px,py;
246 char planet_name[16];
247 int row_used[64];
248 int row;
249 int blob_size;
250
251 current_screen = SCR_SHORT_RANGE;
252
253 gfx_clear_display();
254
255 gfx_display_centre_text (10, "SHORT RANGE CHART", 140, GFX_COL_GOLD);
256
257 gfx_draw_line (0, 36, 511, 36);
258
259 draw_fuel_limit_circle (GFX_X_CENTRE, GFX_Y_CENTRE);
260
261 for (i = 0; i < 64; i++)
262 row_used[i] = 0;
263
264 glx = cmdr.galaxy;
265
266 for (i = 0; i < 256; i++)
267 {
268
269 dx = abs (glx.d - docked_planet.d);
270 dy = abs (glx.b - docked_planet.b);
271
272 if ((dx >= 20) || (dy >= 38))
273 {
274 waggle_galaxy (&glx);
275 waggle_galaxy (&glx);
276 waggle_galaxy (&glx);
277 waggle_galaxy (&glx);
278
279 continue;
280 }
281
282 px = (glx.d - docked_planet.d);
283 px = px * 4 * GFX_SCALE + GFX_X_CENTRE; /* Convert to screen co-ords */
284
285 py = (glx.b - docked_planet.b);
286 py = py * 2 * GFX_SCALE + GFX_Y_CENTRE; /* Convert to screen co-ords */
287
288 row = py / (8 * GFX_SCALE);
289
290 if (row_used[row] == 1)
291 row++;
292
293 if (row_used[row] == 1)
294 row -= 2;
295
296 if (row <= 3)
297 {
298 waggle_galaxy (&glx);
299 waggle_galaxy (&glx);
300 waggle_galaxy (&glx);
301 waggle_galaxy (&glx);
302
303 continue;
304 }
305
306 if (row_used[row] == 0)
307 {
308 row_used[row] = 1;
309
310 name_planet (planet_name, glx);
311 capitalise_name (planet_name);
312
313 gfx_display_text (px + (4 * GFX_SCALE), (row * 8 - 5) * GFX_SCALE, planet_name);
314 }
315
316
317 /* The next bit calculates the size of the circle used to represent */
318 /* a planet. The carry_flag is left over from the name generation. */
319 /* Yes this was how it was done... don't ask :-( */
320
321 blob_size = (glx.f & 1) + 2 + carry_flag;
322 blob_size *= GFX_SCALE;
323 gfx_draw_filled_circle (px, py, blob_size, GFX_COL_GOLD);
324
325 waggle_galaxy (&glx);
326 waggle_galaxy (&glx);
327 waggle_galaxy (&glx);
328 waggle_galaxy (&glx);
329 }
330
331 cross_x = ((hyperspace_planet.d - docked_planet.d) * 4 * GFX_SCALE) + GFX_X_CENTRE;
332 cross_y = ((hyperspace_planet.b - docked_planet.b) * 2 * GFX_SCALE) + GFX_Y_CENTRE;
333 }
334
335
336
337
338 void display_galactic_chart (void)
339 {
340 int i;
341 struct galaxy_seed glx;
342 char str[64];
343 int px,py;
344
345
346 current_screen = SCR_GALACTIC_CHART;
347
348 gfx_clear_display();
349
350 sprintf (str, "GALACTIC CHART %d", cmdr.galaxy_number + 1);
351
352 gfx_display_centre_text (10, str, 140, GFX_COL_GOLD);
353
354 gfx_draw_line (0, 36, 511, 36);
355 gfx_draw_line (0, 36+258, 511, 36+258);
356
357 draw_fuel_limit_circle (docked_planet.d * GFX_SCALE,
358 (docked_planet.b / (2 / GFX_SCALE)) + (18 * GFX_SCALE) + 1);
359
360 glx = cmdr.galaxy;
361
362 for (i = 0; i < 256; i++)
363 {
364 px = glx.d * GFX_SCALE;
365 py = (glx.b / (2 / GFX_SCALE)) + (18 * GFX_SCALE) + 1;
366
367 gfx_plot_pixel (px, py, GFX_COL_WHITE);
368
369 if ((glx.e | 0x50) < 0x90)
370 gfx_plot_pixel (px + 1, py, GFX_COL_WHITE);
371
372 waggle_galaxy (&glx);
373 waggle_galaxy (&glx);
374 waggle_galaxy (&glx);
375 waggle_galaxy (&glx);
376
377 }
378
379
380 cross_x = hyperspace_planet.d * GFX_SCALE;
381 cross_y = (hyperspace_planet.b / (2 / GFX_SCALE)) + (18 * GFX_SCALE) + 1;
382 }
383
384
385
386
387
388 /*
389 * Displays data on the currently selected Hyperspace Planet.
390 */
391
392 void display_data_on_planet (void)
393 {
394 char planet_name[16];
395 char str[100];
396 char *description;
397 struct planet_data hyper_planet_data;
398
399 current_screen = SCR_PLANET_DATA;
400
401 gfx_clear_display();
402
403 name_planet (planet_name, hyperspace_planet);
404 sprintf (str, "DATA ON %s", planet_name);
405
406 gfx_display_centre_text (10, str, 140, GFX_COL_GOLD);
407
408 gfx_draw_line (0, 36, 511, 36);
409
410
411 generate_planet_data (&hyper_planet_data, hyperspace_planet);
412
413 show_distance (42, docked_planet, hyperspace_planet);
414
415 sprintf (str, "Economy:%s", economy_type[hyper_planet_data.economy]);
416 gfx_display_text (16, 74, str);
417
418 sprintf (str, "Government:%s", government_type[hyper_planet_data.government]);
419 gfx_display_text (16, 106, str);
420
421 sprintf (str, "Tech.Level:%3d", hyper_planet_data.techlevel + 1);
422 gfx_display_text (16, 138, str);
423
424 sprintf (str, "Population:%d.%d Billion", hyper_planet_data.population / 10, hyper_planet_data.population % 10);
425 gfx_display_text (16, 170, str);
426
427 describe_inhabitants (str, hyperspace_planet);
428 gfx_display_text (16, 202, str);
429
430 sprintf (str, "Gross Productivity:%5d M CR", hyper_planet_data.productivity);
431 gfx_display_text (16, 234, str);
432
433 sprintf (str, "Average Radius:%5d km", hyper_planet_data.radius);
434 gfx_display_text (16, 266, str);
435
436 description = describe_planet (hyperspace_planet);
437 gfx_display_pretty_text (16, 298, 400, 384, description);
438 }
439
440
441
442 struct rank
443 {
444 int score;
445 char *title;
446 };
447
448 #define NO_OF_RANKS 9
449
450 struct rank rating[NO_OF_RANKS] =
451 {
452 {0x0000, "Harmless"},
453 {0x0008, "Mostly Harmless"},
454 {0x0010, "Poor"},
455 {0x0020, "Average"},
456 {0x0040, "Above Average"},
457 {0x0080, "Competent"},
458 {0x0200, "Dangerous"},
459 {0x0A00, "Deadly"},
460 {0x1900, "---- E L I T E ---"}
461 };
462
463 char *laser_name[5] = {"Pulse", "Beam", "Military", "Mining", "Custom"};
464
465
466
467 char *laser_type (int strength)
468 {
469 switch (strength)
470 {
471 case PULSE_LASER:
472 return laser_name[0];
473
474 case BEAM_LASER:
475 return laser_name[1];
476
477 case MILITARY_LASER:
478 return laser_name[2];
479
480 case MINING_LASER:
481 return laser_name[3];
482 }
483
484 return laser_name[4];
485 }
486
487
488 #define EQUIP_START_Y 202
489 #define EQUIP_START_X 50
490 #define EQUIP_MAX_Y 290
491 #define EQUIP_WIDTH 200
492 #define Y_INC 16
493
494
495 static char *condition_txt[] =
496 {
497 "Docked",
498 "Green",
499 "Yellow",
500 "Red"
501 };
502
503 void display_commander_status (void)
504 {
505 char planet_name[16];
506 char str[100];
507 int i;
508 int x,y;
509 int condition;
510 int type;
511
512 current_screen = SCR_CMDR_STATUS;
513
514 gfx_clear_display();
515
516 sprintf (str, "COMMANDER %s", cmdr.name);
517
518 gfx_display_centre_text (10, str, 140, GFX_COL_GOLD);
519
520 gfx_draw_line (0, 36, 511, 36);
521
522
523 gfx_display_colour_text (16, 58, "Present System:", GFX_COL_GREEN_1);
524
525 if (!witchspace)
526 {
527 name_planet (planet_name, docked_planet);
528 capitalise_name (planet_name);
529 sprintf (str, "%s", planet_name);
530 gfx_display_text (190, 58, str);
531 }
532
533 gfx_display_colour_text (16, 74, "Hyperspace System:", GFX_COL_GREEN_1);
534 name_planet (planet_name, hyperspace_planet);
535 capitalise_name (planet_name);
536 sprintf (str, "%s", planet_name);
537 gfx_display_text (190, 74, str);
538
539 if (docked)
540 condition = 0;
541 else
542 {
543 condition = 1;
544
545 for (i = 0; i < MAX_UNIV_OBJECTS; i++)
546 {
547 type = universe[i].type;
548
549 if ((type == SHIP_MISSILE) ||
550 ((type > SHIP_ROCK) && (type < SHIP_DODEC)))
551 {
552 condition = 2;
553 break;
554 }
555 }
556
557 if ((condition == 2) && (energy < 128))
558 condition = 3;
559 }
560
561 gfx_display_colour_text (16, 90, "Condition:", GFX_COL_GREEN_1);
562 gfx_display_text (190, 90, condition_txt[condition]);
563
564 sprintf (str, "%d.%d Light Years", cmdr.fuel / 10, cmdr.fuel % 10);
565 gfx_display_colour_text (16, 106, "Fuel:", GFX_COL_GREEN_1);
566 gfx_display_text (70, 106, str);
567
568 sprintf (str, "%d.%d Cr", cmdr.credits / 10, cmdr.credits % 10);
569 gfx_display_colour_text (16, 122, "Cash:", GFX_COL_GREEN_1);
570 gfx_display_text (70, 122, str);
571
572 if (cmdr.legal_status == 0)
573 strcpy (str, "Clean");
574 else
575 strcpy (str, cmdr.legal_status > 50 ? "Fugitive" : "Offender");
576
577 gfx_display_colour_text (16, 138, "Legal Status:", GFX_COL_GREEN_1);
578 gfx_display_text (128, 138, str);
579
580 for (i = 0; i < NO_OF_RANKS; i++)
581 if (cmdr.score >= rating[i].score)
582 strcpy (str, rating[i].title);
583
584 gfx_display_colour_text (16, 154, "Rating:", GFX_COL_GREEN_1);
585 gfx_display_text (80, 154, str);
586
587 gfx_display_colour_text (16, 186, "EQUIPMENT:", GFX_COL_GREEN_1);
588
589 x = EQUIP_START_X;
590 y = EQUIP_START_Y;
591
592 if (cmdr.cargo_capacity > 20)
593 {
594 gfx_display_text (x, y, "Large Cargo Bay");
595 y += Y_INC;
596 }
597
598 if (cmdr.escape_pod)
599 {
600 gfx_display_text (x, y, "Escape Pod");
601 y += Y_INC;
602 }
603
604 if (cmdr.fuel_scoop)
605 {
606 gfx_display_text (x, y, "Fuel Scoops");
607 y += Y_INC;
608 }
609
610 if (cmdr.ecm)
611 {
612 gfx_display_text (x, y, "E.C.M. System");
613 y += Y_INC;
614 }
615
616 if (cmdr.energy_bomb)
617 {
618 gfx_display_text (x, y, "Energy Bomb");
619 y += Y_INC;
620 }
621
622 if (cmdr.energy_unit)
623 {
624 gfx_display_text (x, y,
625 cmdr.energy_unit == 1 ? "Extra Energy Unit" :"Naval Energy Unit");
626 y += Y_INC;
627 if (y > EQUIP_MAX_Y)
628 {
629 y = EQUIP_START_Y;
630 x += EQUIP_WIDTH;
631 }
632 }
633
634 if (cmdr.docking_computer)
635 {
636 gfx_display_text (x, y, "Docking Computers");
637 y += Y_INC;
638 if (y > EQUIP_MAX_Y)
639 {
640 y = EQUIP_START_Y;
641 x += EQUIP_WIDTH;
642 }
643 }
644
645
646 if (cmdr.galactic_hyperdrive)
647 {
648 gfx_display_text (x, y, "Galactic Hyperspace");
649 y += Y_INC;
650 if (y > EQUIP_MAX_Y)
651 {
652 y = EQUIP_START_Y;
653 x += EQUIP_WIDTH;
654 }
655 }
656
657 if (cmdr.front_laser)
658 {
659 sprintf (str, "Front %s Laser", laser_type(cmdr.front_laser));
660 gfx_display_text (x, y, str);
661 y += Y_INC;
662 if (y > EQUIP_MAX_Y)
663 {
664 y = EQUIP_START_Y;
665 x += EQUIP_WIDTH;
666 }
667 }
668
669 if (cmdr.rear_laser)
670 {
671 sprintf (str, "Rear %s Laser", laser_type(cmdr.rear_laser));
672 gfx_display_text (x, y, str);
673 y += Y_INC;
674 if (y > EQUIP_MAX_Y)
675 {
676 y = EQUIP_START_Y;
677 x += EQUIP_WIDTH;
678 }
679 }
680
681 if (cmdr.left_laser)
682 {
683 sprintf (str, "Left %s Laser", laser_type(cmdr.left_laser));
684 gfx_display_text (x, y, str);
685 y += Y_INC;
686 if (y > EQUIP_MAX_Y)
687 {
688 y = EQUIP_START_Y;
689 x += EQUIP_WIDTH;
690 }
691 }
692
693 if (cmdr.right_laser)
694 {
695 sprintf (str, "Right %s Laser", laser_type(cmdr.right_laser));
696 gfx_display_text (x, y, str);
697 }
698 }
699
700
701
702 /***********************************************************************************/
703
704 #define TONNES 0
705 #define KILOGRAMS 1
706 #define GRAMS 2
707
708 static int hilite_item;
709 static char *unit_name[] = {"t", "kg", "g"};
710
711
712 void display_stock_price (int i)
713 {
714 int y;
715 char str[100];
716
717 y = i * 15 + 55;
718
719 gfx_display_text (16, y, stock_market[i].name);
720
721 gfx_display_text (180, y, unit_name[stock_market[i].units]);
722 sprintf (str, "%d.%d", stock_market[i].current_price / 10,
723 stock_market[i].current_price % 10);
724 gfx_display_text (256, y, str);
725
726 if (stock_market[i].current_quantity > 0)
727 sprintf (str, "%d%s", stock_market[i].current_quantity,
728 unit_name[stock_market[i].units]);
729 else
730 strcpy (str, "-");
731
732 gfx_display_text (338, y, str);
733
734 if (cmdr.current_cargo[i] > 0)
735 sprintf (str, "%d%s", cmdr.current_cargo[i],
736 unit_name[stock_market[i].units]);
737 else
738 strcpy (str, "-");
739
740 gfx_display_text (444, y, str);
741 }
742
743
744 void highlight_stock (int i)
745 {
746 int y;
747 char str[30];
748
749 if ((hilite_item != -1) && (hilite_item != i))
750 {
751 y = hilite_item * 15 + 55;
752 gfx_clear_area (2, y, 510, y + 15);
753 display_stock_price (hilite_item);
754 }
755
756 y = i * 15 + 55;
757
758 gfx_draw_rectangle (2, y, 510, y + 15, GFX_COL_DARK_RED);
759 display_stock_price (i);
760
761 hilite_item = i;
762
763 gfx_clear_text_area();
764 sprintf (str, "Cash: %d.%d", cmdr.credits / 10, cmdr.credits % 10);
765 gfx_display_text (16, 340, str);
766 }
767
768 void select_previous_stock (void)
769 {
770 if ((!docked) || (hilite_item == 0))
771 return;
772
773 highlight_stock (hilite_item - 1);
774 }
775
776 void select_next_stock (void)
777 {
778 if ((!docked) || (hilite_item == 16))
779 return;
780
781 highlight_stock (hilite_item + 1);
782 }
783
784
785 void buy_stock (void)
786 {
787 struct stock_item *item;
788 int cargo_held;
789
790 if (!docked)
791 return;
792
793 item = &stock_market[hilite_item];
794
795 if ((item->current_quantity == 0) ||
796 (cmdr.credits < item->current_price))
797 return;
798
799 cargo_held = total_cargo();
800
801 if ((item->units == TONNES) &&
802 (cargo_held == cmdr.cargo_capacity))
803 return;
804
805 cmdr.current_cargo[hilite_item]++;
806 item->current_quantity--;
807 cmdr.credits -= item->current_price;
808
809 highlight_stock (hilite_item);
810 }
811
812
813 void sell_stock (void)
814 {
815 struct stock_item *item;
816
817 if ((!docked) || (cmdr.current_cargo[hilite_item] == 0))
818 return;
819
820 item = &stock_market[hilite_item];
821
822 cmdr.current_cargo[hilite_item]--;
823 item->current_quantity++;
824 cmdr.credits += item->current_price;
825
826 highlight_stock (hilite_item);
827 }
828
829
830
831 void display_market_prices (void)
832 {
833 char str[100];
834 char planet_name[16];
835 int i;
836
837 current_screen = SCR_MARKET_PRICES;
838
839 gfx_clear_display();
840
841 name_planet (planet_name, docked_planet);
842 sprintf (str, "%s MARKET PRICES", planet_name);
843 gfx_display_centre_text (10, str, 140, GFX_COL_GOLD);
844
845 gfx_draw_line (0, 36, 511, 36);
846
847 gfx_display_colour_text (16, 40, "PRODUCT", GFX_COL_GREEN_1);
848 gfx_display_colour_text (166, 40, "UNIT", GFX_COL_GREEN_1);
849 gfx_display_colour_text (246, 40, "PRICE", GFX_COL_GREEN_1);
850 gfx_display_colour_text (314, 40, "FOR SALE", GFX_COL_GREEN_1);
851 gfx_display_colour_text (420, 40, "IN HOLD", GFX_COL_GREEN_1);
852
853 for (i = 0; i < 17; i++)
854 {
855 display_stock_price (i);
856 }
857
858 if (docked)
859 {
860 hilite_item = -1;
861 highlight_stock (0);
862 }
863 }
864
865
866 void display_inventory (void)
867 {
868 int i;
869 int y;
870 char str[80];
871
872 current_screen = SCR_INVENTORY;
873
874 gfx_clear_display();
875 gfx_display_centre_text (10, "INVENTORY", 140, GFX_COL_GOLD);
876 gfx_draw_line (0, 36, 511, 36);
877
878 sprintf (str, "%d.%d Light Years", cmdr.fuel / 10, cmdr.fuel % 10);
879 gfx_display_colour_text (16, 50, "Fuel:", GFX_COL_GREEN_1);
880 gfx_display_text (70, 50, str);
881
882 sprintf (str, "%d.%d Cr", cmdr.credits / 10, cmdr.credits % 10);
883 gfx_display_colour_text (16, 66, "Cash:", GFX_COL_GREEN_1);
884 gfx_display_text (70, 66, str);
885
886 y = 98;
887 for (i = 0; i < 17; i++)
888 {
889 if (cmdr.current_cargo[i] > 0)
890 {
891 gfx_display_text (16, y, stock_market[i].name);
892
893 sprintf (str, "%d%s", cmdr.current_cargo[i],
894 unit_name[stock_market[i].units]);
895
896 gfx_display_text (180, y, str);
897 y += 16;
898 }
899 }
900 }
901
902 /***********************************************************************************/
903
904 enum equip_types
905 {
906 EQ_FUEL, EQ_MISSILE, EQ_CARGO_BAY, EQ_ECM, EQ_FUEL_SCOOPS,
907 EQ_ESCAPE_POD, EQ_ENERGY_BOMB, EQ_ENERGY_UNIT, EQ_DOCK_COMP,
908 EQ_GAL_DRIVE, EQ_PULSE_LASER, EQ_FRONT_PULSE, EQ_REAR_PULSE,
909 EQ_LEFT_PULSE, EQ_RIGHT_PULSE, EQ_BEAM_LASER, EQ_FRONT_BEAM,
910 EQ_REAR_BEAM, EQ_LEFT_BEAM, EQ_RIGHT_BEAM, EQ_MINING_LASER,
911 EQ_FRONT_MINING, EQ_REAR_MINING, EQ_LEFT_MINING, EQ_RIGHT_MINING,
912 EQ_MILITARY_LASER, EQ_FRONT_MILITARY, EQ_REAR_MILITARY,
913 EQ_LEFT_MILITARY, EQ_RIGHT_MILITARY
914 };
915
916
917
918 #define NO_OF_EQUIP_ITEMS 34
919
920 struct equip_item
921 {
922 int canbuy;
923 int y;
924 int show;
925 int level;
926 int price;
927 char *name;
928 int type;
929 };
930
931 struct equip_item equip_stock[NO_OF_EQUIP_ITEMS] =
932 {
933 {0, 0, 1, 1, 2, " Fuel", EQ_FUEL},
934 {0, 0, 1, 1, 300, " Missile", EQ_MISSILE},
935 {0, 0, 1, 1, 4000, " Large Cargo Bay", EQ_CARGO_BAY},
936 {0, 0, 1, 2, 6000, " E.C.M. System", EQ_ECM},
937 {0, 0, 1, 5, 5250, " Fuel Scoops", EQ_FUEL_SCOOPS},
938 {0, 0, 1, 6, 10000, " Escape Pod", EQ_ESCAPE_POD},
939 {0, 0, 1, 7, 9000, " Energy Bomb", EQ_ENERGY_BOMB},
940 {0, 0, 1, 8, 15000, " Extra Energy Unit", EQ_ENERGY_UNIT},
941 {0, 0, 1, 9, 15000, " Docking Computers", EQ_DOCK_COMP},
942 {0, 0, 1,10, 50000, " Galactic Hyperdrive", EQ_GAL_DRIVE},
943 {0, 0, 0, 3, 4000, "+Pulse Laser", EQ_PULSE_LASER},
944 {0, 0, 1, 3, 0, "-Pulse Laser", EQ_PULSE_LASER},
945 {0, 0, 1, 3, 4000, ">Front", EQ_FRONT_PULSE},
946 {0, 0, 1, 3, 4000, ">Rear", EQ_REAR_PULSE},
947 {0, 0, 1, 3, 4000, ">Left", EQ_LEFT_PULSE},
948 {0, 0, 1, 3, 4000, ">Right", EQ_RIGHT_PULSE},
949 {0, 0, 1, 4, 10000, "+Beam Laser", EQ_BEAM_LASER},
950 {0, 0, 0, 4, 0, "-Beam Laser", EQ_BEAM_LASER},
951 {0, 0, 0, 4, 10000, ">Front", EQ_FRONT_BEAM},
952 {0, 0, 0, 4, 10000, ">Rear", EQ_REAR_BEAM},
953 {0, 0, 0, 4, 10000, ">Left", EQ_LEFT_BEAM},
954 {0, 0, 0, 4, 10000, ">Right", EQ_RIGHT_BEAM},
955 {0, 0, 1,10, 8000, "+Mining Laser", EQ_MINING_LASER},
956 {0, 0, 0,10, 0, "-Mining Laser", EQ_MINING_LASER},
957 {0, 0, 0,10, 8000, ">Front", EQ_FRONT_MINING},
958 {0, 0, 0,10, 8000, ">Rear", EQ_REAR_MINING},
959 {0, 0, 0,10, 8000, ">Left", EQ_LEFT_MINING},
960 {0, 0, 0,10, 8000, ">Right", EQ_RIGHT_MINING},
961 {0, 0, 1,10, 60000, "+Military Laser", EQ_MILITARY_LASER},
962 {0, 0, 0,10, 0, "-Military Laser", EQ_MILITARY_LASER},
963 {0, 0, 0,10, 60000, ">Front", EQ_FRONT_MILITARY},
964 {0, 0, 0,10, 60000, ">Rear", EQ_REAR_MILITARY},
965 {0, 0, 0,10, 60000, ">Left", EQ_LEFT_MILITARY},
966 {0, 0, 0,10, 60000, ">Right", EQ_RIGHT_MILITARY}
967 };
968
969
970 int equip_present (int type)
971 {
972 switch (type)
973 {
974 case EQ_FUEL:
975 return (cmdr.fuel >= 70);
976
977 case EQ_MISSILE:
978 return (cmdr.missiles >= 4);
979
980 case EQ_CARGO_BAY:
981 return (cmdr.cargo_capacity > 20);
982
983 case EQ_ECM:
984 return cmdr.ecm;
985
986 case EQ_FUEL_SCOOPS:
987 return cmdr.fuel_scoop;
988
989 case EQ_ESCAPE_POD:
990 return cmdr.escape_pod;
991
992 case EQ_ENERGY_BOMB:
993 return cmdr.energy_bomb;
994
995 case EQ_ENERGY_UNIT:
996 return cmdr.energy_unit;
997
998 case EQ_DOCK_COMP:
999 return cmdr.docking_computer;
1000
1001 case EQ_GAL_DRIVE:
1002 return cmdr.galactic_hyperdrive;
1003
1004 case EQ_FRONT_PULSE:
1005 return (cmdr.front_laser == PULSE_LASER);
1006
1007 case EQ_REAR_PULSE:
1008 return (cmdr.rear_laser == PULSE_LASER);
1009
1010 case EQ_LEFT_PULSE:
1011 return (cmdr.left_laser == PULSE_LASER);
1012
1013 case EQ_RIGHT_PULSE:
1014 return (cmdr.right_laser == PULSE_LASER);
1015
1016 case EQ_FRONT_BEAM:
1017 return (cmdr.front_laser == BEAM_LASER);
1018
1019 case EQ_REAR_BEAM:
1020 return (cmdr.rear_laser == BEAM_LASER);
1021
1022 case EQ_LEFT_BEAM:
1023 return (cmdr.left_laser == BEAM_LASER);
1024
1025 case EQ_RIGHT_BEAM:
1026 return (cmdr.right_laser == BEAM_LASER);
1027
1028 case EQ_FRONT_MINING:
1029 return (cmdr.front_laser == MINING_LASER);
1030
1031 case EQ_REAR_MINING:
1032 return (cmdr.rear_laser == MINING_LASER);
1033
1034 case EQ_LEFT_MINING:
1035 return (cmdr.left_laser == MINING_LASER);
1036
1037 case EQ_RIGHT_MINING:
1038 return (cmdr.right_laser == MINING_LASER);
1039
1040 case EQ_FRONT_MILITARY:
1041 return (cmdr.front_laser == MILITARY_LASER);
1042
1043 case EQ_REAR_MILITARY:
1044 return (cmdr.rear_laser == MILITARY_LASER);
1045
1046 case EQ_LEFT_MILITARY:
1047 return (cmdr.left_laser == MILITARY_LASER);
1048
1049 case EQ_RIGHT_MILITARY:
1050 return (cmdr.right_laser == MILITARY_LASER);
1051 }
1052
1053 return 0;
1054 }
1055
1056
1057 void display_equip_price (int i)
1058 {
1059 int x, y;
1060 int col;
1061 char str[100];
1062
1063 y = equip_stock[i].y;
1064 if (y == 0)
1065 return;
1066
1067 col = equip_stock[i].canbuy ? GFX_COL_WHITE : GFX_COL_GREY_1;
1068
1069 x = *(equip_stock[i].name) == '>' ? 50 : 16;
1070
1071 gfx_display_colour_text (x, y, &equip_stock[i].name[1], col);
1072
1073 if (equip_stock[i].price != 0)
1074 {
1075 sprintf (str, "%d.%d", equip_stock[i].price / 10, equip_stock[i].price % 10);
1076 gfx_display_colour_text (338, y, str, col);
1077 }
1078 }
1079
1080
1081 void highlight_equip (int i)
1082 {
1083 int y;
1084 char str[30];
1085
1086 if ((hilite_item != -1) && (hilite_item != i))
1087 {
1088 y = equip_stock[hilite_item].y;
1089 gfx_clear_area (2, y+1, 510, y + 15);
1090 display_equip_price (hilite_item);
1091 }
1092
1093 y = equip_stock[i].y;
1094
1095 gfx_draw_rectangle (2, y+1, 510, y + 15, GFX_COL_DARK_RED);
1096 display_equip_price (i);
1097
1098 hilite_item = i;
1099
1100 gfx_clear_text_area();
1101 sprintf (str, "Cash: %d.%d", cmdr.credits / 10, cmdr.credits % 10);
1102 gfx_display_text (16, 340, str);
1103 }
1104
1105
1106 void select_next_equip (void)
1107 {
1108 int next;
1109 int i;
1110
1111 if (hilite_item == (NO_OF_EQUIP_ITEMS - 1))
1112 return;
1113
1114 next = hilite_item;
1115 for (i = hilite_item + 1; i < NO_OF_EQUIP_ITEMS; i++)
1116 {
1117 if (equip_stock[i].y != 0)
1118 {
1119 next = i;
1120 break;
1121 }
1122 }
1123
1124 if (next != hilite_item)
1125 highlight_equip (next);
1126 }
1127
1128 void select_previous_equip (void)
1129 {
1130 int i;
1131 int prev;
1132
1133 if (hilite_item == 0)
1134 return;
1135
1136 prev = hilite_item;
1137 for (i = hilite_item - 1; i >= 0; i--)
1138 {
1139 if (equip_stock[i].y != 0)
1140 {
1141 prev = i;
1142 break;
1143 }
1144 }
1145
1146 if (prev != hilite_item)
1147 highlight_equip (prev);
1148 }
1149
1150
1151 void list_equip_prices (void)
1152 {
1153 int i;
1154 int y;
1155 int tech_level;
1156
1157 gfx_clear_area (2, 55, 510, 380);
1158
1159 tech_level = current_planet_data.techlevel + 1;
1160
1161 equip_stock[0].price = (70 - cmdr.fuel) * 2;
1162
1163 y = 55;
1164 for (i = 0; i < NO_OF_EQUIP_ITEMS; i++)
1165 {
1166 equip_stock[i].canbuy = ((equip_present (equip_stock[i].type) == 0) &&
1167 (equip_stock[i].price <= cmdr.credits));
1168
1169 if (equip_stock[i].show && (tech_level >= equip_stock[i].level))
1170 {
1171 equip_stock[i].y = y;
1172 y += 15;
1173 }
1174 else
1175 equip_stock[i].y = 0;
1176
1177 display_equip_price (i);
1178 }
1179
1180 i = hilite_item;
1181 hilite_item = -1;
1182 highlight_equip (i);
1183 }
1184
1185
1186 void collapse_equip_list (void)
1187 {
1188 int i;
1189 int ch;
1190
1191 for (i = 0; i < NO_OF_EQUIP_ITEMS; i++)
1192 {
1193 ch = *(equip_stock[i].name);
1194 equip_stock[i].show = ((ch == ' ') || (ch == '+'));
1195 }
1196 }
1197
1198
1199 int laser_refund (int laser_type)
1200 {
1201 switch (laser_type)
1202 {
1203 case PULSE_LASER:
1204 return 4000;
1205
1206 case BEAM_LASER:
1207 return 10000;
1208
1209 case MILITARY_LASER:
1210 return 60000;
1211
1212 case MINING_LASER:
1213 return 8000;
1214 }
1215
1216 return 0;
1217 }
1218
1219
1220 void buy_equip (void)
1221 {
1222 int i;
1223
1224 if (equip_stock[hilite_item].name[0] == '+')
1225 {
1226 collapse_equip_list();
1227 equip_stock[hilite_item].show = 0;
1228 hilite_item++;
1229 for (i = 0; i < 5; i++)
1230 equip_stock[hilite_item + i].show = 1;
1231
1232 list_equip_prices();
1233 return;
1234 }
1235
1236 if (equip_stock[hilite_item].canbuy == 0)
1237 return;
1238
1239 switch (equip_stock[hilite_item].type)
1240 {
1241 case EQ_FUEL:
1242 cmdr.fuel = myship.max_fuel;
1243 update_console();
1244 break;
1245
1246 case EQ_MISSILE:
1247 cmdr.missiles++;
1248 update_console();
1249 break;
1250
1251 case EQ_CARGO_BAY:
1252 cmdr.cargo_capacity = 35;
1253 break;
1254
1255 case EQ_ECM:
1256 cmdr.ecm = 1;
1257 break;
1258
1259 case EQ_FUEL_SCOOPS:
1260 cmdr.fuel_scoop = 1;
1261 break;
1262
1263 case EQ_ESCAPE_POD:
1264 cmdr.escape_pod = 1;
1265 break;
1266
1267 case EQ_ENERGY_BOMB:
1268 cmdr.energy_bomb = 1;
1269 break;
1270
1271 case EQ_ENERGY_UNIT:
1272 cmdr.energy_unit = 1;
1273 break;
1274
1275 case EQ_DOCK_COMP:
1276 cmdr.docking_computer = 1;
1277 break;
1278
1279 case EQ_GAL_DRIVE:
1280 cmdr.galactic_hyperdrive = 1;
1281 break;
1282
1283 case EQ_FRONT_PULSE:
1284 cmdr.credits += laser_refund (cmdr.front_laser);
1285 cmdr.front_laser = PULSE_LASER;
1286 break;
1287
1288 case EQ_REAR_PULSE:
1289 cmdr.credits += laser_refund (cmdr.rear_laser);
1290 cmdr.rear_laser = PULSE_LASER;
1291 break;
1292
1293 case EQ_LEFT_PULSE:
1294 cmdr.credits += laser_refund (cmdr.left_laser);
1295 cmdr.left_laser = PULSE_LASER;
1296 break;
1297
1298 case EQ_RIGHT_PULSE:
1299 cmdr.credits += laser_refund (cmdr.right_laser);
1300 cmdr.right_laser = PULSE_LASER;
1301 break;
1302
1303 case EQ_FRONT_BEAM:
1304 cmdr.credits += laser_refund (cmdr.front_laser);
1305 cmdr.front_laser = BEAM_LASER;
1306 break;
1307
1308 case EQ_REAR_BEAM:
1309 cmdr.credits += laser_refund (cmdr.rear_laser);
1310 cmdr.rear_laser = BEAM_LASER;
1311 break;
1312
1313 case EQ_LEFT_BEAM:
1314 cmdr.credits += laser_refund (cmdr.left_laser);
1315 cmdr.left_laser = BEAM_LASER;
1316 break;
1317
1318 case EQ_RIGHT_BEAM:
1319 cmdr.credits += laser_refund (cmdr.right_laser);
1320 cmdr.right_laser = BEAM_LASER;
1321 break;
1322
1323 case EQ_FRONT_MINING:
1324 cmdr.credits += laser_refund (cmdr.front_laser);
1325 cmdr.front_laser = MINING_LASER;
1326 break;
1327
1328 case EQ_REAR_MINING:
1329 cmdr.credits += laser_refund (cmdr.rear_laser);
1330 cmdr.rear_laser = MINING_LASER;
1331 break;
1332
1333 case EQ_LEFT_MINING:
1334 cmdr.credits += laser_refund (cmdr.left_laser);
1335 cmdr.left_laser = MINING_LASER;
1336 break;
1337
1338 case EQ_RIGHT_MINING:
1339 cmdr.credits += laser_refund (cmdr.right_laser);
1340 cmdr.right_laser = MINING_LASER;
1341 break;
1342
1343 case EQ_FRONT_MILITARY:
1344 cmdr.credits += laser_refund (cmdr.front_laser);
1345 cmdr.front_laser = MILITARY_LASER;
1346 break;
1347
1348 case EQ_REAR_MILITARY:
1349 cmdr.credits += laser_refund (cmdr.rear_laser);
1350 cmdr.rear_laser = MILITARY_LASER;
1351 break;
1352
1353 case EQ_LEFT_MILITARY:
1354 cmdr.credits += laser_refund (cmdr.left_laser);
1355 cmdr.left_laser = MILITARY_LASER;
1356 break;
1357
1358 case EQ_RIGHT_MILITARY:
1359 cmdr.credits += laser_refund (cmdr.right_laser);
1360 cmdr.right_laser = MILITARY_LASER;
1361 break;
1362 }
1363
1364 cmdr.credits -= equip_stock[hilite_item].price;
1365 list_equip_prices();
1366 }
1367
1368
1369 void equip_ship (void)
1370 {
1371 current_screen = SCR_EQUIP_SHIP;
1372
1373 gfx_clear_display();
1374 gfx_display_centre_text (10, "EQUIP SHIP", 140, GFX_COL_GOLD);
1375 gfx_draw_line (0, 36, 511, 36);
1376
1377 collapse_equip_list();
1378
1379 hilite_item = 0;
1380
1381 list_equip_prices();
1382 }