]> git.pond.sub.org Git - empserver/blob - src/lib/commands/upgr.c
Break long lines more tastefully
[empserver] / src / lib / commands / upgr.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2010, 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  *  upgr.c: Upgrade tech of ships/planes/units
29  *
30  *  Known contributors to this file:
31  *     Dave Pare, 1986
32  *     Steve McClure, 1996-2000
33  */
34
35 #include <config.h>
36
37 #include "commands.h"
38 #include "land.h"
39 #include "plane.h"
40 #include "ship.h"
41
42 enum {
43     UPGR_COST = 15,             /* how much avail and money to charge */
44     UPGR_EFF = 35               /* efficiency reduction */
45 };
46
47 static int lupgr(void);
48 static int pupgr(void);
49 static int supgr(void);
50
51 int
52 upgr(void)
53 {
54     char *p;
55     char buf[1024];
56
57     if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
58         return RET_SYN;
59     switch (*p) {
60     case 's':
61     case 'S':
62         return supgr();
63     case 'p':
64     case 'P':
65         return pupgr();
66     case 'l':
67     case 'L':
68         return lupgr();
69     default:
70         break;
71     }
72     pr("Ships, land units or planes only!\n");
73     return RET_SYN;
74 }
75
76 static int
77 lupgr(void)
78 {
79     struct sctstr sect;
80     struct natstr *natp;
81     struct nstr_item ni;
82     struct lndstr land;
83     struct lchrstr *lp;
84     int n;
85     int tlev;
86     int avail, cost;
87     int rel;
88     long cash;
89
90     if (!snxtitem(&ni, EF_LAND, player->argp[2], NULL))
91         return RET_SYN;
92     natp = getnatp(player->cnum);
93     cash = natp->nat_money;
94     tlev = (int)natp->nat_level[NAT_TLEV];
95     n = 0;
96     while (nxtitem(&ni, &land)) {
97         if (land.lnd_own == 0)
98             continue;
99         getsect(land.lnd_x, land.lnd_y, &sect);
100         if (sect.sct_own != player->cnum)
101             continue;
102         if (sect.sct_type != SCT_HEADQ || sect.sct_effic < 60)
103             continue;
104         rel = getrel(getnatp(land.lnd_own), sect.sct_own);
105         if (rel < FRIENDLY && sect.sct_own != land.lnd_own) {
106             pr("You are not on friendly terms with the owner of unit %d!\n",
107                land.lnd_uid);
108             continue;
109         }
110         n++;
111         lp = &lchr[(int)land.lnd_type];
112         avail = (LND_BLD_WORK(lp->l_lcm, lp->l_hcm) * UPGR_COST + 99) / 100;
113         if (sect.sct_avail < avail) {
114             pr("Not enough available work in %s to upgrade a %s\n",
115                xyas(sect.sct_x, sect.sct_y, player->cnum), lp->l_name);
116             pr(" (%d available work required)\n", avail);
117             continue;
118         }
119         if (land.lnd_effic < 60) {
120             pr("%s is too damaged to upgrade!\n", prland(&land));
121             continue;
122         }
123         if (land.lnd_tech >= tlev) {
124             pr("%s tech: %d, yours is only %d\n",
125                prland(&land), land.lnd_tech, tlev);
126             continue;
127         }
128         cost = lp->l_cost * UPGR_COST / 100;
129         if (cost + player->dolcost > cash) {
130             pr("You don't have enough money to upgrade %s!\n",
131                prland(&land));
132             continue;
133         }
134
135         sect.sct_avail -= avail;
136         land.lnd_effic -= UPGR_EFF;
137         lnd_set_tech(&land, tlev);
138         land.lnd_harden = 0;
139         land.lnd_mission = 0;
140
141         putland(land.lnd_uid, &land);
142         putsect(&sect);
143         player->dolcost += cost;
144         pr("%s upgraded to tech %d, at a cost of %d\n",
145            prland(&land), land.lnd_tech, cost);
146         if (land.lnd_own != player->cnum)
147             wu(0, land.lnd_own,
148                "%s upgraded by %s to tech %d, at a cost of %d\n",
149                prland(&land), cname(player->cnum), land.lnd_tech, cost);
150     }
151     if (n == 0) {
152         pr("No land units\n");
153         return RET_SYN;
154     }
155     return RET_OK;
156 }
157
158 static int
159 supgr(void)
160 {
161     struct sctstr sect;
162     struct natstr *natp;
163     struct nstr_item ni;
164     struct shpstr ship;
165     struct mchrstr *mp;
166     int n;
167     int tlev;
168     int avail, cost;
169     int rel;
170     long cash;
171
172     if (!snxtitem(&ni, EF_SHIP, player->argp[2], NULL))
173         return RET_SYN;
174     natp = getnatp(player->cnum);
175     cash = natp->nat_money;
176     tlev = (int)natp->nat_level[NAT_TLEV];
177     n = 0;
178     while (nxtitem(&ni, &ship)) {
179         if (ship.shp_own == 0)
180             continue;
181         getsect(ship.shp_x, ship.shp_y, &sect);
182         if (sect.sct_own != player->cnum)
183             continue;
184         if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60)
185             continue;
186         rel = getrel(getnatp(ship.shp_own), sect.sct_own);
187         if (rel < FRIENDLY && sect.sct_own != ship.shp_own) {
188             pr("You are not on friendly terms with the owner of ship %d!\n",
189                ship.shp_uid);
190             continue;
191         }
192         n++;
193         mp = &mchr[(int)ship.shp_type];
194         avail = (SHP_BLD_WORK(mp->m_lcm, mp->m_hcm) * UPGR_COST + 99) / 100;
195         if (sect.sct_avail < avail) {
196             pr("Not enough available work in %s to upgrade a %s\n",
197                xyas(sect.sct_x, sect.sct_y, player->cnum), mp->m_name);
198             pr(" (%d available work required)\n", avail);
199             continue;
200         }
201         if (ship.shp_effic < 60) {
202             pr("%s is too damaged to upgrade!\n", prship(&ship));
203             continue;
204         }
205         if (ship.shp_tech >= tlev) {
206             pr("%s tech: %d, yours is only %d\n",
207                prship(&ship), ship.shp_tech, tlev);
208             continue;
209         }
210         cost = mp->m_cost * UPGR_COST / 100;
211         if (cost + player->dolcost > cash) {
212             pr("You don't have enough money to upgrade %s!\n",
213                prship(&ship));
214             continue;
215         }
216
217         sect.sct_avail -= avail;
218         ship.shp_effic -= UPGR_EFF;
219         shp_set_tech(&ship, tlev);
220         ship.shp_mission = 0;
221
222         putship(ship.shp_uid, &ship);
223         putsect(&sect);
224         player->dolcost += cost;
225         pr("%s upgraded to tech %d, at a cost of %d\n",
226            prship(&ship), ship.shp_tech, cost);
227         if (ship.shp_own != player->cnum)
228             wu(0, ship.shp_own,
229                "%s upgraded by %s to tech %d, at a cost of %d\n",
230                prship(&ship), cname(player->cnum), ship.shp_tech, cost);
231     }
232     if (n == 0) {
233         pr("No ships\n");
234         return RET_SYN;
235     }
236     return RET_OK;
237 }
238
239 static int
240 pupgr(void)
241 {
242     struct sctstr sect;
243     struct natstr *natp;
244     struct nstr_item ni;
245     struct plnstr plane;
246     struct plchrstr *pp;
247     int n;
248     int tlev;
249     int avail, cost;
250     int rel;
251     long cash;
252
253     if (!snxtitem(&ni, EF_PLANE, player->argp[2], NULL))
254         return RET_SYN;
255     natp = getnatp(player->cnum);
256     cash = natp->nat_money;
257     tlev = (int)natp->nat_level[NAT_TLEV];
258     n = 0;
259     while (nxtitem(&ni, &plane)) {
260         if (plane.pln_own == 0)
261             continue;
262         getsect(plane.pln_x, plane.pln_y, &sect);
263         if (sect.sct_own != player->cnum)
264             continue;
265         if (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)
266             continue;
267         rel = getrel(getnatp(plane.pln_own), sect.sct_own);
268         if (rel < FRIENDLY && sect.sct_own != plane.pln_own) {
269             pr("You are not on friendly terms with the owner of plane %d!\n",
270                plane.pln_uid);
271             continue;
272         }
273         if (pln_is_in_orbit(&plane)) {
274             pr("Plane %s is in orbit!\n", prplane(&plane));
275             continue;
276         }
277         if (plane.pln_flags & PLN_LAUNCHED)
278             continue;
279         n++;
280         pp = &plchr[(int)plane.pln_type];
281         avail = (PLN_BLD_WORK(pp->pl_lcm, pp->pl_hcm) * UPGR_COST + 99) / 100;
282         if (sect.sct_avail < avail) {
283             pr("Not enough available work in %s to upgrade a %s\n",
284                xyas(sect.sct_x, sect.sct_y, player->cnum), pp->pl_name);
285             pr(" (%d available work required)\n", avail);
286             continue;
287         }
288         if (plane.pln_effic < 60) {
289             pr("%s is too damaged to upgrade!\n", prplane(&plane));
290             continue;
291         }
292         if (plane.pln_tech >= tlev) {
293             pr("%s tech: %d, yours is only %d\n",
294                prplane(&plane), plane.pln_tech, tlev);
295             continue;
296         }
297         cost = pp->pl_cost * UPGR_COST / 100;
298         if (cost + player->dolcost > cash) {
299             pr("You don't have enough money to upgrade %s!\n",
300                prplane(&plane));
301             continue;
302         }
303
304         sect.sct_avail -= avail;
305         plane.pln_effic -= UPGR_EFF;
306         pln_set_tech(&plane, tlev);
307         plane.pln_harden = 0;
308         plane.pln_mission = 0;
309
310         putplane(plane.pln_uid, &plane);
311         putsect(&sect);
312         player->dolcost += cost;
313         pr("%s upgraded to tech %d, at a cost of %d\n",
314            prplane(&plane), plane.pln_tech, cost);
315         if (plane.pln_own != player->cnum)
316             wu(0, plane.pln_own,
317                "%s upgraded by %s to tech %d, at a cost of %d\n",
318                prplane(&plane), cname(player->cnum), plane.pln_tech, cost);
319     }
320     if (n == 0) {
321         pr("No planes.\n");
322         return RET_SYN;
323     }
324     return RET_OK;
325 }