]> 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-2017, 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  *  scra.c: Scrap ships, planes or land units
28  *
29  *  Known contributors to this file:
30  *     Steve McClure, 2000
31  *     Markus Armbruster, 2004-2016
32  */
33
34 #include <config.h>
35
36 #include <ctype.h>
37 #include "chance.h"
38 #include "commands.h"
39 #include "optlist.h"
40 #include "plague.h"
41 #include "unit.h"
42
43 int
44 scra(void)
45 {
46     struct nstr_item ni;
47     union empobj_storage item;
48     int type, n;
49     struct sctstr sect;
50     struct mchrstr *mp;
51     struct plchrstr *pp;
52     struct lchrstr *lp;
53     char *p;
54     i_type i;
55     char prompt[128];
56     char buf[1024];
57     float eff;
58     short *mvec;
59     int amt;
60
61     if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf)))
62         return RET_SYN;
63     switch (*p) {
64     case 's':
65         type = EF_SHIP;
66         break;
67     case 'p':
68         type = EF_PLANE;
69         break;
70     case 'l':
71         type = EF_LAND;
72         break;
73     default:
74         pr("Ships, land units, or planes only! (s, l, p)\n");
75         return RET_SYN;
76     }
77
78     if (!snxtitem(&ni, type, player->argp[2], NULL))
79         return RET_SYN;
80     n = 0;
81     while (nxtitem(&ni, &item)) {
82         if (!player->owner)
83             continue;
84         n++;
85     }
86     snprintf(prompt, sizeof(prompt), "Really scrap %d %s%s [n]? ",
87                             n, ef_nameof(type), splur(n));
88     if (!confirm(prompt))
89         return RET_FAIL;
90
91     snxtitem_rewind(&ni);
92     while (nxtitem(&ni, &item)) {
93         if (!player->owner)
94             continue;
95
96         if (opt_MARKET) {
97             if (ontradingblock(type, &item.ship)) {
98                 pr("You cannot scrap an item on the trading block!\n");
99                 continue;
100             }
101         }
102
103         getsect(item.gen.x, item.gen.y, &sect);
104         if (type == EF_SHIP) {
105             if (!player->owner
106                 && relations_with(sect.sct_own, player->cnum) < FRIENDLY) {
107                 pr("%s is not in a friendly harbor!\n",
108                    prship(&item.ship));
109                 continue;
110             }
111             if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60) {
112                 pr("%s is not in a 60%% efficient harbor!\n",
113                    prship(&item.ship));
114                 continue;
115             }
116             if (mchr[item.ship.shp_type].m_flags & M_TRADE) {
117                 pr("WARNING: You only collect money from trade ships if you \"scuttle\" them!\n");
118                 sprintf(prompt,
119                         "Are you really sure that you want to scrap %s (n)? ",
120                         prship(&item.ship));
121                 if (!confirm(prompt)) {
122                     pr("%s not scrapped\n", prship(&item.ship));
123                     continue;
124                 }
125             }
126         } else {
127             if (!player->owner
128                 && relations_with(sect.sct_own, player->cnum) != ALLIED) {
129                 pr("%s is not in an allied sector!\n",
130                    unit_nameof(&item.gen));
131                 continue;
132             }
133             if (type == EF_PLANE
134                 && (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)) {
135                 pr("%s is not in a 60%% efficient airfield!\n",
136                    prplane(&item.plane));
137                 continue;
138             }
139         }
140
141         pr("%s scrapped in %s\n",
142            unit_nameof(&item.gen),
143            xyas(item.gen.x, item.gen.y, player->cnum));
144         unit_drop_cargo(&item.gen, sect.sct_own);
145         if (type == EF_SHIP) {
146             eff = item.ship.shp_effic / 100.0;
147             mp = &mchr[(int)item.ship.shp_type];
148             for (i = I_NONE + 1; i <= I_MAX; i++) {
149                 if (load_comm_ok(&sect, item.ship.shp_own, i,
150                                  -item.ship.shp_item[i]))
151                     sect.sct_item[i] += item.ship.shp_item[i];
152             }
153             mvec = mp->m_mat;
154             if (item.ship.shp_pstage == PLG_INFECT
155                 && sect.sct_pstage == PLG_HEALTHY)
156                 sect.sct_pstage = PLG_EXPOSED;
157         } else if (type == EF_LAND) {
158             eff = item.land.lnd_effic / 100.0;
159             lp = &lchr[(int)item.land.lnd_type];
160             for (i = I_NONE + 1; i <= I_MAX; i++) {
161                 if (load_comm_ok(&sect, item.land.lnd_own, i,
162                                  -item.land.lnd_item[i]))
163                     sect.sct_item[i] += item.land.lnd_item[i];
164             }
165             mvec = lp->l_mat;
166             if (item.land.lnd_pstage == PLG_INFECT
167                 && sect.sct_pstage == PLG_HEALTHY)
168                 sect.sct_pstage = PLG_EXPOSED;
169         } else {
170             eff = item.land.lnd_effic / 100.0;
171             pp = &plchr[(int)item.plane.pln_type];
172             mvec = pp->pl_mat;
173         }
174         item.gen.effic = 0;
175         put_empobj(type, item.gen.uid, &item.gen);
176         for (i = I_NONE + 1; i <= I_MAX; i++) {
177             if (i == I_CIVIL || i == I_MILIT || i == I_UW)
178                 amt = sect.sct_item[i] + mvec[i] * eff;
179             else
180                 amt = sect.sct_item[i] + mvec[i] * 2 / 3 * eff;
181             if (amt > ITEM_MAX)
182                 amt = ITEM_MAX;
183             sect.sct_item[i] = amt;
184         }
185         putsect(&sect);
186     }
187     return RET_OK;
188 }