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