]> git.pond.sub.org Git - empserver/blob - src/lib/commands/upgr.c
64a221cb9f04058a366fa50514d9cbea9a31bb5f
[empserver] / src / lib / commands / upgr.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2009, 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,
150                cost);
151     }
152     if (n == 0) {
153         pr("No land units\n");
154         return RET_SYN;
155     }
156     return RET_OK;
157 }
158
159 static int
160 supgr(void)
161 {
162     struct sctstr sect;
163     struct natstr *natp;
164     struct nstr_item ni;
165     struct shpstr ship;
166     struct mchrstr *mp;
167     int n;
168     int tlev;
169     int avail, cost;
170     int rel;
171     long cash;
172
173     if (!snxtitem(&ni, EF_SHIP, player->argp[2], NULL))
174         return RET_SYN;
175     natp = getnatp(player->cnum);
176     cash = natp->nat_money;
177     tlev = (int)natp->nat_level[NAT_TLEV];
178     n = 0;
179     while (nxtitem(&ni, &ship)) {
180         if (ship.shp_own == 0)
181             continue;
182         getsect(ship.shp_x, ship.shp_y, &sect);
183         if (sect.sct_own != player->cnum)
184             continue;
185         if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60)
186             continue;
187         rel = getrel(getnatp(ship.shp_own), sect.sct_own);
188         if (rel < FRIENDLY && sect.sct_own != ship.shp_own) {
189             pr("You are not on friendly terms with the owner of ship %d!\n",
190                ship.shp_uid);
191             continue;
192         }
193         n++;
194         mp = &mchr[(int)ship.shp_type];
195         avail = (SHP_BLD_WORK(mp->m_lcm, mp->m_hcm) * UPGR_COST + 99) / 100;
196         if (sect.sct_avail < avail) {
197             pr("Not enough available work in %s to upgrade a %s\n",
198                xyas(sect.sct_x, sect.sct_y, player->cnum), mp->m_name);
199             pr(" (%d available work required)\n", avail);
200             continue;
201         }
202         if (ship.shp_effic < 60) {
203             pr("%s is too damaged to upgrade!\n", prship(&ship));
204             continue;
205         }
206         if (ship.shp_tech >= tlev) {
207             pr("%s tech: %d, yours is only %d\n",
208                prship(&ship), ship.shp_tech, tlev);
209             continue;
210         }
211         cost = mp->m_cost * UPGR_COST / 100;
212         if (cost + player->dolcost > cash) {
213             pr("You don't have enough money to upgrade %s!\n",
214                prship(&ship));
215             continue;
216         }
217
218         sect.sct_avail -= avail;
219         ship.shp_effic -= UPGR_EFF;
220         shp_set_tech(&ship, tlev);
221         ship.shp_mission = 0;
222
223         putship(ship.shp_uid, &ship);
224         putsect(&sect);
225         player->dolcost += cost;
226         pr("%s upgraded to tech %d, at a cost of %d\n",
227            prship(&ship), ship.shp_tech, cost);
228         if (ship.shp_own != player->cnum)
229             wu(0, ship.shp_own,
230                "%s upgraded by %s to tech %d, at a cost of %d\n",
231                prship(&ship), cname(player->cnum), ship.shp_tech,
232                cost);
233     }
234     if (n == 0) {
235         pr("No ships\n");
236         return RET_SYN;
237     }
238     return RET_OK;
239 }
240
241 static int
242 pupgr(void)
243 {
244     struct sctstr sect;
245     struct natstr *natp;
246     struct nstr_item ni;
247     struct plnstr plane;
248     struct plchrstr *pp;
249     int n;
250     int tlev;
251     int avail, cost;
252     int rel;
253     long cash;
254
255     if (!snxtitem(&ni, EF_PLANE, player->argp[2], NULL))
256         return RET_SYN;
257     natp = getnatp(player->cnum);
258     cash = natp->nat_money;
259     tlev = (int)natp->nat_level[NAT_TLEV];
260     n = 0;
261     while (nxtitem(&ni, &plane)) {
262         if (plane.pln_own == 0)
263             continue;
264         getsect(plane.pln_x, plane.pln_y, &sect);
265         if (sect.sct_own != player->cnum)
266             continue;
267         if (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)
268             continue;
269         rel = getrel(getnatp(plane.pln_own), sect.sct_own);
270         if (rel < FRIENDLY && sect.sct_own != plane.pln_own) {
271             pr("You are not on friendly terms with the owner of plane %d!\n",
272                plane.pln_uid);
273             continue;
274         }
275         if (pln_is_in_orbit(&plane)) {
276             pr("Plane %s is in orbit!\n", prplane(&plane));
277             continue;
278         }
279         if (plane.pln_flags & PLN_LAUNCHED)
280             continue;
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",
296                prplane(&plane), 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
306         sect.sct_avail -= avail;
307         plane.pln_effic -= UPGR_EFF;
308         pln_set_tech(&plane, tlev);
309         plane.pln_harden = 0;
310         plane.pln_mission = 0;
311
312         putplane(plane.pln_uid, &plane);
313         putsect(&sect);
314         player->dolcost += cost;
315         pr("%s upgraded to tech %d, at a cost of %d\n",
316            prplane(&plane), plane.pln_tech, cost);
317         if (plane.pln_own != player->cnum)
318             wu(0, plane.pln_own,
319                "%s upgraded by %s to tech %d, at a cost of %d\n",
320                prplane(&plane), cname(player->cnum), plane.pln_tech,
321                cost);
322     }
323     if (n == 0) {
324         pr("No planes.\n");
325         return RET_SYN;
326     }
327     return RET_OK;
328 }