]> git.pond.sub.org Git - empserver/blob - src/lib/subs/show.c
(show_nuke_build, show_nuke_capab): Column res used to be shown only
[empserver] / src / lib / subs / show.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  show.c: General show routines
29  * 
30  *  Known contributors to this file:
31  *     Julian Onions, 1988
32  *     Jeff Bailey, 1990
33  *     Steve McClure, 1996
34  */
35
36 /*
37  * general routines that are callable to give info on things.
38  * currently, planes, ships, nukes and bridges. Tanks & regiments one day?
39  *
40  * Added nuke_flags to be consistent. Jeff Bailey 12/15/90
41  *                                    (bailey@mcs.kent.edu)
42  */
43
44 #include <config.h>
45
46 #include <math.h>
47 #include "misc.h"
48 #include "player.h"
49 #include "nuke.h"
50 #include "ship.h"
51 #include "land.h"
52 #include "item.h"
53 #include "plane.h"
54 #include "sect.h"
55 #include "optlist.h"
56 #include "file.h"
57 #include "nat.h"
58 #include "prototypes.h"
59 #include "nsc.h"
60
61 struct look_list {
62     union {
63         struct lchrstr *lp;
64         struct plchrstr *pp;
65         struct mchrstr *mp;
66     } l_u;
67     int tech;
68 } lookup_list[200];             /* Change this if there are ever more than 200 planes, ships
69                                    or land units. */
70 static int lookup_list_cnt = 0;
71
72 static void
73 sort_lookup_list(void)
74 {
75     struct natstr *np = getnatp(player->cnum);
76     struct look_list tmp;
77     int i;
78     int j;
79
80     if (!(np->nat_flags & NF_TECHLISTS))
81         return;
82     for (i = 0; i < lookup_list_cnt; i++) {
83         for (j = i; j < lookup_list_cnt; j++) {
84             if (lookup_list[j].tech < lookup_list[i].tech) {
85                 tmp = lookup_list[j];
86                 lookup_list[j] = lookup_list[i];
87                 lookup_list[i] = tmp;
88             }
89         }
90     }
91 }
92
93 static void
94 make_new_list(int tlev, int type)
95 {
96     struct plchrstr *pp;
97     struct lchrstr *lp;
98     struct mchrstr *mp;
99
100     lookup_list_cnt = 0;
101     if (type == EF_PLANE) {
102         for (pp = plchr; pp->pl_name; pp++) {
103             if (pp->pl_tech > tlev)
104                 continue;
105             lookup_list[lookup_list_cnt].l_u.pp = pp;
106             lookup_list[lookup_list_cnt].tech = pp->pl_tech;
107             lookup_list_cnt++;
108         }
109     } else if (type == EF_SHIP) {
110         for (mp = mchr; mp->m_name; mp++) {
111             if (mp->m_tech > tlev)
112                 continue;
113             lookup_list[lookup_list_cnt].l_u.mp = mp;
114             lookup_list[lookup_list_cnt].tech = mp->m_tech;
115             lookup_list_cnt++;
116         }
117     } else if (type == EF_LAND) {
118         for (lp = lchr; lp->l_name; lp++) {
119             if (lp->l_tech > tlev)
120                 continue;
121             lookup_list[lookup_list_cnt].l_u.lp = lp;
122             lookup_list[lookup_list_cnt].tech = lp->l_tech;
123             lookup_list_cnt++;
124         }
125     } else
126         return;
127
128     sort_lookup_list();
129 }
130
131 void
132 show_bridge(int tlev)
133 {
134     if (tlev < buil_bt)
135         return;
136     pr("Bridges require %g tech,", buil_bt);
137     pr(" %d hcm,", buil_bh);
138     pr(" %d workers,\n", 0);
139     pr("%d available workforce, and cost $%g\n",
140        (SCT_BLD_WORK(0, buil_bh) * SCT_MINEFF + 99) / 100,
141        buil_bc);
142 }
143
144 void
145 show_tower(int tlev)
146 {
147     if (tlev < buil_tower_bt)
148         return;
149     pr("Bridge Towers require %g tech,", buil_tower_bt);
150     pr(" %d hcm,", buil_tower_bh);
151     pr(" %d workers,\n", 0);
152     pr("%d available workforce, and cost $%g\n",
153        (SCT_BLD_WORK(0, buil_tower_bh) * SCT_MINEFF + 99) / 100,
154        buil_tower_bc);
155 }
156
157 void
158 show_nuke_stats(int tlev)
159 {
160     show_nuke_capab(tlev);
161 }
162
163 void
164 show_nuke_build(int tlev)
165 {
166     struct nchrstr *np;
167     int avail;
168
169     pr("%13s lcm hcm  oil  rad avail tech res $\n", "");
170
171     for (np = nchr; np->n_name; np++) {
172         avail = NUK_BLD_WORK(np->n_lcm, np->n_hcm, np->n_oil, np->n_rad);
173         if (np->n_tech > tlev)
174             continue;
175         pr("%-13.13s %3d %3d %4d %4d %5d %4d %3d $%6d\n",
176            np->n_name, np->n_lcm, np->n_hcm, np->n_oil,
177            np->n_rad, avail, np->n_tech,
178            opt_DRNUKE ? (int)(np->n_tech * drnuke_const) + 1 : 0,
179            np->n_cost);
180     }
181 }
182
183 void
184 show_nuke_capab(int tlev)
185 {
186     struct nchrstr *np;
187     int i, j;
188     char *p;
189
190     pr("%13s blst dam lbs tech res $%7s abilities\n", "", "");
191
192     for (np = nchr; np->n_name; np++) {
193         if (np->n_tech > tlev)
194             continue;
195         pr("%-13.13s %4d %3d %3d %4d %3d $%7d ",
196            np->n_name, np->n_blast, np->n_dam,
197            np->n_weight, np->n_tech,
198            opt_DRNUKE ? (int)(np->n_tech * drnuke_const) + 1 : 0,
199            np->n_cost);
200         for (i = j = 0; i < 32; i++) {
201             if (!(np->n_flags & bit(i)))
202                 continue;
203             if (NULL != (p = symbol_by_value(bit(i), nuke_chr_flags))) {
204                 if (j++ > 0)
205                     pr(" ");
206                 pr(p);
207             }
208         }
209         pr("\n");
210     }
211 }
212
213 void
214 show_ship_build(int tlev)
215 {
216     struct mchrstr *mp;
217     int n;
218
219     pr("%25s lcm hcm avail tech $\n", "");
220     make_new_list(tlev, EF_SHIP);
221     for (n = 0; n < lookup_list_cnt; n++) {
222         mp = (struct mchrstr *)lookup_list[n].l_u.mp;
223         /* Can't show trade ships unless it's turned on */
224         if ((mp->m_flags & M_TRADE) && !opt_TRADESHIPS)
225             continue;
226
227         pr("%-25.25s %3d %3d %5d %4d $%d\n",
228            mp->m_name, mp->m_lcm, mp->m_hcm,
229            SHP_BLD_WORK(mp->m_lcm, mp->m_hcm), mp->m_tech, mp->m_cost);
230     }
231 }
232
233 void
234 show_ship_stats(int tlev)
235 {
236     struct mchrstr *mp;
237     int scount;
238     int techdiff;
239
240     pr("%25s      s  v  s  r  f  l  p", "");
241     pr("  h");
242     pr("  x");
243     if (opt_FUEL)
244         pr("  fuel");
245     pr("\n");
246
247     pr("%25s      p  i  p  n  i  n  l", "");
248     pr("  e");
249     pr("  p");
250     if (opt_FUEL)
251         pr("   c/u");
252     pr("\n");
253
254     pr("%25s def  d  s  y  g  r  d  n", "");
255     pr("  l");
256     pr("  l");
257     if (opt_FUEL)
258         pr("      ");
259     pr("\n");
260
261
262     make_new_list(tlev, EF_SHIP);
263     for (scount = 0; scount < lookup_list_cnt; scount++) {
264         mp = (struct mchrstr *)lookup_list[scount].l_u.mp;
265         /* Can't show trade ships unless it's turned on */
266         if ((mp->m_flags & M_TRADE) && !opt_TRADESHIPS)
267             continue;
268
269         techdiff = (int)(tlev - mp->m_tech);
270         pr("%-25.25s %3d %2d %2d %2d %2d %2d ",
271            mp->m_name,
272            (short)SHP_DEF(mp->m_armor, techdiff),
273            (short)SHP_SPD(mp->m_speed, techdiff),
274            (short)SHP_VIS(mp->m_visib, techdiff),
275            mp->m_vrnge,
276            (short)SHP_RNG(mp->m_frnge, techdiff),
277            (short)SHP_FIR(mp->m_glim, techdiff));
278
279         pr("%2d ", mp->m_nland);
280         pr("%2d ", mp->m_nplanes);
281         pr("%2d ", mp->m_nchoppers);
282         pr("%2d ", mp->m_nxlight);
283         if (opt_FUEL)
284             pr("%3d/%1d ", mp->m_fuelc, mp->m_fuelu);
285         pr("\n");
286     }
287 }
288
289 void
290 show_ship_capab(int tlev)
291 {
292     struct mchrstr *mp;
293     i_type i;
294     int j;
295     int scount;
296     int n;
297     char *p;
298
299     pr("%25s cargos & capabilities\n", "");
300
301     make_new_list(tlev, EF_SHIP);
302     for (scount = 0; scount < lookup_list_cnt; scount++) {
303         mp = (struct mchrstr *)lookup_list[scount].l_u.mp;
304         /* Can't show trade ships unless it's turned on */
305         if ((mp->m_flags & M_TRADE) && !opt_TRADESHIPS)
306             continue;
307
308         pr("%-25.25s ", mp->m_name);
309
310         for (i = I_NONE + 1; i <= I_MAX; ++i)
311             if (mp->m_item[i])
312                 pr(" %d%c", mp->m_item[i], ichr[i].i_mnem);
313         pr(" ");
314         for (j = n = 0; j < 32; j++) {
315             if (!(mp->m_flags & bit(j)))
316                 continue;
317             if (NULL != (p = symbol_by_value(bit(j), ship_chr_flags))) {
318                 if (n++ > 0)
319                     pr(" ");
320                 pr(p);
321             }
322         }
323         pr("\n");
324     }
325 }
326
327 void
328 show_plane_stats(int tlev)
329 {
330     struct plchrstr *pp;
331     int pcount;
332
333     pr("%25s acc load att def ran fuel stlth\n", "");
334     make_new_list(tlev, EF_PLANE);
335     for (pcount = 0; pcount < lookup_list_cnt; pcount++) {
336         pp = (struct plchrstr *)lookup_list[pcount].l_u.pp;
337         pr("%-25.25s %3d %4d %3d %3d %3d %4d ",
338            pp->pl_name,
339            (int)PLN_ACC(pp->pl_acc, (int)(tlev - pp->pl_tech)),
340            (int)PLN_LOAD(pp->pl_load, (int)(tlev - pp->pl_tech)),
341            (int)PLN_ATTDEF(pp->pl_att, (int)(tlev - pp->pl_tech)),
342            (int)PLN_ATTDEF(pp->pl_def, (int)(tlev - pp->pl_tech)),
343            (int)PLN_RAN(pp->pl_range, (int)(tlev - pp->pl_tech)),
344            pp->pl_fuel);
345         pr("%4d%% ", pp->pl_stealth);
346         pr("\n");
347     }
348 }
349
350 void
351 show_plane_capab(int tlev)
352 {
353     struct plchrstr *pp;
354     int i;
355     int pcount;
356     int n;
357     char *p;
358
359     pr("%25s capabilities\n", "");
360     make_new_list(tlev, EF_PLANE);
361     for (pcount = 0; pcount < lookup_list_cnt; pcount++) {
362         pp = (struct plchrstr *)lookup_list[pcount].l_u.pp;
363         pr("%-25.25s  ", pp->pl_name);
364
365         for (i = n = 0; i < 32; i++) {
366             if (!(pp->pl_flags & bit(i)))
367                 continue;
368             if (NULL != (p = symbol_by_value(bit(i), plane_chr_flags))) {
369                 if (n++ > 0)
370                     pr(" ");
371                 pr(p);
372             }
373         }
374         pr("\n");
375     }
376 }
377
378 void
379 show_plane_build(int tlev)
380 {
381     struct plchrstr *pp;
382     int pcount;
383
384     pr("%25s lcm hcm crew avail tech $\n", "");
385     make_new_list(tlev, EF_PLANE);
386     for (pcount = 0; pcount < lookup_list_cnt; pcount++) {
387         pp = (struct plchrstr *)lookup_list[pcount].l_u.pp;
388         pr("%-25.25s %3d %3d %4d %5d %4d $%d\n",
389            pp->pl_name, pp->pl_lcm,
390            pp->pl_hcm, pp->pl_crew,
391            PLN_BLD_WORK(pp->pl_lcm, pp->pl_hcm), pp->pl_tech, pp->pl_cost);
392     }
393 }
394
395 void
396 show_land_build(int tlev)
397 {
398     struct lchrstr *lp;
399     int n;
400
401     pr("%25s lcm hcm guns avail tech $\n", "");
402     make_new_list(tlev, EF_LAND);
403     for (n = 0; n < lookup_list_cnt; n++) {
404         lp = (struct lchrstr *)lookup_list[n].l_u.lp;
405         if ((lp->l_flags & L_SPY) && !opt_LANDSPIES)
406             continue;
407         pr("%-25.25s %3d %3d %4d %5d %4d $%d\n",
408            lp->l_name, lp->l_lcm,
409            lp->l_hcm,
410            lp->l_gun,
411            LND_BLD_WORK(lp->l_lcm, lp->l_hcm), lp->l_tech, lp->l_cost);
412     }
413 }
414
415 void
416 show_land_capab(int tlev)
417 {
418     struct lchrstr *lcp;
419     int lcount;
420     i_type i;
421     int j, n;
422     char *p;
423
424     pr("%25s capabilities\n", "");
425
426     make_new_list(tlev, EF_LAND);
427     for (lcount = 0; lcount < lookup_list_cnt; lcount++) {
428         lcp = (struct lchrstr *)lookup_list[lcount].l_u.lp;
429         if ((lcp->l_flags & L_SPY) && !opt_LANDSPIES)
430             continue;
431
432         pr("%-25s ", lcp->l_name);
433
434         for (i = I_NONE + 1; i <= I_MAX; ++i)
435             if (lcp->l_item[i])
436                 pr(" %d%c", lcp->l_item[i], ichr[i].i_mnem);
437         pr(" ");
438         for (j = n = 0; j < 32; j++) {
439             if (!(lcp->l_flags & bit(j)))
440                 continue;
441             if (NULL != (p = symbol_by_value(bit(j), land_chr_flags))) {
442                 if (n++ > 0)
443                     pr(" ");
444                 pr(p);
445             }
446         }
447         pr("\n");
448     }
449 }
450
451 void
452 show_land_stats(int tlev)
453 {
454     struct lchrstr *lcp;
455     int lcount;
456     int ourtlev;
457
458     pr("%25s              s  v  s  r  r  a  f  a  a        x  l\n", "");
459     pr("%25s              p  i  p  a  n  c  i  m  a  f  f  p  n\n", "");
460     pr("%25s att def vul  d  s  y  d  g  c  r  m  f  c  u  l  d\n", "");
461
462     make_new_list(tlev, EF_LAND);
463     for (lcount = 0; lcount < lookup_list_cnt; lcount++) {
464         lcp = (struct lchrstr *)lookup_list[lcount].l_u.lp;
465         if ((lcp->l_flags & L_SPY) && !opt_LANDSPIES)
466             continue;
467
468         ourtlev = (int)(tlev - lcp->l_tech);
469         pr("%-25s %1.1f %1.1f %3d ",
470            lcp->l_name, (float)LND_ATTDEF(lcp->l_att, ourtlev),
471            (float)LND_ATTDEF(lcp->l_def, ourtlev),
472            (int)LND_VUL(lcp->l_vul, ourtlev));
473         pr("%2d %2d %2d %2d ",
474            (int)LND_SPD(lcp->l_spd, ourtlev),
475            (int)LND_VIS(lcp->l_vis, ourtlev),
476            (int)LND_SPY(lcp->l_spy, ourtlev),
477            (int)LND_RAD(lcp->l_rad, ourtlev));
478         pr("%2d %2d %2d %2d %2d ",
479            (int)LND_FRG(lcp->l_frg, ourtlev),
480            (int)LND_ACC(lcp->l_acc, ourtlev),
481            (int)LND_DAM(lcp->l_dam, ourtlev),
482            (int)LND_AMM(lcp->l_ammo, lcp->l_dam, ourtlev),
483            (int)LND_AAF(lcp->l_aaf, ourtlev));
484         pr("%2d %2d %2d %2d ",
485            (int)LND_FC(lcp->l_fuelc, ourtlev),
486            (int)LND_FU(lcp->l_fuelu, ourtlev),
487            (int)LND_XPL(lcp->l_nxlight, ourtlev),
488            (int)LND_MXL(lcp->l_mxland, ourtlev));
489
490         pr("\n");
491     }
492 }
493
494 void
495 show_sect_build(int foo)
496 {
497     int x, first = 1;
498
499     for (x = 0; x <= SCT_MAXDEF; x++) {
500         if (dchr[x].d_mnem == 0)
501             continue;
502         if (dchr[x].d_cost < 0)
503             continue;
504         if ((dchr[x].d_cost > 0) || (dchr[x].d_build != 1) ||
505             (dchr[x].d_lcms > 0) || (dchr[x].d_hcms > 0)) {
506             if (first) {
507                 pr("sector type    cost to des    cost for 1%% eff   lcms for 1%%    hcms for 1%%\n");
508                 first = 0;
509             }
510             pr("%-14c %-14d %-17d %-14d %d\n",
511                dchr[x].d_mnem, dchr[x].d_cost, dchr[x].d_build,
512                dchr[x].d_lcms, dchr[x].d_hcms);
513         }
514     }
515     pr("\n");
516     pr("Infrastructure building - adding 1 point of efficiency costs:\n");
517     pr("       type          lcms    hcms    mobility    $$$$\n");
518     for (x = 0; intrchr[x].in_name; x++) {
519         pr("%-20s %4d    %4d    %8d    %4d\n", intrchr[x].in_name,
520            intrchr[x].in_lcms, intrchr[x].in_hcms,
521            intrchr[x].in_mcost, intrchr[x].in_dcost);
522     }
523 }
524
525 void
526 show_sect_stats(int foo)
527 {
528     int x, first = 1;
529     struct natstr *natp;
530
531     natp = getnatp(player->cnum);
532     for (x = 0; x <= SCT_MAXDEF; x++) {
533         if (dchr[x].d_mnem == 0)
534             continue;
535         if (first) {
536             pr("                        base     max   max   --  packing bonus  --   max\n");
537             pr("  sector type           mcost    off   def   mil  uw civ bar other   pop\n");
538             first = 0;
539         }
540         pr("%c %-23s %3d  %5.2f %5.2f   %3d %3d %3d %3d %5d %5d\n",
541            dchr[x].d_mnem, dchr[x].d_name,
542            dchr[x].d_mcst, dchr[x].d_ostr,
543            dchr[x].d_dstr,
544            ichr[I_MILIT].i_pkg[dchr[x].d_pkg],
545            ichr[I_UW].i_pkg[dchr[x].d_pkg],
546            ichr[I_CIVIL].i_pkg[dchr[x].d_pkg],
547            ichr[I_BAR].i_pkg[dchr[x].d_pkg],
548            ichr[I_LCM].i_pkg[dchr[x].d_pkg],
549            max_population(natp->nat_level[NAT_RLEV], x, 100));
550     }
551 }
552
553 void
554 show_sect_capab(int foo)
555 {
556     int x, first = 1, i, j;
557     char *tmpstr;
558
559     for (x = 0; x <= SCT_MAXDEF; x++) {
560         if ((dchr[x].d_mnem == 0) || (dchr[x].d_prd == 0))
561             continue;
562         if (first) {
563             pr("                                                 --- level ---          reso \n");
564             pr("  sector type             product use1 use2 use3 level min lag eff%% $$$ dep c\n");
565             first = 0;
566         }
567
568         j = dchr[x].d_prd;
569
570         pr("%c %-23s %-7s ", dchr[x].d_mnem, dchr[x].d_name,
571            pchr[j].p_sname);
572         (void)CANT_HAPPEN(MAXPRCON > 3); /* output has only three columns */
573         for (i = 0; i < 3; i++) {
574             if (i < MAXPRCON
575                 && pchr[j].p_camt[i]
576                 && pchr[j].p_ctype[i] > I_NONE
577                 && pchr[j].p_ctype[i] <= I_MAX) {
578                 pr("%2d %c ", pchr[j].p_camt[i],
579                    ichr[pchr[j].p_ctype[i]].i_name[0]);
580             } else {
581                 pr("     ");
582             }
583         }
584         switch (pchr[j].p_nlndx) {
585         case NAT_TLEV:
586             tmpstr = "tech";
587             break;
588         case NAT_ELEV:
589             tmpstr = "edu";
590             break;
591         case NAT_RLEV:
592             tmpstr = "res";
593             break;
594         case NAT_HLEV:
595             tmpstr = "hap";
596             break;
597         default:
598             tmpstr = " ";
599             break;
600         }
601         pr("%-5s %3d %3d %4d %3d %3d %c",
602            tmpstr,
603            pchr[j].p_nlmin,
604            pchr[j].p_nllag,
605            pchr[j].p_effic, pchr[j].p_cost, pchr[j].p_nrdep,
606            pchr[j].p_type != I_NONE ? ichr[pchr[j].p_type].i_mnem : ' ');
607
608         pr("\n");
609     }
610 }