Proper Subversion configuration.
[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 #include "keyboard.h"
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 "Red"
502 };
503
504 void display_commander_status (void)
505 {
506 char planet_name[16];
507 char str[100];
508 int i;
509 int x,y;
510
511 current_screen = SCR_CMDR_STATUS;
512
513 gfx_clear_display();
514
515 sprintf (str, "COMMANDER %s", cmdr.name);
516
517 gfx_display_centre_text (10, str, 140, GFX_COL_GOLD);
518
519 gfx_draw_line (0, 36, 511, 36);
520
521
522 gfx_display_colour_text (16, 58, "Present System:", GFX_COL_GREEN_1);
523
524 if (!witchspace)
525 {
526 name_planet (planet_name, docked_planet);
527 capitalise_name (planet_name);
528 sprintf (str, "%s", planet_name);
529 gfx_display_text (190, 58, str);
530 }
531
532 gfx_display_colour_text (16, 74, "Hyperspace System:", GFX_COL_GREEN_1);
533 name_planet (planet_name, hyperspace_planet);
534 capitalise_name (planet_name);
535 sprintf (str, "%s", planet_name);
536 gfx_display_text (190, 74, str);
537
538 gfx_display_colour_text (16, 90, "Condition:", GFX_COL_GREEN_1);
539 gfx_display_text (190, 90, condition_txt[condition]);
540
541 sprintf (str, "%d.%d Light Years", cmdr.fuel / 10, cmdr.fuel % 10);
542 gfx_display_colour_text (16, 106, "Fuel:", GFX_COL_GREEN_1);
543 gfx_display_text (70, 106, str);
544
545 sprintf (str, "%d.%d Cr", cmdr.credits / 10, cmdr.credits % 10);
546 gfx_display_colour_text (16, 122, "Cash:", GFX_COL_GREEN_1);
547 gfx_display_text (70, 122, str);
548
549 if (cmdr.legal_status == 0)
550 strcpy (str, "Clean");
551 else
552 strcpy (str, cmdr.legal_status > 50 ? "Fugitive" : "Offender");
553
554 gfx_display_colour_text (16, 138, "Legal Status:", GFX_COL_GREEN_1);
555 gfx_display_text (128, 138, str);
556
557 for (i = 0; i < NO_OF_RANKS; i++)
558 if (cmdr.score >= rating[i].score)
559 strcpy (str, rating[i].title);
560
561 gfx_display_colour_text (16, 154, "Rating:", GFX_COL_GREEN_1);
562 gfx_display_text (80, 154, str);
563
564 gfx_display_colour_text (16, 186, "EQUIPMENT:", GFX_COL_GREEN_1);
565
566 x = EQUIP_START_X;
567 y = EQUIP_START_Y;
568
569 if (cmdr.cargo_capacity > 20)
570 {
571 gfx_display_text (x, y, "Large Cargo Bay");
572 y += Y_INC;
573 }
574
575 if (cmdr.escape_pod)
576 {
577 gfx_display_text (x, y, "Escape Pod");
578 y += Y_INC;
579 }
580
581 if (cmdr.fuel_scoop)
582 {
583 gfx_display_text (x, y, "Fuel Scoops");
584 y += Y_INC;
585 }
586
587 if (cmdr.ecm)
588 {
589 gfx_display_text (x, y, "E.C.M. System");
590 y += Y_INC;
591 }
592
593 if (cmdr.energy_bomb)
594 {
595 gfx_display_text (x, y, "Energy Bomb");
596 y += Y_INC;
597 }
598
599 if (cmdr.energy_unit)
600 {
601 gfx_display_text (x, y,
602 cmdr.energy_unit == 1 ? "Extra Energy Unit" :"Naval Energy Unit");
603 y += Y_INC;
604 if (y > EQUIP_MAX_Y)
605 {
606 y = EQUIP_START_Y;
607 x += EQUIP_WIDTH;
608 }
609 }
610
611 if (cmdr.docking_computer)
612 {
613 gfx_display_text (x, y, "Docking Computers");
614 y += Y_INC;
615 if (y > EQUIP_MAX_Y)
616 {
617 y = EQUIP_START_Y;
618 x += EQUIP_WIDTH;
619 }
620 }
621
622
623 if (cmdr.galactic_hyperdrive)
624 {
625 gfx_display_text (x, y, "Galactic Hyperspace");
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.front_laser)
635 {
636 sprintf (str, "Front %s Laser", laser_type(cmdr.front_laser));
637 gfx_display_text (x, y, str);
638 y += Y_INC;
639 if (y > EQUIP_MAX_Y)
640 {
641 y = EQUIP_START_Y;
642 x += EQUIP_WIDTH;
643 }
644 }
645
646 if (cmdr.rear_laser)
647 {
648 sprintf (str, "Rear %s Laser", laser_type(cmdr.rear_laser));
649 gfx_display_text (x, y, str);
650 y += Y_INC;
651 if (y > EQUIP_MAX_Y)
652 {
653 y = EQUIP_START_Y;
654 x += EQUIP_WIDTH;
655 }
656 }
657
658 if (cmdr.left_laser)
659 {
660 sprintf (str, "Left %s Laser", laser_type(cmdr.left_laser));
661 gfx_display_text (x, y, str);
662 y += Y_INC;
663 if (y > EQUIP_MAX_Y)
664 {
665 y = EQUIP_START_Y;
666 x += EQUIP_WIDTH;
667 }
668 }
669
670 if (cmdr.right_laser)
671 {
672 sprintf (str, "Right %s Laser", laser_type(cmdr.right_laser));
673 gfx_display_text (x, y, str);
674 }
675 }
676
677
678
679 /***********************************************************************************/
680
681 #define TONNES 0
682 #define KILOGRAMS 1
683 #define GRAMS 2
684
685 static int hilite_item;
686 static char *unit_name[] = {"t", "kg", "g"};
687
688
689 void display_stock_price (int i)
690 {
691 int y;
692 char str[100];
693
694 y = i * 15 + 55;
695
696 gfx_display_text (16, y, stock_market[i].name);
697
698 gfx_display_text (180, y, unit_name[stock_market[i].units]);
699 sprintf (str, "%d.%d", stock_market[i].current_price / 10,
700 stock_market[i].current_price % 10);
701 gfx_display_text (256, y, str);
702
703 if (stock_market[i].current_quantity > 0)
704 sprintf (str, "%d%s", stock_market[i].current_quantity,
705 unit_name[stock_market[i].units]);
706 else
707 strcpy (str, "-");
708
709 gfx_display_text (338, y, str);
710
711 if (cmdr.current_cargo[i] > 0)
712 sprintf (str, "%d%s", cmdr.current_cargo[i],
713 unit_name[stock_market[i].units]);
714 else
715 strcpy (str, "-");
716
717 gfx_display_text (444, y, str);
718 }
719
720
721 void highlight_stock (int i)
722 {
723 int y;
724 char str[30];
725
726 if ((hilite_item != -1) && (hilite_item != i))
727 {
728 y = hilite_item * 15 + 55;
729 gfx_clear_area (2, y, 510, y + 15);
730 display_stock_price (hilite_item);
731 }
732
733 y = i * 15 + 55;
734
735 gfx_draw_rectangle (2, y, 510, y + 15, GFX_COL_DARK_RED);
736 display_stock_price (i);
737
738 hilite_item = i;
739
740 gfx_clear_text_area();
741 sprintf (str, "Cash: %d.%d", cmdr.credits / 10, cmdr.credits % 10);
742 gfx_display_text (16, 340, str);
743 }
744
745 void select_previous_stock (void)
746 {
747 if ((!docked) || (hilite_item == 0))
748 return;
749
750 highlight_stock (hilite_item - 1);
751 }
752
753 void select_next_stock (void)
754 {
755 if ((!docked) || (hilite_item == 16))
756 return;
757
758 highlight_stock (hilite_item + 1);
759 }
760
761
762 void buy_stock (void)
763 {
764 struct stock_item *item;
765 int cargo_held;
766
767 if (!docked)
768 return;
769
770 item = &stock_market[hilite_item];
771
772 do {
773 if ((item->current_quantity == 0) ||
774 (cmdr.credits < item->current_price))
775 return;
776
777 cargo_held = total_cargo();
778
779 if ((item->units == TONNES) &&
780 (cargo_held == cmdr.cargo_capacity))
781 return;
782
783 cmdr.current_cargo[hilite_item]++;
784 item->current_quantity--;
785 cmdr.credits -= item->current_price;
786
787 highlight_stock (hilite_item);
788 } while (kbd_ctrl_pressed);
789 }
790
791
792 void sell_stock (void)
793 {
794 struct stock_item *item;
795
796 do {
797 if ((!docked) || (cmdr.current_cargo[hilite_item] == 0))
798 return;
799
800 item = &stock_market[hilite_item];
801
802 cmdr.current_cargo[hilite_item]--;
803 item->current_quantity++;
804 cmdr.credits += item->current_price;
805
806 highlight_stock (hilite_item);
807 } while (kbd_ctrl_pressed);
808 }
809
810
811
812 void display_market_prices (void)
813 {
814 char str[100];
815 char planet_name[16];
816 int i;
817
818 current_screen = SCR_MARKET_PRICES;
819
820 gfx_clear_display();
821
822 name_planet (planet_name, docked_planet);
823 sprintf (str, "%s MARKET PRICES", planet_name);
824 gfx_display_centre_text (10, str, 140, GFX_COL_GOLD);
825
826 gfx_draw_line (0, 36, 511, 36);
827
828 gfx_display_colour_text (16, 40, "PRODUCT", GFX_COL_GREEN_1);
829 gfx_display_colour_text (166, 40, "UNIT", GFX_COL_GREEN_1);
830 gfx_display_colour_text (246, 40, "PRICE", GFX_COL_GREEN_1);
831 gfx_display_colour_text (314, 40, "FOR SALE", GFX_COL_GREEN_1);
832 gfx_display_colour_text (420, 40, "IN HOLD", GFX_COL_GREEN_1);
833
834 for (i = 0; i < 17; i++)
835 {
836 display_stock_price (i);
837 }
838
839 if (docked)
840 {
841 hilite_item = -1;
842 highlight_stock (0);
843 }
844 }
845
846
847 void display_inventory (void)
848 {
849 int i;
850 int y;
851 char str[80];
852
853 current_screen = SCR_INVENTORY;
854
855 gfx_clear_display();
856 gfx_display_centre_text (10, "INVENTORY", 140, GFX_COL_GOLD);
857 gfx_draw_line (0, 36, 511, 36);
858
859 sprintf (str, "%d.%d Light Years", cmdr.fuel / 10, cmdr.fuel % 10);
860 gfx_display_colour_text (16, 50, "Fuel:", GFX_COL_GREEN_1);
861 gfx_display_text (70, 50, str);
862
863 sprintf (str, "%d.%d Cr", cmdr.credits / 10, cmdr.credits % 10);
864 gfx_display_colour_text (16, 66, "Cash:", GFX_COL_GREEN_1);
865 gfx_display_text (70, 66, str);
866
867 y = 98;
868 for (i = 0; i < 17; i++)
869 {
870 if (cmdr.current_cargo[i] > 0)
871 {
872 gfx_display_text (16, y, stock_market[i].name);
873
874 sprintf (str, "%d%s", cmdr.current_cargo[i],
875 unit_name[stock_market[i].units]);
876
877 gfx_display_text (180, y, str);
878 y += 16;
879 }
880 }
881 }
882
883 /***********************************************************************************/
884
885 enum equip_types
886 {
887 EQ_FUEL, EQ_MISSILE, EQ_CARGO_BAY, EQ_ECM, EQ_FUEL_SCOOPS,
888 EQ_ESCAPE_POD, EQ_ENERGY_BOMB, EQ_ENERGY_UNIT, EQ_DOCK_COMP,
889 EQ_GAL_DRIVE, EQ_PULSE_LASER, EQ_FRONT_PULSE, EQ_REAR_PULSE,
890 EQ_LEFT_PULSE, EQ_RIGHT_PULSE, EQ_BEAM_LASER, EQ_FRONT_BEAM,
891 EQ_REAR_BEAM, EQ_LEFT_BEAM, EQ_RIGHT_BEAM, EQ_MINING_LASER,
892 EQ_FRONT_MINING, EQ_REAR_MINING, EQ_LEFT_MINING, EQ_RIGHT_MINING,
893 EQ_MILITARY_LASER, EQ_FRONT_MILITARY, EQ_REAR_MILITARY,
894 EQ_LEFT_MILITARY, EQ_RIGHT_MILITARY
895 };
896
897
898
899 #define NO_OF_EQUIP_ITEMS 34
900
901 struct equip_item
902 {
903 int canbuy;
904 int y;
905 int show;
906 int level;
907 int price;
908 char *name;
909 int type;
910 };
911
912 struct equip_item equip_stock[NO_OF_EQUIP_ITEMS] =
913 {
914 {0, 0, 1, 1, 2, " Fuel", EQ_FUEL},
915 {0, 0, 1, 1, 300, " Missile", EQ_MISSILE},
916 {0, 0, 1, 1, 4000, " Large Cargo Bay", EQ_CARGO_BAY},
917 {0, 0, 1, 2, 6000, " E.C.M. System", EQ_ECM},
918 {0, 0, 1, 5, 5250, " Fuel Scoops", EQ_FUEL_SCOOPS},
919 {0, 0, 1, 6, 10000, " Escape Pod", EQ_ESCAPE_POD},
920 {0, 0, 1, 7, 9000, " Energy Bomb", EQ_ENERGY_BOMB},
921 {0, 0, 1, 8, 15000, " Extra Energy Unit", EQ_ENERGY_UNIT},
922 {0, 0, 1, 9, 15000, " Docking Computers", EQ_DOCK_COMP},
923 {0, 0, 1,10, 50000, " Galactic Hyperdrive", EQ_GAL_DRIVE},
924 {0, 0, 0, 3, 4000, "+Pulse Laser", EQ_PULSE_LASER},
925 {0, 0, 1, 3, 0, "-Pulse Laser", EQ_PULSE_LASER},
926 {0, 0, 1, 3, 4000, ">Front", EQ_FRONT_PULSE},
927 {0, 0, 1, 3, 4000, ">Rear", EQ_REAR_PULSE},
928 {0, 0, 1, 3, 4000, ">Left", EQ_LEFT_PULSE},
929 {0, 0, 1, 3, 4000, ">Right", EQ_RIGHT_PULSE},
930 {0, 0, 1, 4, 10000, "+Beam Laser", EQ_BEAM_LASER},
931 {0, 0, 0, 4, 0, "-Beam Laser", EQ_BEAM_LASER},
932 {0, 0, 0, 4, 10000, ">Front", EQ_FRONT_BEAM},
933 {0, 0, 0, 4, 10000, ">Rear", EQ_REAR_BEAM},
934 {0, 0, 0, 4, 10000, ">Left", EQ_LEFT_BEAM},
935 {0, 0, 0, 4, 10000, ">Right", EQ_RIGHT_BEAM},
936 {0, 0, 1,10, 8000, "+Mining Laser", EQ_MINING_LASER},
937 {0, 0, 0,10, 0, "-Mining Laser", EQ_MINING_LASER},
938 {0, 0, 0,10, 8000, ">Front", EQ_FRONT_MINING},
939 {0, 0, 0,10, 8000, ">Rear", EQ_REAR_MINING},
940 {0, 0, 0,10, 8000, ">Left", EQ_LEFT_MINING},
941 {0, 0, 0,10, 8000, ">Right", EQ_RIGHT_MINING},
942 {0, 0, 1,10, 60000, "+Military Laser", EQ_MILITARY_LASER},
943 {0, 0, 0,10, 0, "-Military Laser", EQ_MILITARY_LASER},
944 {0, 0, 0,10, 60000, ">Front", EQ_FRONT_MILITARY},
945 {0, 0, 0,10, 60000, ">Rear", EQ_REAR_MILITARY},
946 {0, 0, 0,10, 60000, ">Left", EQ_LEFT_MILITARY},
947 {0, 0, 0,10, 60000, ">Right", EQ_RIGHT_MILITARY}
948 };
949
950
951 int equip_present (int type)
952 {
953 switch (type)
954 {
955 case EQ_FUEL:
956 return (cmdr.fuel >= 70);
957
958 case EQ_MISSILE:
959 return (cmdr.missiles >= 4);
960
961 case EQ_CARGO_BAY:
962 return (cmdr.cargo_capacity > 20);
963
964 case EQ_ECM:
965 return cmdr.ecm;
966
967 case EQ_FUEL_SCOOPS:
968 return cmdr.fuel_scoop;
969
970 case EQ_ESCAPE_POD:
971 return cmdr.escape_pod;
972
973 case EQ_ENERGY_BOMB:
974 return cmdr.energy_bomb;
975
976 case EQ_ENERGY_UNIT:
977 return cmdr.energy_unit;
978
979 case EQ_DOCK_COMP:
980 return cmdr.docking_computer;
981
982 case EQ_GAL_DRIVE:
983 return cmdr.galactic_hyperdrive;
984
985 case EQ_FRONT_PULSE:
986 return (cmdr.front_laser == PULSE_LASER);
987
988 case EQ_REAR_PULSE:
989 return (cmdr.rear_laser == PULSE_LASER);
990
991 case EQ_LEFT_PULSE:
992 return (cmdr.left_laser == PULSE_LASER);
993
994 case EQ_RIGHT_PULSE:
995 return (cmdr.right_laser == PULSE_LASER);
996
997 case EQ_FRONT_BEAM:
998 return (cmdr.front_laser == BEAM_LASER);
999
1000 case EQ_REAR_BEAM:
1001 return (cmdr.rear_laser == BEAM_LASER);
1002
1003 case EQ_LEFT_BEAM:
1004 return (cmdr.left_laser == BEAM_LASER);
1005
1006 case EQ_RIGHT_BEAM:
1007 return (cmdr.right_laser == BEAM_LASER);
1008
1009 case EQ_FRONT_MINING:
1010 return (cmdr.front_laser == MINING_LASER);
1011
1012 case EQ_REAR_MINING:
1013 return (cmdr.rear_laser == MINING_LASER);
1014
1015 case EQ_LEFT_MINING:
1016 return (cmdr.left_laser == MINING_LASER);
1017
1018 case EQ_RIGHT_MINING:
1019 return (cmdr.right_laser == MINING_LASER);
1020
1021 case EQ_FRONT_MILITARY:
1022 return (cmdr.front_laser == MILITARY_LASER);
1023
1024 case EQ_REAR_MILITARY:
1025 return (cmdr.rear_laser == MILITARY_LASER);
1026
1027 case EQ_LEFT_MILITARY:
1028 return (cmdr.left_laser == MILITARY_LASER);
1029
1030 case EQ_RIGHT_MILITARY:
1031 return (cmdr.right_laser == MILITARY_LASER);
1032 }
1033
1034 return 0;
1035 }
1036
1037
1038 void display_equip_price (int i)
1039 {
1040 int x, y;
1041 int col;
1042 char str[100];
1043
1044 y = equip_stock[i].y;
1045 if (y == 0)
1046 return;
1047
1048 col = equip_stock[i].canbuy ? GFX_COL_WHITE : GFX_COL_GREY_1;
1049
1050 x = *(equip_stock[i].name) == '>' ? 50 : 16;
1051
1052 gfx_display_colour_text (x, y, &equip_stock[i].name[1], col);
1053
1054 if (equip_stock[i].price != 0)
1055 {
1056 sprintf (str, "%d.%d", equip_stock[i].price / 10, equip_stock[i].price % 10);
1057 gfx_display_colour_text (338, y, str, col);
1058 }
1059 }
1060
1061
1062 void highlight_equip (int i)
1063 {
1064 int y;
1065 char str[30];
1066
1067 if ((hilite_item != -1) && (hilite_item != i))
1068 {
1069 y = equip_stock[hilite_item].y;
1070 gfx_clear_area (2, y+1, 510, y + 15);
1071 display_equip_price (hilite_item);
1072 }
1073
1074 y = equip_stock[i].y;
1075
1076 gfx_draw_rectangle (2, y+1, 510, y + 15, GFX_COL_DARK_RED);
1077 display_equip_price (i);
1078
1079 hilite_item = i;
1080
1081 gfx_clear_text_area();
1082 sprintf (str, "Cash: %d.%d", cmdr.credits / 10, cmdr.credits % 10);
1083 gfx_display_text (16, 340, str);
1084 }
1085
1086
1087 void select_next_equip (void)
1088 {
1089 int next;
1090 int i;
1091
1092 if (hilite_item == (NO_OF_EQUIP_ITEMS - 1))
1093 return;
1094
1095 next = hilite_item;
1096 for (i = hilite_item + 1; i < NO_OF_EQUIP_ITEMS; i++)
1097 {
1098 if (equip_stock[i].y != 0)
1099 {
1100 next = i;
1101 break;
1102 }
1103 }
1104
1105 if (next != hilite_item)
1106 highlight_equip (next);
1107 }
1108
1109 void select_previous_equip (void)
1110 {
1111 int i;
1112 int prev;
1113
1114 if (hilite_item == 0)
1115 return;
1116
1117 prev = hilite_item;
1118 for (i = hilite_item - 1; i >= 0; i--)
1119 {
1120 if (equip_stock[i].y != 0)
1121 {
1122 prev = i;
1123 break;
1124 }
1125 }
1126
1127 if (prev != hilite_item)
1128 highlight_equip (prev);
1129 }
1130
1131
1132 void list_equip_prices (void)
1133 {
1134 int i;
1135 int y;
1136 int tech_level;
1137
1138 gfx_clear_area (2, 55, 510, 380);
1139
1140 tech_level = current_planet_data.techlevel + 1;
1141
1142 equip_stock[0].price = (70 - cmdr.fuel) * 2;
1143
1144 y = 55;
1145 for (i = 0; i < NO_OF_EQUIP_ITEMS; i++)
1146 {
1147 equip_stock[i].canbuy = ((equip_present (equip_stock[i].type) == 0) &&
1148 (equip_stock[i].price <= cmdr.credits));
1149
1150 if (equip_stock[i].show && (tech_level >= equip_stock[i].level))
1151 {
1152 equip_stock[i].y = y;
1153 y += 15;
1154 }
1155 else
1156 equip_stock[i].y = 0;
1157
1158 display_equip_price (i);
1159 }
1160
1161 i = hilite_item;
1162 hilite_item = -1;
1163 highlight_equip (i);
1164 }
1165
1166
1167 void collapse_equip_list (void)
1168 {
1169 int i;
1170 int ch;
1171
1172 for (i = 0; i < NO_OF_EQUIP_ITEMS; i++)
1173 {
1174 ch = *(equip_stock[i].name);
1175 equip_stock[i].show = ((ch == ' ') || (ch == '+'));
1176 }
1177 }
1178
1179
1180 int laser_refund (int laser_type)
1181 {
1182 switch (laser_type)
1183 {
1184 case PULSE_LASER:
1185 return 4000;
1186
1187 case BEAM_LASER:
1188 return 10000;
1189
1190 case MILITARY_LASER:
1191 return 60000;
1192
1193 case MINING_LASER:
1194 return 8000;
1195 }
1196
1197 return 0;
1198 }
1199
1200
1201 void buy_equip (void)
1202 {
1203 int i;
1204
1205 if (equip_stock[hilite_item].name[0] == '+')
1206 {
1207 collapse_equip_list();
1208 equip_stock[hilite_item].show = 0;
1209 hilite_item++;
1210 for (i = 0; i < 5; i++)
1211 equip_stock[hilite_item + i].show = 1;
1212
1213 list_equip_prices();
1214 return;
1215 }
1216
1217 if (equip_stock[hilite_item].canbuy == 0)
1218 return;
1219
1220 switch (equip_stock[hilite_item].type)
1221 {
1222 case EQ_FUEL:
1223 cmdr.fuel = myship.max_fuel;
1224 update_console();
1225 break;
1226
1227 case EQ_MISSILE:
1228 cmdr.missiles++;
1229 update_console();
1230 break;
1231
1232 case EQ_CARGO_BAY:
1233 cmdr.cargo_capacity = 35;
1234 break;
1235
1236 case EQ_ECM:
1237 cmdr.ecm = 1;
1238 break;
1239
1240 case EQ_FUEL_SCOOPS:
1241 cmdr.fuel_scoop = 1;
1242 break;
1243
1244 case EQ_ESCAPE_POD:
1245 cmdr.escape_pod = 1;
1246 break;
1247
1248 case EQ_ENERGY_BOMB:
1249 cmdr.energy_bomb = 1;
1250 break;
1251
1252 case EQ_ENERGY_UNIT:
1253 cmdr.energy_unit = 1;
1254 break;
1255
1256 case EQ_DOCK_COMP:
1257 cmdr.docking_computer = 1;
1258 break;
1259
1260 case EQ_GAL_DRIVE:
1261 cmdr.galactic_hyperdrive = 1;
1262 break;
1263
1264 case EQ_FRONT_PULSE:
1265 cmdr.credits += laser_refund (cmdr.front_laser);
1266 cmdr.front_laser = PULSE_LASER;
1267 break;
1268
1269 case EQ_REAR_PULSE:
1270 cmdr.credits += laser_refund (cmdr.rear_laser);
1271 cmdr.rear_laser = PULSE_LASER;
1272 break;
1273
1274 case EQ_LEFT_PULSE:
1275 cmdr.credits += laser_refund (cmdr.left_laser);
1276 cmdr.left_laser = PULSE_LASER;
1277 break;
1278
1279 case EQ_RIGHT_PULSE:
1280 cmdr.credits += laser_refund (cmdr.right_laser);
1281 cmdr.right_laser = PULSE_LASER;
1282 break;
1283
1284 case EQ_FRONT_BEAM:
1285 cmdr.credits += laser_refund (cmdr.front_laser);
1286 cmdr.front_laser = BEAM_LASER;
1287 break;
1288
1289 case EQ_REAR_BEAM:
1290 cmdr.credits += laser_refund (cmdr.rear_laser);
1291 cmdr.rear_laser = BEAM_LASER;
1292 break;
1293
1294 case EQ_LEFT_BEAM:
1295 cmdr.credits += laser_refund (cmdr.left_laser);
1296 cmdr.left_laser = BEAM_LASER;
1297 break;
1298
1299 case EQ_RIGHT_BEAM:
1300 cmdr.credits += laser_refund (cmdr.right_laser);
1301 cmdr.right_laser = BEAM_LASER;
1302 break;
1303
1304 case EQ_FRONT_MINING:
1305 cmdr.credits += laser_refund (cmdr.front_laser);
1306 cmdr.front_laser = MINING_LASER;
1307 break;
1308
1309 case EQ_REAR_MINING:
1310 cmdr.credits += laser_refund (cmdr.rear_laser);
1311 cmdr.rear_laser = MINING_LASER;
1312 break;
1313
1314 case EQ_LEFT_MINING:
1315 cmdr.credits += laser_refund (cmdr.left_laser);
1316 cmdr.left_laser = MINING_LASER;
1317 break;
1318
1319 case EQ_RIGHT_MINING:
1320 cmdr.credits += laser_refund (cmdr.right_laser);
1321 cmdr.right_laser = MINING_LASER;
1322 break;
1323
1324 case EQ_FRONT_MILITARY:
1325 cmdr.credits += laser_refund (cmdr.front_laser);
1326 cmdr.front_laser = MILITARY_LASER;
1327 break;
1328
1329 case EQ_REAR_MILITARY:
1330 cmdr.credits += laser_refund (cmdr.rear_laser);
1331 cmdr.rear_laser = MILITARY_LASER;
1332 break;
1333
1334 case EQ_LEFT_MILITARY:
1335 cmdr.credits += laser_refund (cmdr.left_laser);
1336 cmdr.left_laser = MILITARY_LASER;
1337 break;
1338
1339 case EQ_RIGHT_MILITARY:
1340 cmdr.credits += laser_refund (cmdr.right_laser);
1341 cmdr.right_laser = MILITARY_LASER;
1342 break;
1343 }
1344
1345 cmdr.credits -= equip_stock[hilite_item].price;
1346 list_equip_prices();
1347 }
1348
1349
1350 void equip_ship (void)
1351 {
1352 current_screen = SCR_EQUIP_SHIP;
1353
1354 gfx_clear_display();
1355 gfx_display_centre_text (10, "EQUIP SHIP", 140, GFX_COL_GOLD);
1356 gfx_draw_line (0, 36, 511, 36);
1357
1358 collapse_equip_list();
1359
1360 hilite_item = 0;
1361
1362 list_equip_prices();
1363 }