]> git.pond.sub.org Git - empserver/blob - src/lib/commands/upgr.c
bf5726220f63566b655447be7500c2d53a08af93
[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 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  *  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     s_char *p;
62     s_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", land.lnd_uid);
114             continue;
115         }
116         n++;
117         lp = &lchr[(int)land.lnd_type];
118         avail = (LND_BLD_WORK(lp->l_lcm, lp->l_hcm) * UPGR_COST + 99) / 100;
119         if (sect.sct_avail < avail) {
120             pr("Not enough available work in %s to upgrade a %s\n",
121                xyas(sect.sct_x, sect.sct_y, player->cnum), lp->l_name);
122             pr(" (%d available work required)\n", avail);
123             continue;
124         }
125         if (land.lnd_effic < 60) {
126             pr("%s is too damaged to upgrade!\n", prland(&land));
127             continue;
128         }
129         if (land.lnd_tech >= tlev) {
130             pr("%s tech: %d, yours is only %d\n", prland(&land),
131                land.lnd_tech, tlev);
132             continue;
133         }
134         cost = lp->l_cost * UPGR_COST / 100;
135         if (cost + player->dolcost > cash) {
136             pr("You don't have enough money to upgrade %s!\n",
137                prland(&land));
138             continue;
139         }
140
141         sect.sct_avail -= avail;
142         land.lnd_effic -= UPGR_EFF;
143         lnd_set_tech(&land, tlev);
144         land.lnd_harden = 0;
145         land.lnd_mission = 0;
146         time(&land.lnd_access);
147
148         putland(land.lnd_uid, &land);
149         putsect(&sect);
150         player->dolcost += cost;
151         pr("%s upgraded to tech %d, at a cost of %d\n", prland(&land),
152            land.lnd_tech, cost);
153         if (land.lnd_own != player->cnum)
154             wu(0, land.lnd_own,
155                "%s upgraded by %s to tech %d, at a cost of %d\n",
156                prland(&land), cname(player->cnum), land.lnd_tech,
157                cost);
158     }
159     if (n == 0) {
160         pr("No land units\n");
161         return RET_SYN;
162     }
163     return RET_OK;
164 }
165
166 static int
167 supgr(void)
168 {
169     struct sctstr sect;
170     struct natstr *natp;
171     struct nstr_item ni;
172     struct shpstr ship;
173     struct mchrstr *mp;
174     int n;
175     int tlev;
176     int avail, cost;
177     int rel;
178     long cash;
179
180     if (!snxtitem(&ni, EF_SHIP, player->argp[2]))
181         return RET_SYN;
182     natp = getnatp(player->cnum);
183     cash = natp->nat_money;
184     tlev = (int)natp->nat_level[NAT_TLEV];
185     n = 0;
186     while (nxtitem(&ni, &ship)) {
187         if (ship.shp_own == 0)
188             continue;
189         getsect(ship.shp_x, ship.shp_y, &sect);
190         if (sect.sct_own != player->cnum)
191             continue;
192         if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60)
193             continue;
194         rel = getrel(getnatp(ship.shp_own), sect.sct_own);
195         if ((rel < FRIENDLY) && (sect.sct_own != ship.shp_own)) {
196             pr("You are not on friendly terms with the owner of ship %d!\n", ship.shp_uid);
197             continue;
198         }
199         n++;
200         mp = &mchr[(int)ship.shp_type];
201         avail = (SHP_BLD_WORK(mp->m_lcm, mp->m_hcm) * UPGR_COST + 99) / 100;
202         if (sect.sct_avail < avail) {
203             pr("Not enough available work in %s to upgrade a %s\n",
204                xyas(sect.sct_x, sect.sct_y, player->cnum), mp->m_name);
205             pr(" (%d available work required)\n", avail);
206             continue;
207         }
208         if (ship.shp_effic < 60) {
209             pr("%s is too damaged to upgrade!\n", prship(&ship));
210             continue;
211         }
212         if (ship.shp_tech >= tlev) {
213             pr("%s tech: %d, yours is only %d\n", prship(&ship),
214                ship.shp_tech, tlev);
215             continue;
216         }
217         cost = mp->m_cost * UPGR_COST / 100;
218         if (cost + player->dolcost > cash) {
219             pr("You don't have enough money to upgrade %s!\n",
220                prship(&ship));
221             continue;
222         }
223
224         sect.sct_avail -= avail;
225         ship.shp_effic -= UPGR_EFF;
226         shp_set_tech(&ship, tlev);
227         ship.shp_mission = 0;
228         time(&ship.shp_access);
229
230         putship(ship.shp_uid, &ship);
231         putsect(&sect);
232         player->dolcost += cost;
233         pr("%s upgraded to tech %d, at a cost of %d\n", prship(&ship),
234            ship.shp_tech, cost);
235         if (ship.shp_own != player->cnum)
236             wu(0, ship.shp_own,
237                "%s upgraded by %s to tech %d, at a cost of %d\n",
238                prship(&ship), cname(player->cnum), ship.shp_tech,
239                cost);
240     }
241     if (n == 0) {
242         pr("No ships\n");
243         return RET_SYN;
244     }
245     return RET_OK;
246 }
247
248 static int
249 pupgr(void)
250 {
251     struct sctstr sect;
252     struct natstr *natp;
253     struct nstr_item ni;
254     struct plnstr plane;
255     struct plchrstr *pp;
256     int n;
257     int tlev;
258     int avail, cost;
259     int rel;
260     long cash;
261
262     if (!snxtitem(&ni, EF_PLANE, player->argp[2]))
263         return RET_SYN;
264     natp = getnatp(player->cnum);
265     cash = natp->nat_money;
266     tlev = (int)natp->nat_level[NAT_TLEV];
267     n = 0;
268     while (nxtitem(&ni, &plane)) {
269         if (plane.pln_own == 0)
270             continue;
271         getsect(plane.pln_x, plane.pln_y, &sect);
272         if (sect.sct_own != player->cnum)
273             continue;
274         if (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)
275             continue;
276         rel = getrel(getnatp(plane.pln_own), sect.sct_own);
277         if ((rel < FRIENDLY) && (sect.sct_own != plane.pln_own)) {
278             pr("You are not on friendly terms with the owner of plane %d!\n", plane.pln_uid);
279             continue;
280         }
281         n++;
282         pp = &plchr[(int)plane.pln_type];
283         avail = (PLN_BLD_WORK(pp->pl_lcm, pp->pl_hcm) * UPGR_COST + 99) / 100;
284         if (sect.sct_avail < avail) {
285             pr("Not enough available work in %s to upgrade a %s\n",
286                xyas(sect.sct_x, sect.sct_y, player->cnum), pp->pl_name);
287             pr(" (%d available work required)\n", avail);
288             continue;
289         }
290         if (plane.pln_effic < 60) {
291             pr("%s is too damaged to upgrade!\n", prplane(&plane));
292             continue;
293         }
294         if (plane.pln_tech >= tlev) {
295             pr("%s tech: %d, yours is only %d\n", prplane(&plane),
296                plane.pln_tech, tlev);
297             continue;
298         }
299         cost = pp->pl_cost * UPGR_COST / 100;
300         if (cost + player->dolcost > cash) {
301             pr("You don't have enough money to upgrade %s!\n",
302                prplane(&plane));
303             continue;
304         }
305         if (plane.pln_flags & PLN_LAUNCHED) {
306             pr("Plane %s is in orbit!\n", prplane(&plane));
307             continue;
308         }
309
310         sect.sct_avail -= avail;
311         plane.pln_effic -= UPGR_EFF;
312         pln_set_tech(&plane, tlev);
313         plane.pln_harden = 0;
314         plane.pln_mission = 0;
315         time(&plane.pln_access);
316
317         putplane(plane.pln_uid, &plane);
318         putsect(&sect);
319         player->dolcost += cost;
320         pr("%s upgraded to tech %d, at a cost of %d\n", prplane(&plane),
321            plane.pln_tech, cost);
322         if (plane.pln_own != player->cnum)
323             wu(0, plane.pln_own,
324                "%s upgraded by %s to tech %d, at a cost of %d\n",
325                prplane(&plane), cname(player->cnum), plane.pln_tech,
326                cost);
327     }
328     if (n == 0) {
329         pr("No planes.\n");
330         return RET_SYN;
331     }
332     return RET_OK;
333 }