]> git.pond.sub.org Git - empserver/blob - src/lib/commands/retr.c
Make retr() and lretr() simpler and more robust
[empserver] / src / lib / commands / retr.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2008, 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  *  retr.c: Set retreat conditionals for ships
29  * 
30  *  Known contributors to this file:
31  *     Ken Stevens, 1995
32  *     Steve McClure, 2000
33  */
34
35 #include <config.h>
36
37 #include <ctype.h>
38 #include "commands.h"
39 #include "land.h"
40 #include "path.h"
41 #include "retreat.h"
42 #include "ship.h"
43
44 int
45 retr(void)
46 {
47     char *pq, *fl;
48     int nships;
49     struct nstr_item ni;
50     struct shpstr ship;
51     int rflags;
52     unsigned i;
53     char buf1[1024];
54     char buf2[1024];
55
56     if (!snxtitem(&ni, EF_SHIP, player->argp[1]))
57         return RET_SYN;
58     nships = 0;
59     if (player->argp[2] != NULL)
60         pq = getstarg(player->argp[2], "Retreat path? ", buf1);
61     else
62         pq = NULL;
63
64     rflags = 0;
65     if (pq != NULL) {
66         fl = getstarg(player->argp[3],
67                       "Retreat conditions [i|t|s|h|b|d|u|c]? ", buf2);
68         if (!fl)
69             return RET_SYN;
70
71         for (i = 0; fl[i]; i++) {
72             switch (fl[i]) {
73             case 'I':
74             case 'i':
75                 rflags |= RET_INJURED;
76                 break;
77             case 'T':
78             case 't':
79                 rflags |= RET_TORPED;
80                 break;
81             case 'S':
82             case 's':
83                 rflags |= RET_SONARED;
84                 break;
85             case 'H':
86             case 'h':
87                 rflags |= RET_HELPLESS;
88                 break;
89             case 'B':
90             case 'b':
91                 rflags |= RET_BOMBED;
92                 break;
93             case 'D':
94             case 'd':
95                 rflags |= RET_DCHRGED;
96                 break;
97             case 'U':
98             case 'u':
99                 rflags |= RET_BOARDED;
100                 break;
101             case 'C':
102             case 'c':
103                 pq = "";
104                 break;
105             default:
106                 pr("bad condition\n");
107                 /* fall through */
108             case '?':
109                 pr("i\tretreat when injured\n");
110                 pr("t\tretreat when torped\n");
111                 pr("s\tretreat when sonared\n");
112                 pr("h\tretreat when helpless\n");
113                 pr("b\tretreat when bombed\n");
114                 pr("d\tretreat when depth-charged\n");
115                 pr("u\tretreat when boarded\n");
116             }
117         }
118         if (*pq && !rflags) {
119             pr("Must give retreat conditions!\n");
120             return RET_FAIL;
121         }
122         if (ni.sel == NS_GROUP && ni.group)
123             rflags |= RET_GROUP;
124         if (!*pq)
125             rflags = 0;
126     }
127
128     while (nxtitem(&ni, &ship)) {
129         if (!player->owner || ship.shp_own == 0)
130             continue;
131         if (pq != NULL) {
132             strncpy(ship.shp_rpath, pq, sizeof(ship.shp_rpath) - 1);
133             ship.shp_rflags = rflags;
134             putship(ship.shp_uid, &ship);
135         }
136         if (nships++ == 0) {
137             if (player->god)
138                 pr("own ");
139             pr("shp#     ship type       x,y   fl path       as flt? flags\n");
140         }
141         if (player->god)
142             pr("%3d ", ship.shp_own);
143         pr("%4d ", ni.cur);
144         pr("%-16.16s ", mchr[(int)ship.shp_type].m_name);
145         prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
146         pr("%1.1s", &ship.shp_fleet);
147         pr(" %-11s", ship.shp_rpath);
148         if (ship.shp_rflags & RET_GROUP)
149             pr("Yes     ");
150         else
151             pr("        ");
152         if (ship.shp_rflags & RET_INJURED)
153             pr("I");
154         if (ship.shp_rflags & RET_TORPED)
155             pr("T");
156         if (ship.shp_rflags & RET_SONARED)
157             pr("S");
158         if (ship.shp_rflags & RET_HELPLESS)
159             pr("H");
160         if (ship.shp_rflags & RET_BOMBED)
161             pr("B");
162         if (ship.shp_rflags & RET_DCHRGED)
163             pr("D");
164         if (ship.shp_rflags & RET_BOARDED)
165             pr("U");
166         pr("\n");
167     }
168     if (nships == 0) {
169         if (player->argp[1])
170             pr("%s: No ship(s)\n", player->argp[1]);
171         else
172             pr("%s: No ship(s)\n", "");
173         return RET_FAIL;
174     } else
175         pr("%d ship%s\n", nships, splur(nships));
176     return RET_OK;
177 }
178
179 int
180 lretr(void)
181 {
182     char *pq, *fl;
183     int nunits;
184     struct nstr_item ni;
185     struct lndstr land;
186     int rflags;
187     unsigned i;
188     char buf1[1024];
189     char buf2[1024];
190
191     if (!snxtitem(&ni, EF_LAND, player->argp[1]))
192         return RET_SYN;
193     nunits = 0;
194     if (player->argp[2] != NULL)
195         pq = getstarg(player->argp[2], "Retreat path? ", buf1);
196     else
197         pq = NULL;
198
199     rflags = 0;
200     if (pq != NULL) {
201         fl = getstarg(player->argp[3], "Retreat conditions [i|h|b|c]? ",
202                       buf2);
203         if (!fl)
204             return RET_SYN;
205
206         for (i = 0; fl[i]; i++) {
207             switch (fl[i]) {
208             case 'I':
209             case 'i':
210                 rflags |= RET_INJURED;
211                 break;
212             case 'H':
213             case 'h':
214                 rflags |= RET_HELPLESS;
215                 break;
216             case 'B':
217             case 'b':
218                 rflags |= RET_BOMBED;
219                 break;
220             case 'C':
221             case 'c':
222                 pq = "";
223                 break;
224             default:
225                 pr("bad condition\n");
226                 /* fall through */
227             case '?':
228                 pr("i\tretreat when injured\n");
229                 pr("h\tretreat when helpless\n");
230                 pr("b\tretreat when bombed\n");
231             }
232         }
233         if (*pq && !rflags) {
234             pr("Must give retreat conditions!\n");
235             return RET_FAIL;
236         }
237         if (ni.sel == NS_GROUP && ni.group)
238             rflags |= RET_GROUP;
239         if (!*pq)
240             rflags = 0;
241     }
242
243     while (nxtitem(&ni, &land)) {
244         if (!player->owner || land.lnd_own == 0)
245             continue;
246         if (pq != NULL) {
247             strncpy(land.lnd_rpath, pq, sizeof(land.lnd_rpath) - 1);
248             land.lnd_rflags = rflags;
249             putland(land.lnd_uid, &land);
250         }
251
252         if (nunits++ == 0) {
253             if (player->god)
254                 pr("own ");
255             pr("lnd#     unit type       x,y   ar path       as army? flags\n");
256         }
257         if (player->god)
258             pr("%3d ", land.lnd_own);
259         pr("%4d ", ni.cur);
260         pr("%-16.16s ", lchr[(int)land.lnd_type].l_name);
261         prxy("%4d,%-4d ", land.lnd_x, land.lnd_y, player->cnum);
262         pr("%1.1s", &land.lnd_army);
263         pr(" %-11s", land.lnd_rpath);
264         if (land.lnd_rflags & RET_GROUP)
265             pr("Yes      ");
266         else
267             pr("         ");
268         if (land.lnd_rflags & RET_INJURED)
269             pr("I");
270         if (land.lnd_rflags & RET_TORPED)
271             pr("T");
272         if (land.lnd_rflags & RET_SONARED)
273             pr("S");
274         if (land.lnd_rflags & RET_HELPLESS)
275             pr("H");
276         if (land.lnd_rflags & RET_BOMBED)
277             pr("B");
278         if (land.lnd_rflags & RET_DCHRGED)
279             pr("D");
280         if (land.lnd_rflags & RET_BOARDED)
281             pr("U");
282         pr("\n");
283     }
284     if (nunits == 0) {
285         if (player->argp[1])
286             pr("%s: No unit(s)\n", player->argp[1]);
287         else
288             pr("%s: No unit(s)\n", "");
289         return RET_FAIL;
290     }
291     pr("%d unit%s\n", nunits, splur(nunits));
292     return RET_OK;
293 }