]> git.pond.sub.org Git - empserver/blob - src/lib/commands/repo.c
Fix long lines. No functional changes.
[empserver] / src / lib / commands / repo.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 files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  repo.c: Report on various levels (tech, research) of other nations
29  * 
30  *  Known contributors to this file:
31  *     Keith Muller, 1983
32  *     Dave Pare, 1986 (rewrite)
33  *     Steve McClure, 2000
34  */
35
36 #include <config.h>
37
38 #include "misc.h"
39 #include "player.h"
40 #include "nat.h"
41 #include "file.h"
42 #include "commands.h"
43 #include "optlist.h"
44
45 static void repo_header(void);
46 static void repo_list(struct natstr *, struct natstr *);
47 static void printdiff(struct natstr *, struct natstr *, int what);
48 static int tryprdiff(double, double, double, int, int);
49
50 int
51 repo(void)
52 {
53     struct natstr *natp;
54     struct natstr nat;
55     struct nstr_item ni;
56
57     if (!snxtitem(&ni, EF_NATION, player->argp[1]))
58         return RET_SYN;
59     prdate();
60     natp = getnatp(player->cnum);
61     repo_header();
62     while (nxtitem(&ni, &nat)) {
63         if (nat.nat_stat == STAT_UNUSED)
64             continue;
65         if (opt_HIDDEN) {
66             if (!player->god && !getcontact(natp, ni.cur))
67                 continue;
68         }
69         if (!player->god && nat.nat_stat != STAT_ACTIVE)
70             continue;
71         repo_list(natp, &nat);
72     }
73     return RET_OK;
74 }
75
76 static void
77 repo_header(void)
78 {
79     pr(" #    name                tech      research   education   happiness"
80        " %s\n",
81        player->god ? "capital" : " status");
82 }
83
84 static void
85 repo_list(struct natstr *plnatp, struct natstr *natp)
86 {
87     pr(" %-3d   %-14.14s ", natp->nat_cnum, natp->nat_cnam);
88     if (player->god || player->cnum == natp->nat_cnum) {
89         pr(" %7.2f     %7.2f     %7.2f     %7.2f%s",
90            natp->nat_level[NAT_TLEV], natp->nat_level[NAT_RLEV],
91            natp->nat_level[NAT_ELEV], natp->nat_level[NAT_HLEV],
92            player->god ? "" : "    ");
93     } else {
94         printdiff(plnatp, natp, NAT_TLEV);
95         printdiff(plnatp, natp, NAT_RLEV);
96         printdiff(plnatp, natp, NAT_ELEV);
97         printdiff(plnatp, natp, NAT_HLEV);
98     }
99     if (player->god) {
100         prxy("  %4d,%-4d\n", natp->nat_xcap, natp->nat_ycap, player->cnum);
101     } else {
102         if (!opt_HIDDEN && influx(natp))
103             pr("In flux\n");
104         else if (!opt_HIDDEN && natp->nat_money <= 0)
105             pr("Broke\n");
106         else
107             pr("Active\n");
108     }
109 }
110
111 static void
112 printdiff(struct natstr *plnatp, struct natstr *natp, int what)
113 {
114     double ours = plnatp->nat_level[what];
115     double theirs;
116     int shift;
117     int tolerance;
118
119     if (ours
120         && plnatp->nat_stat >= STAT_ACTIVE
121         && natp->nat_stat >= STAT_ACTIVE) {
122         theirs = natp->nat_level[what];
123         if ((shift = MIN((int)theirs, (int)ours) - 100) > 0) {
124             ours -= shift;
125             theirs -= shift;
126         } else
127             shift = 0;
128         switch (what) {
129         case NAT_TLEV:
130             tolerance = 20;
131             break;
132         case NAT_RLEV:
133             tolerance = 10;
134             break;
135         default:
136             tolerance = 5;
137         }
138         if (tolerance > 2 * ours)
139             tolerance = (int)(2 * ours);
140         if (tryprdiff(theirs, 2 * ours, -1.0, shift, tolerance))
141           ;
142         else if (tryprdiff(theirs, 1.5 * ours, 2.0 * ours, shift, tolerance))
143           ;
144         else if (tryprdiff(theirs, 1.2 * ours, 1.5 * ours, shift, tolerance))
145           ;
146         else if (tryprdiff(theirs, 1.1 * ours, 1.2 * ours, shift, tolerance))
147           ;
148         else if (tryprdiff(theirs, ours / 1.1, 1.1 * ours, shift, tolerance))
149           ;
150         else if (tryprdiff(theirs, ours / 1.2, ours / 1.1, shift, tolerance))
151           ;
152         else if (tryprdiff(theirs, ours / 1.5, ours / 1.2, shift, tolerance))
153           ;
154         else if (tryprdiff(theirs, ours / 2.0, ours / 1.5, shift, tolerance))
155           ;
156         else if (tryprdiff(theirs, -1.0, ours / 2.0, shift, tolerance)) ;
157         else
158             pr("    n/a     ");
159     } else
160         pr("    n/a     ");
161 }
162
163 static int
164 tryprdiff(double theirs, double min, double max, int shift, int tolerance)
165 {
166     double shove;
167
168     if (min < 0) {
169         if (theirs <= max) {
170             if (max < tolerance)
171                 max = tolerance;
172             pr("   0 - %-4d ", (int)max + shift);
173             return 1;
174         }
175     } else if (max < 0) {
176         if (theirs >= min) {
177             pr("    >= %-4d ", (int)min + shift);
178             return 1;
179         }
180     } else if (theirs >= min && theirs <= max) {
181         if (max - min < tolerance) {
182             shove = (tolerance - (max - min)) / 2;
183             if (min + shift - shove >= 0) {
184                 min -= shove;
185                 max += shove;
186             } else {
187                 min = 0;
188                 max = tolerance;
189             }
190         }
191         pr("%4d - %-4d ", (int)min + shift, (int)max + shift);
192         return 1;
193     }
194
195     return 0;
196 }