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