]> git.pond.sub.org Git - empserver/blob - src/lib/commands/repo.c
Indented with src/scripts/indent-emp.
[empserver] / src / lib / commands / repo.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, 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  *  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 "misc.h"
37 #include "player.h"
38 #include "var.h"
39 #include "sect.h"
40 #include "nat.h"
41 #include "deity.h"
42 #include "file.h"
43 #include "xy.h"
44 #include "nsc.h"
45 #include <fcntl.h>
46 #include <ctype.h>
47 #include "commands.h"
48 #include "optlist.h"
49
50 struct stats {
51     double res;
52     double tech;
53     double edu;
54     double hap;
55     int stat;
56 };
57
58 static void printdiff(int mystat, double ours, struct natstr *natp,
59                       int what);
60 static void repo_header(void);
61 static void repo_list(struct stats *stat, natid cn, struct natstr *natp);
62
63 static int check(s_char *buf, double theirs, double min, double max,
64                  int shift, int what, int tolerance);
65
66 int
67 repo(void)
68 {
69     struct natstr *natp;
70     struct stats mystat;
71     struct natstr nat;
72     struct nstr_item ni;
73     int first;
74
75     if (!snxtitem(&ni, EF_NATION, player->argp[1]))
76         return RET_SYN;
77     prdate();
78     natp = getnatp(player->cnum);
79     bzero((s_char *)&mystat, sizeof(struct stats));
80     mystat.stat = natp->nat_stat;
81     if (mystat.stat & STAT_NORM) {
82         mystat.res = natp->nat_level[NAT_RLEV];
83         mystat.tech = natp->nat_level[NAT_TLEV];
84         mystat.edu = natp->nat_level[NAT_ELEV];
85         mystat.hap = natp->nat_level[NAT_HLEV];
86     }
87     if (opt_HIDDEN) {
88         repo_header();
89         first = 0;
90     } else {
91         first = 1;
92     }
93     while (nxtitem(&ni, (s_char *)&nat)) {
94         if (!(nat.nat_stat & STAT_INUSE))
95             continue;
96         if (opt_HIDDEN) {
97             if (!player->god && !getcontact(getnatp(player->cnum), ni.cur))
98                 continue;
99         }
100         if (first) {
101             repo_header();
102             first = 0;
103         }
104         repo_list(&mystat, (natid)ni.cur, &nat);
105     }
106     return RET_OK;
107 }
108
109 static void
110 repo_header(void)
111 {
112     pr(" #    name                tech      research   education   happiness ");
113     if (player->god)
114         pr("capital\n");
115     else {
116         if (opt_HIDDEN)
117             pr("\n");
118         else
119             pr(" status\n");
120     }
121 }
122
123 static void
124 repo_list(struct stats *stat, natid cn, struct natstr *natp)
125 {
126     struct sctstr cap;
127
128     if (player->god) {
129         pr(" %-3d   %-14.14s ", cn, natp->nat_cnam);
130         pr(" %7.2f    %7.2f      %7.2f     %7.2f",
131            natp->nat_level[NAT_TLEV],
132            natp->nat_level[NAT_RLEV],
133            natp->nat_level[NAT_ELEV], natp->nat_level[NAT_HLEV]);
134         prxy("  %4d,%-4d\n", natp->nat_xcap, natp->nat_ycap, player->cnum);
135         return;
136     }
137     switch (natp->
138             nat_stat & (STAT_NORM | STAT_GOD | STAT_NEW | STAT_SANCT)) {
139     case STAT_NORM:
140     case (STAT_NORM | STAT_SANCT):
141         pr(" %-3d   %-14.14s ", cn, natp->nat_cnam);
142         printdiff(stat->stat, stat->tech, natp, NAT_TLEV);
143         printdiff(stat->stat, stat->res, natp, NAT_RLEV);
144         printdiff(stat->stat, stat->edu, natp, NAT_ELEV);
145         printdiff(stat->stat, stat->hap, natp, NAT_HLEV);
146         getsect(natp->nat_xcap, natp->nat_ycap, &cap);
147         if (opt_HIDDEN) {
148             pr("\n");
149         } else {
150             if ((cap.sct_own != cn) ||
151                 (cap.sct_type != SCT_CAPIT &&
152                  cap.sct_type != SCT_MOUNT) ||
153                 (natp->nat_flags & NF_SACKED))
154                 pr("In flux\n");
155             else if (natp->nat_money <= 0)
156                 pr("Broke\n");
157             else
158                 pr("Active\n");
159         }
160         break;
161     case STAT_SANCT:
162         break;
163     case STAT_NEW:
164     case 0:
165         break;
166     case STAT_SANCT | STAT_NORM | STAT_GOD:
167     case STAT_NORM | STAT_GOD:
168     case STAT_GOD:
169         break;
170     default:
171         pr("????        ????        ????        ????\n");
172         break;
173     }
174 }
175
176 static void
177 printdiff(int mystat, double ours, struct natstr *natp, int what)
178 {
179     double theirs;
180     int shift;
181     int tolerance;
182     s_char buf[128];
183
184     if (natp->nat_cnum == player->cnum) {
185         pr(" %7.2f    ", ours);
186         return;
187     }
188     if (ours && mystat & STAT_NORM && natp->nat_stat & STAT_NORM) {
189         theirs = natp->nat_level[what];
190         if ((shift = min((int)theirs, (int)ours) - 100) > 0) {
191             ours -= shift;
192             theirs -= shift;
193         } else
194             shift = 0;
195         switch (what) {
196         case NAT_TLEV:
197             tolerance = 20;
198             break;
199         case NAT_RLEV:
200             tolerance = 10;
201             break;
202         default:
203             tolerance = 5;
204         }
205         if (tolerance > 2 * ours)
206             tolerance = (int)(2 * ours);
207         if (check(buf, theirs, 2 * ours, -1.0, shift, what, tolerance)) ;
208         else if (check
209                  (buf, theirs, 1.5 * ours, 2.0 * ours, shift, what,
210                   tolerance)) ;
211         else if (check
212                  (buf, theirs, 1.2 * ours, 1.5 * ours, shift, what,
213                   tolerance)) ;
214         else if (check
215                  (buf, theirs, 1.1 * ours, 1.2 * ours, shift, what,
216                   tolerance)) ;
217         else if (check
218                  (buf, theirs, ours / 1.1, 1.1 * ours, shift, what,
219                   tolerance)) ;
220         else if (check
221                  (buf, theirs, ours / 1.2, ours / 1.1, shift, what,
222                   tolerance)) ;
223         else if (check
224                  (buf, theirs, ours / 1.5, ours / 1.2, shift, what,
225                   tolerance)) ;
226         else if (check
227                  (buf, theirs, ours / 2.0, ours / 1.5, shift, what,
228                   tolerance)) ;
229         else if (check
230                  (buf, theirs, -1.0, ours / 2.0, shift, what, tolerance)) ;
231         else
232             sprintf(buf, "    n/a");
233     } else
234         sprintf(buf, "    n/a");
235
236     pr("%-11s ", buf);
237 }
238
239 static int
240 check(s_char *buf, double theirs, double min, double max, int shift,
241       int what, int tolerance)
242 {
243     double shove;
244
245     if (min < 0) {
246         if (theirs <= max) {
247             if (max < tolerance)
248                 max = tolerance;
249             sprintf(buf, "   0 - %d", (int)max + shift);
250             return 1;
251         }
252     } else if (max < 0) {
253         if (theirs >= min) {
254             sprintf(buf, "    >= %d", (int)min + shift);
255             return 1;
256         }
257     } else if (theirs >= min && theirs <= max) {
258         if (max - min < tolerance) {
259             shove = (tolerance - (max - min)) / 2;
260             if (min + shift - shove >= 0) {
261                 min -= shove;
262                 max += shove;
263             } else {
264                 min = 0;
265                 max = tolerance;
266             }
267         }
268         sprintf(buf, "%4d - %d", (int)min + shift, (int)max + shift);
269         return 1;
270     }
271
272     return 0;
273 }