]> git.pond.sub.org Git - empserver/blob - src/lib/commands/scra.c
Update copyright notice.
[empserver] / src / lib / commands / scra.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2005, 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  *  scra.c: Scrap ships, planes or land units
29  * 
30  *  Known contributors to this file:
31  *     Steve McClure, 2000
32  *     
33  */
34
35 #include "misc.h"
36 #include "player.h"
37 #include "xy.h"
38 #include "sect.h"
39 #include "ship.h"
40 #include "plane.h"
41 #include "land.h"
42 #include "nat.h"
43 #include "nsc.h"
44 #include "file.h"
45 #include "commands.h"
46 #include "optlist.h"
47
48 union item_u {
49     struct shpstr ship;
50     struct plnstr plane;
51     struct lndstr land;
52 };
53
54 int
55 scra(void)
56 {
57     struct nstr_item ni;
58     union item_u item;
59     int type;
60     struct sctstr sect;
61     struct mchrstr *mp;
62     struct plchrstr *pp;
63     struct lchrstr *lp;
64     s_char *p;
65     i_type i;
66     struct nstr_item ni2;
67     struct plnstr plane;
68     struct lndstr land;
69     struct sctstr sect2;
70     s_char prompt[128];
71     s_char buf[1024];
72     float eff;
73
74     if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
75         return RET_SYN;
76     switch (*p) {
77     case 's':
78         type = EF_SHIP;
79         break;
80     case 'p':
81         type = EF_PLANE;
82         break;
83     case 'l':
84         type = EF_LAND;
85         break;
86     default:
87         pr("Ships, land units, or planes only! (s, l, p)\n");
88         return RET_SYN;
89     }
90     sprintf(prompt, "%s(s)? ", ef_nameof(type));
91     if ((p = getstarg(player->argp[2], prompt, buf)) == 0)
92         return RET_SYN;
93     if (!snxtitem(&ni, type, p))
94         return RET_SYN;
95     if (p && (isalpha(*p) || (*p == '*') || (*p == '~') || issector(p)
96               || islist(p))) {
97         s_char y_or_n[80], bbuf[80];
98
99         memset(y_or_n, 0, sizeof(y_or_n));
100         if (type == EF_SHIP) {
101             if (*p == '*')
102                 sprintf(bbuf, "all ships");
103             else if (*p == '~')
104                 sprintf(bbuf, "all unassigned ships");
105             else if (issector(p))
106                 sprintf(bbuf, "all ships in %s", p);
107             else if (isalpha(*p))
108                 sprintf(bbuf, "fleet %c", *p);
109             else
110                 sprintf(bbuf, "ships %s", p);
111         } else if (type == EF_LAND) {
112             if (*p == '*')
113                 sprintf(bbuf, "all land units");
114             else if (*p == '~')
115                 sprintf(bbuf, "all unassigned land units");
116             else if (issector(p))
117                 sprintf(bbuf, "all units in %s", p);
118             else if (isalpha(*p))
119                 sprintf(bbuf, "army %c", *p);
120             else
121                 sprintf(bbuf, "units %s", p);
122         } else {
123             if (*p == '*')
124                 sprintf(bbuf, "all planes");
125             else if (*p == '~')
126                 sprintf(bbuf, "all unassigned planes");
127             else if (issector(p))
128                 sprintf(bbuf, "all planes in %s", p);
129             else if (isalpha(*p))
130                 sprintf(bbuf, "wing %c", *p);
131             else
132                 sprintf(bbuf, "planes %s", p);
133         }
134
135         sprintf(y_or_n, "Really scrap %s [n]? ", bbuf);
136         if (!confirm(y_or_n))
137             return RET_FAIL;
138     }
139     while (nxtitem(&ni, (s_char *)&item)) {
140         if (!player->owner)
141             continue;
142
143         if (opt_MARKET) {
144             if (ontradingblock(type, (int *)&item.ship)) {
145                 pr("You cannot scrap an item on the trading block!\n");
146                 continue;
147             }
148         }
149
150         if (type == EF_SHIP) {
151             getsect(item.ship.shp_x, item.ship.shp_y, &sect);
152             if (sect.sct_type != SCT_HARBR)
153                 continue;
154             if (sect.sct_effic < 60 || sect.sct_own != player->cnum)
155                 continue;
156         } else if (type == EF_LAND) {
157             if (item.land.lnd_ship >= 0) {
158                 pr("%s is on a ship, and cannot be scrapped!\n",
159                    prland(&item.land));
160                 continue;
161             }
162             getsect(item.land.lnd_x, item.land.lnd_y, &sect);
163         } else {
164             getsect(item.plane.pln_x, item.plane.pln_y, &sect);
165             if (sect.sct_type != SCT_AIRPT)
166                 continue;
167             if (sect.sct_effic < 60 ||
168                 (sect.sct_own != player->cnum &&
169                  getrel(getnatp(sect.sct_own), player->cnum) < FRIENDLY))
170                 continue;
171         }
172         if (type == EF_SHIP) {
173             eff = ((float)item.ship.shp_effic / 100.0);
174             mp = &mchr[(int)item.ship.shp_type];
175             if (opt_TRADESHIPS) {
176                 if (mp->m_flags & M_TRADE) {
177                     pr("WARNING: You only collect money from trade ships if you \"scuttle\" them!\n");
178                     sprintf(prompt,
179                             "Are you really sure that you want to scrap %s (n)? ",
180                             prship(&item.ship));
181                     if (!confirm(prompt)) {
182                         pr("%s not scrapped\n", prship(&item.ship));
183                         continue;
184                     }
185                 }
186             }
187             pr("%s", prship(&item.ship));
188             for (i = I_NONE + 1; i <= I_MAX; i++) {
189                 sect.sct_item[i] += item.ship.shp_item[i];
190             }
191             sect.sct_item[I_LCM] += mp->m_lcm * 2 / 3 * eff;
192             sect.sct_item[I_HCM] += mp->m_hcm * 2 / 3 * eff;
193             getsect(item.ship.shp_x, item.ship.shp_y, &sect2);
194             snxtitem_all(&ni2, EF_PLANE);
195             while (nxtitem(&ni2, (s_char *)&plane)) {
196                 if (plane.pln_own == 0)
197                     continue;
198                 if (plane.pln_ship == item.ship.shp_uid) {
199                     wu(0, plane.pln_own,
200                        "Plane %d transferred off ship %d to %s\n",
201                        ni2.cur, item.ship.shp_uid,
202                        xyas(plane.pln_x, plane.pln_y, player->cnum));
203                     plane.pln_ship = -1;
204                     if (sect2.sct_own != plane.pln_own) {
205                         wu(0, plane.pln_own,
206                            "%s given to %s\n", prplane(&plane),
207                            cname(sect2.sct_own));
208                         wu(0, sect2.sct_own,
209                            "%s given to you by %s\n", prplane(&plane),
210                            cname(player->cnum));
211                     }
212                     makelost(EF_PLANE, plane.pln_own, plane.pln_uid,
213                              plane.pln_x, plane.pln_y);
214                     plane.pln_own = sect2.sct_own;
215                     makenotlost(EF_PLANE, plane.pln_own, plane.pln_uid,
216                                 plane.pln_x, plane.pln_y);
217                     putplane(plane.pln_uid, (s_char *)&plane);
218                 }
219             }
220             snxtitem_all(&ni2, EF_LAND);
221             while (nxtitem(&ni2, (s_char *)&land)) {
222                 if (land.lnd_own == 0)
223                     continue;
224                 if (land.lnd_ship == item.ship.shp_uid) {
225                     wu(0, land.lnd_own,
226                        "Land unit %d transferred off ship %d to %s\n",
227                        ni2.cur, item.ship.shp_uid,
228                        xyas(land.lnd_x, land.lnd_y, player->cnum));
229                     land.lnd_ship = -1;
230                     if (sect2.sct_own != land.lnd_own) {
231                         wu(0, land.lnd_own,
232                            "%s given to %s\n", prland(&land),
233                            cname(sect2.sct_own));
234                         wu(0, sect2.sct_own,
235                            "%s given to you by %s\n", prland(&land),
236                            cname(player->cnum));
237                     }
238                     makelost(EF_LAND, land.lnd_own, land.lnd_uid,
239                              land.lnd_x, land.lnd_y);
240                     land.lnd_own = sect2.sct_own;
241                     makenotlost(EF_LAND, land.lnd_own, land.lnd_uid,
242                                 land.lnd_x, land.lnd_y);
243                     putland(land.lnd_uid, (s_char *)&land);
244                 }
245             }
246             makelost(EF_SHIP, item.ship.shp_own, item.ship.shp_uid,
247                      item.ship.shp_x, item.ship.shp_y);
248             item.ship.shp_own = 0;
249             putship(item.ship.shp_uid, (s_char *)&item.ship);
250         } else if (type == EF_LAND) {
251             eff = ((float)item.land.lnd_effic / 100.0);
252             lp = &lchr[(int)item.land.lnd_type];
253             pr("%s", prland(&item.land));
254             for (i = I_NONE + 1; i <= I_MAX; i++) {
255                 sect.sct_item[i] += item.land.lnd_item[i];
256             }
257             sect.sct_item[I_LCM] += lp->l_lcm * 2 / 3 * eff;
258             sect.sct_item[I_HCM] += lp->l_hcm * 2 / 3 * eff;
259             getsect(item.land.lnd_x, item.land.lnd_y, &sect2);
260
261             snxtitem_all(&ni2, EF_LAND);
262             while (nxtitem(&ni2, (s_char *)&land)) {
263                 if (land.lnd_own == 0)
264                     continue;
265                 if (land.lnd_land == item.land.lnd_uid) {
266                     wu(0, land.lnd_own,
267                        "Land unit %d transferred off land unit %d to %s\n",
268                        land.lnd_uid, item.land.lnd_uid,
269                        xyas(land.lnd_x, land.lnd_y, player->cnum));
270                     land.lnd_land = -1;
271                     if (sect2.sct_own != land.lnd_own) {
272                         wu(0, land.lnd_own,
273                            "%s given to %s\n", prland(&land),
274                            cname(sect2.sct_own));
275                         wu(0, sect2.sct_own,
276                            "%s given to you by %s\n", prland(&land),
277                            cname(player->cnum));
278                     }
279                     makelost(EF_LAND, land.lnd_own, land.lnd_uid,
280                              land.lnd_x, land.lnd_y);
281                     land.lnd_own = sect2.sct_own;
282                     makenotlost(EF_LAND, land.lnd_own, land.lnd_uid,
283                                 land.lnd_x, land.lnd_y);
284                     putland(land.lnd_uid, (s_char *)&land);
285                 }
286             }
287
288             snxtitem_all(&ni2, EF_PLANE);
289             while (nxtitem(&ni2, (s_char *)&plane)) {
290                 if (plane.pln_own == 0)
291                     continue;
292                 if (plane.pln_land == item.land.lnd_uid) {
293                     wu(0, plane.pln_own,
294                        "Plane %d transferred off land unit %d to %s\n",
295                        ni2.cur, item.land.lnd_uid,
296                        xyas(plane.pln_x, plane.pln_y, player->cnum));
297                     plane.pln_land = -1;
298                     if (sect2.sct_own != plane.pln_own) {
299                         wu(0, plane.pln_own,
300                            "%s given to %s\n", prplane(&plane),
301                            cname(sect2.sct_own));
302                         wu(0, sect2.sct_own,
303                            "%s given to you by %s\n", prplane(&plane),
304                            cname(player->cnum));
305                     }
306                     makelost(EF_PLANE, plane.pln_own, plane.pln_uid,
307                              plane.pln_x, plane.pln_y);
308                     plane.pln_own = sect2.sct_own;
309                     makenotlost(EF_PLANE, plane.pln_own, plane.pln_uid,
310                                 plane.pln_x, plane.pln_y);
311                     putplane(plane.pln_uid, (s_char *)&plane);
312                 }
313             }
314             makelost(EF_LAND, item.land.lnd_own, item.land.lnd_uid,
315                      item.land.lnd_x, item.land.lnd_y);
316             item.land.lnd_own = 0;
317             putland(item.land.lnd_uid, (s_char *)&item.land);
318         } else {
319             eff = ((float)item.land.lnd_effic / 100.0);
320             pp = &plchr[(int)item.plane.pln_type];
321             pr("%s", prplane(&item.plane));
322             sect.sct_item[I_LCM] += pp->pl_lcm * 2 / 3 * eff;
323             sect.sct_item[I_HCM] += pp->pl_hcm * 2 / 3 * eff;
324             sect.sct_item[I_MILIT] += pp->pl_crew;
325             makelost(EF_PLANE, item.plane.pln_own, item.plane.pln_uid,
326                      item.plane.pln_x, item.plane.pln_y);
327             item.plane.pln_own = 0;
328             putplane(item.plane.pln_uid, (s_char *)&item.plane);
329         }
330         pr(" scrapped in %s\n",
331            xyas(sect.sct_x, sect.sct_y, player->cnum));
332         for (i = I_NONE + 1; i <= I_MAX; i++) {
333             if (sect.sct_item[i] > ITEM_MAX)
334                 sect.sct_item[i] = ITEM_MAX;
335         }
336         putsect(&sect);
337     }
338     return RET_OK;
339 }