]> git.pond.sub.org Git - empserver/blob - src/lib/commands/repo.c
COPYING duplicates information from README. Remove. Move GPL from
[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 && natp->nat_stat >= STAT_ACTIVE) {
121         theirs = natp->nat_level[what];
122         if ((shift = MIN((int)theirs, (int)ours) - 100) > 0) {
123             ours -= shift;
124             theirs -= shift;
125         } else
126             shift = 0;
127         switch (what) {
128         case NAT_TLEV:
129             tolerance = 20;
130             break;
131         case NAT_RLEV:
132             tolerance = 10;
133             break;
134         default:
135             tolerance = 5;
136         }
137         if (tolerance > 2 * ours)
138             tolerance = (int)(2 * ours);
139         if (tryprdiff(theirs, 2 * ours, -1.0, shift, tolerance))
140           ;
141         else if (tryprdiff(theirs, 1.5 * ours, 2.0 * ours, shift, tolerance))
142           ;
143         else if (tryprdiff(theirs, 1.2 * ours, 1.5 * ours, shift, tolerance))
144           ;
145         else if (tryprdiff(theirs, 1.1 * ours, 1.2 * ours, shift, tolerance))
146           ;
147         else if (tryprdiff(theirs, ours / 1.1, 1.1 * ours, shift, tolerance))
148           ;
149         else if (tryprdiff(theirs, ours / 1.2, ours / 1.1, shift, tolerance))
150           ;
151         else if (tryprdiff(theirs, ours / 1.5, ours / 1.2, shift, tolerance))
152           ;
153         else if (tryprdiff(theirs, ours / 2.0, ours / 1.5, shift, tolerance))
154           ;
155         else if (tryprdiff(theirs, -1.0, ours / 2.0, shift, tolerance)) ;
156         else
157             pr("    n/a     ");
158     } else
159         pr("    n/a     ");
160 }
161
162 static int
163 tryprdiff(double theirs, double min, double max, int shift, int tolerance)
164 {
165     double shove;
166
167     if (min < 0) {
168         if (theirs <= max) {
169             if (max < tolerance)
170                 max = tolerance;
171             pr("   0 - %-4d ", (int)max + shift);
172             return 1;
173         }
174     } else if (max < 0) {
175         if (theirs >= min) {
176             pr("    >= %-4d ", (int)min + shift);
177             return 1;
178         }
179     } else if (theirs >= min && theirs <= max) {
180         if (max - min < tolerance) {
181             shove = (tolerance - (max - min)) / 2;
182             if (min + shift - shove >= 0) {
183                 min -= shove;
184                 max += shove;
185             } else {
186                 min = 0;
187                 max = tolerance;
188             }
189         }
190         pr("%4d - %-4d ", (int)min + shift, (int)max + shift);
191         return 1;
192     }
193
194     return 0;
195 }