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