]> 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-2012, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire 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 3 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, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  upgr.c: Upgrade tech of ships/planes/units
28  *
29  *  Known contributors to this file:
30  *     Dave Pare, 1986
31  *     Steve McClure, 1996-2000
32  */
33
34 #include <config.h>
35
36 #include "commands.h"
37 #include "land.h"
38 #include "plane.h"
39 #include "ship.h"
40
41 enum {
42     UPGR_COST = 15,             /* how much avail and money to charge */
43     UPGR_EFF = 35               /* efficiency reduction */
44 };
45
46 static int lupgr(void);
47 static int pupgr(void);
48 static int supgr(void);
49
50 int
51 upgr(void)
52 {
53     char *p;
54     char buf[1024];
55
56     if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
57         return RET_SYN;
58     switch (*p) {
59     case 's':
60     case 'S':
61         return supgr();
62     case 'p':
63     case 'P':
64         return pupgr();
65     case 'l':
66     case 'L':
67         return lupgr();
68     default:
69         break;
70     }
71     pr("Ships, land units or planes only!\n");
72     return RET_SYN;
73 }
74
75 static int
76 lupgr(void)
77 {
78     struct sctstr sect;
79     struct natstr *natp;
80     struct nstr_item ni;
81     struct lndstr land;
82     struct lchrstr *lp;
83     int n;
84     int tlev;
85     int avail, cost;
86     long cash;
87
88     if (!snxtitem(&ni, EF_LAND, player->argp[2], NULL))
89         return RET_SYN;
90     natp = getnatp(player->cnum);
91     cash = natp->nat_money;
92     tlev = (int)natp->nat_level[NAT_TLEV];
93     n = 0;
94     while (nxtitem(&ni, &land)) {
95         if (land.lnd_own == 0)
96             continue;
97         getsect(land.lnd_x, land.lnd_y, &sect);
98         if (sect.sct_own != player->cnum)
99             continue;
100         if (sect.sct_type != SCT_HEADQ || sect.sct_effic < 60)
101             continue;
102         if (relations_with(land.lnd_own, sect.sct_own) < FRIENDLY) {
103             pr("You are not on friendly terms with the owner of unit %d!\n",
104                land.lnd_uid);
105             continue;
106         }
107         n++;
108         lp = &lchr[(int)land.lnd_type];
109         avail = (LND_BLD_WORK(lp->l_lcm, lp->l_hcm) * UPGR_COST + 99) / 100;
110         if (sect.sct_avail < avail) {
111             pr("Not enough available work in %s to upgrade a %s\n",
112                xyas(sect.sct_x, sect.sct_y, player->cnum), lp->l_name);
113             pr(" (%d available work required)\n", avail);
114             continue;
115         }
116         if (land.lnd_effic < 60) {
117             pr("%s is too damaged to upgrade!\n", prland(&land));
118             continue;
119         }
120         if (land.lnd_tech >= tlev) {
121             pr("%s tech: %d, yours is only %d\n",
122                prland(&land), land.lnd_tech, tlev);
123             continue;
124         }
125         cost = lp->l_cost * UPGR_COST / 100;
126         if (cost + player->dolcost > cash) {
127             pr("You don't have enough money to upgrade %s!\n",
128                prland(&land));
129             continue;
130         }
131
132         sect.sct_avail -= avail;
133         land.lnd_effic -= UPGR_EFF;
134         lnd_set_tech(&land, tlev);
135         land.lnd_harden = 0;
136         land.lnd_mission = 0;
137
138         putland(land.lnd_uid, &land);
139         putsect(&sect);
140         player->dolcost += cost;
141         pr("%s upgraded to tech %d, at a cost of %d\n",
142            prland(&land), land.lnd_tech, cost);
143         if (land.lnd_own != player->cnum)
144             wu(0, land.lnd_own,
145                "%s upgraded by %s to tech %d, at a cost of %d\n",
146                prland(&land), cname(player->cnum), land.lnd_tech, cost);
147     }
148     if (n == 0) {
149         pr("No land units\n");
150         return RET_SYN;
151     }
152     return RET_OK;
153 }
154
155 static int
156 supgr(void)
157 {
158     struct sctstr sect;
159     struct natstr *natp;
160     struct nstr_item ni;
161     struct shpstr ship;
162     struct mchrstr *mp;
163     int n;
164     int tlev;
165     int avail, cost;
166     long cash;
167
168     if (!snxtitem(&ni, EF_SHIP, player->argp[2], NULL))
169         return RET_SYN;
170     natp = getnatp(player->cnum);
171     cash = natp->nat_money;
172     tlev = (int)natp->nat_level[NAT_TLEV];
173     n = 0;
174     while (nxtitem(&ni, &ship)) {
175         if (ship.shp_own == 0)
176             continue;
177         getsect(ship.shp_x, ship.shp_y, &sect);
178         if (sect.sct_own != player->cnum)
179             continue;
180         if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60)
181             continue;
182         if (relations_with(ship.shp_own, sect.sct_own) < FRIENDLY) {
183             pr("You are not on friendly terms with the owner of ship %d!\n",
184                ship.shp_uid);
185             continue;
186         }
187         n++;
188         mp = &mchr[(int)ship.shp_type];
189         avail = (SHP_BLD_WORK(mp->m_lcm, mp->m_hcm) * UPGR_COST + 99) / 100;
190         if (sect.sct_avail < avail) {
191             pr("Not enough available work in %s to upgrade a %s\n",
192                xyas(sect.sct_x, sect.sct_y, player->cnum), mp->m_name);
193             pr(" (%d available work required)\n", avail);
194             continue;
195         }
196         if (ship.shp_effic < 60) {
197             pr("%s is too damaged to upgrade!\n", prship(&ship));
198             continue;
199         }
200         if (ship.shp_tech >= tlev) {
201             pr("%s tech: %d, yours is only %d\n",
202                prship(&ship), ship.shp_tech, tlev);
203             continue;
204         }
205         cost = mp->m_cost * UPGR_COST / 100;
206         if (cost + player->dolcost > cash) {
207             pr("You don't have enough money to upgrade %s!\n",
208                prship(&ship));
209             continue;
210         }
211
212         sect.sct_avail -= avail;
213         ship.shp_effic -= UPGR_EFF;
214         shp_set_tech(&ship, tlev);
215         ship.shp_mission = 0;
216
217         putship(ship.shp_uid, &ship);
218         putsect(&sect);
219         player->dolcost += cost;
220         pr("%s upgraded to tech %d, at a cost of %d\n",
221            prship(&ship), ship.shp_tech, cost);
222         if (ship.shp_own != player->cnum)
223             wu(0, ship.shp_own,
224                "%s upgraded by %s to tech %d, at a cost of %d\n",
225                prship(&ship), cname(player->cnum), ship.shp_tech, cost);
226     }
227     if (n == 0) {
228         pr("No ships\n");
229         return RET_SYN;
230     }
231     return RET_OK;
232 }
233
234 static int
235 pupgr(void)
236 {
237     struct sctstr sect;
238     struct natstr *natp;
239     struct nstr_item ni;
240     struct plnstr plane;
241     struct plchrstr *pp;
242     int n;
243     int tlev;
244     int avail, cost;
245     long cash;
246
247     if (!snxtitem(&ni, EF_PLANE, player->argp[2], NULL))
248         return RET_SYN;
249     natp = getnatp(player->cnum);
250     cash = natp->nat_money;
251     tlev = (int)natp->nat_level[NAT_TLEV];
252     n = 0;
253     while (nxtitem(&ni, &plane)) {
254         if (plane.pln_own == 0)
255             continue;
256         getsect(plane.pln_x, plane.pln_y, &sect);
257         if (sect.sct_own != player->cnum)
258             continue;
259         if (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)
260             continue;
261         if (relations_with(plane.pln_own, sect.sct_own) < FRIENDLY) {
262             pr("You are not on friendly terms with the owner of plane %d!\n",
263                plane.pln_uid);
264             continue;
265         }
266         if (pln_is_in_orbit(&plane)) {
267             pr("Plane %s is in orbit!\n", prplane(&plane));
268             continue;
269         }
270         if (plane.pln_flags & PLN_LAUNCHED)
271             continue;
272         n++;
273         pp = &plchr[(int)plane.pln_type];
274         avail = (PLN_BLD_WORK(pp->pl_lcm, pp->pl_hcm) * UPGR_COST + 99) / 100;
275         if (sect.sct_avail < avail) {
276             pr("Not enough available work in %s to upgrade a %s\n",
277                xyas(sect.sct_x, sect.sct_y, player->cnum), pp->pl_name);
278             pr(" (%d available work required)\n", avail);
279             continue;
280         }
281         if (plane.pln_effic < 60) {
282             pr("%s is too damaged to upgrade!\n", prplane(&plane));
283             continue;
284         }
285         if (plane.pln_tech >= tlev) {
286             pr("%s tech: %d, yours is only %d\n",
287                prplane(&plane), plane.pln_tech, tlev);
288             continue;
289         }
290         cost = pp->pl_cost * UPGR_COST / 100;
291         if (cost + player->dolcost > cash) {
292             pr("You don't have enough money to upgrade %s!\n",
293                prplane(&plane));
294             continue;
295         }
296
297         sect.sct_avail -= avail;
298         plane.pln_effic -= UPGR_EFF;
299         pln_set_tech(&plane, tlev);
300         plane.pln_harden = 0;
301         plane.pln_mission = 0;
302
303         putplane(plane.pln_uid, &plane);
304         putsect(&sect);
305         player->dolcost += cost;
306         pr("%s upgraded to tech %d, at a cost of %d\n",
307            prplane(&plane), plane.pln_tech, cost);
308         if (plane.pln_own != player->cnum)
309             wu(0, plane.pln_own,
310                "%s upgraded by %s to tech %d, at a cost of %d\n",
311                prplane(&plane), cname(player->cnum), plane.pln_tech, cost);
312     }
313     if (n == 0) {
314         pr("No planes.\n");
315         return RET_SYN;
316     }
317     return RET_OK;
318 }