]> git.pond.sub.org Git - empserver/blob - src/lib/commands/upgr.c
Update copyright notice.
[empserver] / src / lib / commands / upgr.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2004, 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 "misc.h"
36 #include "player.h"
37 #include "xy.h"
38 #include "var.h"
39 #include "ship.h"
40 #include "land.h"
41 #include "plane.h"
42 #include "sect.h"
43 #include "nat.h"
44 #include "nsc.h"
45 #include "file.h"
46 #include "commands.h"
47
48 enum {
49   UPGR_COST = 15,               /* how much avail and money to charge */
50   UPGR_EFF = 35                 /* efficiency reduction */
51 };
52
53 static int lupgr(void);
54 static int pupgr(void);
55 static int supgr(void);
56
57 int
58 upgr(void)
59 {
60     s_char *p;
61     s_char buf[1024];
62
63     if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
64         return RET_SYN;
65     switch (*p) {
66     case 's':
67     case 'S':
68         return supgr();
69     case 'p':
70     case 'P':
71         return pupgr();
72     case 'l':
73     case 'L':
74         return lupgr();
75     default:
76         break;
77     }
78     pr("Ships, land units or planes only!\n");
79     return RET_SYN;
80 }
81
82 static int
83 lupgr(void)
84 {
85     struct sctstr sect;
86     struct natstr *natp;
87     struct nstr_item ni;
88     struct lndstr land;
89     struct lchrstr *lp;
90     int n;
91     int tlev;
92     int avail, cost;
93     int rel;
94     long cash;
95
96     if (!snxtitem(&ni, EF_LAND, player->argp[2]))
97         return RET_SYN;
98     ni.flags &= ~(EFF_OWNER);
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, (s_char *)&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     ni.flags &= ~(EFF_OWNER);
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, (s_char *)&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", ship.shp_uid);
198             continue;
199         }
200         n++;
201         mp = &mchr[(int)ship.shp_type];
202         avail = (SHP_BLD_WORK(mp->m_lcm, mp->m_hcm) * UPGR_COST + 99) / 100;
203         if (sect.sct_avail < avail) {
204             pr("Not enough available work in %s to upgrade a %s\n",
205                xyas(sect.sct_x, sect.sct_y, player->cnum), mp->m_name);
206             pr(" (%d available work required)\n", avail);
207             continue;
208         }
209         if (ship.shp_effic < 60) {
210             pr("%s is too damaged to upgrade!\n", prship(&ship));
211             continue;
212         }
213         if (ship.shp_tech >= tlev) {
214             pr("%s tech: %d, yours is only %d\n", prship(&ship),
215                ship.shp_tech, tlev);
216             continue;
217         }
218         cost = mp->m_cost * UPGR_COST / 100;
219         if (cost + player->dolcost > cash) {
220             pr("You don't have enough money to upgrade %s!\n",
221                prship(&ship));
222             continue;
223         }
224
225         sect.sct_avail -= avail;
226         ship.shp_effic -= UPGR_EFF;
227         shp_set_tech(&ship, tlev);
228         ship.shp_mission = 0;
229         time(&ship.shp_access);
230
231         putship(ship.shp_uid, &ship);
232         putsect(&sect);
233         player->dolcost += cost;
234         pr("%s upgraded to tech %d, at a cost of %d\n", prship(&ship),
235            ship.shp_tech, cost);
236         if (ship.shp_own != player->cnum)
237             wu(0, ship.shp_own,
238                "%s upgraded by %s to tech %d, at a cost of %d\n",
239                prship(&ship), cname(player->cnum), ship.shp_tech,
240                cost);
241     }
242     if (n == 0) {
243         pr("No ships\n");
244         return RET_SYN;
245     }
246     return RET_OK;
247 }
248
249 static int
250 pupgr(void)
251 {
252     struct sctstr sect;
253     struct natstr *natp;
254     struct nstr_item ni;
255     struct plnstr plane;
256     struct plchrstr *pp;
257     int n;
258     int tlev;
259     int avail, cost;
260     int rel;
261     long cash;
262
263     if (!snxtitem(&ni, EF_PLANE, player->argp[2]))
264         return RET_SYN;
265     ni.flags &= ~(EFF_OWNER);
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, (s_char *)&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", plane.pln_uid);
281             continue;
282         }
283         n++;
284         pp = &plchr[(int)plane.pln_type];
285         avail = (PLN_BLD_WORK(pp->pl_lcm, pp->pl_hcm) * UPGR_COST + 99) / 100;
286         if (sect.sct_avail < avail) {
287             pr("Not enough available work in %s to upgrade a %s\n",
288                xyas(sect.sct_x, sect.sct_y, player->cnum), pp->pl_name);
289             pr(" (%d available work required)\n", avail);
290             continue;
291         }
292         if (plane.pln_effic < 60) {
293             pr("%s is too damaged to upgrade!\n", prplane(&plane));
294             continue;
295         }
296         if (plane.pln_tech >= tlev) {
297             pr("%s tech: %d, yours is only %d\n", prplane(&plane),
298                plane.pln_tech, tlev);
299             continue;
300         }
301         cost = pp->pl_cost * UPGR_COST / 100;
302         if (cost + player->dolcost > cash) {
303             pr("You don't have enough money to upgrade %s!\n",
304                prplane(&plane));
305             continue;
306         }
307         if (plane.pln_flags & PLN_LAUNCHED) {
308             pr("Plane %s is in orbit!\n", prplane(&plane));
309             continue;
310         }
311
312         sect.sct_avail -= avail;
313         plane.pln_effic -= UPGR_EFF;
314         pln_set_tech(&plane, tlev);
315         plane.pln_harden = 0;
316         plane.pln_mission = 0;
317         time(&plane.pln_access);
318
319         putplane(plane.pln_uid, &plane);
320         putsect(&sect);
321         player->dolcost += cost;
322         pr("%s upgraded to tech %d, at a cost of %d\n", prplane(&plane),
323            plane.pln_tech, cost);
324         if (plane.pln_own != player->cnum)
325             wu(0, plane.pln_own,
326                "%s upgraded by %s to tech %d, at a cost of %d\n",
327                prplane(&plane), cname(player->cnum), plane.pln_tech,
328                cost);
329     }
330     if (n == 0) {
331         pr("No planes.\n");
332         return RET_SYN;
333     }
334     return RET_OK;
335 }