]> git.pond.sub.org Git - empserver/blob - src/lib/commands/retr.c
0f0f3bd4905fe158484513030d950e62dbbbe995
[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 and land units
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 "empobj.h"
40 #include "land.h"
41 #include "path.h"
42 #include "retreat.h"
43 #include "ship.h"
44
45 static int retreat(short);
46
47 int
48 retr(void)
49 {
50     return retreat(EF_SHIP);
51 }
52
53 int
54 lretr(void)
55 {
56     return retreat(EF_LAND);
57 }
58
59 static int
60 retreat(short type)
61 {
62     char *pq, *fl;
63     int nunits;
64     struct nstr_item ni;
65     union empobj_storage unit;
66     int rflags;
67     unsigned i;
68     char *name, *rpath, *what;
69     int *rflagsp;
70     char buf1[1024];
71     char buf2[1024];
72
73     if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
74         type = EF_SHIP;
75
76     if (!snxtitem(&ni, type, player->argp[1]))
77         return RET_SYN;
78     nunits = 0;
79     if (player->argp[2] != NULL)
80         pq = getstarg(player->argp[2], "Retreat path? ", buf1);
81     else
82         pq = NULL;
83
84     rflags = 0;
85     if (pq != NULL) {
86         fl = getstarg(player->argp[3],
87                       type == EF_SHIP
88                       ? "Retreat conditions [i|t|s|h|b|d|u|c]? "
89                       : "Retreat conditions [i|h|b|c]? ",
90                       buf2);
91         if (!fl)
92             return RET_SYN;
93
94         for (i = 0; fl[i]; i++) {
95             switch (fl[i]) {
96             case 'I':
97             case 'i':
98                 rflags |= RET_INJURED;
99                 break;
100             case 'T':
101             case 't':
102                 if (type == EF_LAND)
103                     goto badflag;
104                 rflags |= RET_TORPED;
105                 break;
106             case 'S':
107             case 's':
108                 if (type == EF_LAND)
109                     goto badflag;
110                 rflags |= RET_SONARED;
111                 break;
112             case 'H':
113             case 'h':
114                 rflags |= RET_HELPLESS;
115                 break;
116             case 'B':
117             case 'b':
118                 rflags |= RET_BOMBED;
119                 break;
120             case 'D':
121             case 'd':
122                 if (type == EF_LAND)
123                     goto badflag;
124                 rflags |= RET_DCHRGED;
125                 break;
126             case 'U':
127             case 'u':
128                 if (type == EF_LAND)
129                     goto badflag;
130                 rflags |= RET_BOARDED;
131                 break;
132             case 'C':
133             case 'c':
134                 pq = "";
135                 break;
136             default:
137             badflag:
138                 pr("bad condition\n");
139                 /* fall through */
140             case '?':
141                 pr("i\tretreat when injured\n");
142                 if (type == EF_SHIP) {
143                     pr("t\tretreat when torped\n");
144                     pr("s\tretreat when sonared\n");
145                 }
146                 pr("h\tretreat when helpless\n");
147                 pr("b\tretreat when bombed\n");
148                 if (type == EF_SHIP) {
149                     pr("d\tretreat when depth-charged\n");
150                     pr("u\tretreat when boarded\n");
151                 }
152             }
153         }
154         if (*pq && !rflags) {
155             pr("Must give retreat conditions!\n");
156             return RET_FAIL;
157         }
158         if (ni.sel == NS_GROUP && ni.group)
159             rflags |= RET_GROUP;
160         if (!*pq)
161             rflags = 0;
162     }
163
164     while (nxtitem(&ni, &unit)) {
165         if (!player->owner || unit.gen.own == 0)
166             continue;
167         if (type == EF_SHIP) {
168             if (nunits++ == 0) {
169                 if (player->god)
170                     pr("own ");
171                 pr("shp#     ship type       x,y   fl path       as flt?  flags\n");
172             }
173             name = mchr[unit.ship.shp_type].m_name;
174             rpath = unit.ship.shp_rpath;
175             rflagsp = &unit.ship.shp_rflags;
176         } else {
177             if (nunits++ == 0) {
178                 if (player->god)
179                     pr("own ");
180                 pr("lnd#     unit type       x,y   ar path       as army? flags\n");
181             }
182             name = lchr[unit.land.lnd_type].l_name;
183             rpath = unit.land.lnd_rpath;
184             rflagsp = &unit.land.lnd_rflags;
185         }
186         if (pq) {
187             strncpy(rpath, pq, RET_LEN - 1);
188             *rflagsp = rflags;
189             put_empobj(type, unit.gen.uid, &unit);
190         }
191         if (player->god)
192             pr("%3d ", unit.gen.own);
193         pr("%4d ", ni.cur);
194         pr("%-16.16s ", name);
195         prxy("%4d,%-4d ", unit.gen.x, unit.gen.y, player->cnum);
196         pr("%1.1s", &unit.gen.group);
197         pr(" %-11s", rpath);
198         rflags = *rflagsp;
199         if (rflags & RET_GROUP)
200             pr("Yes      ");
201         else
202             pr("         ");
203         if (rflags & RET_INJURED)
204             pr("I");
205         if (rflags & RET_TORPED)
206             pr("T");
207         if (rflags & RET_SONARED)
208             pr("S");
209         if (rflags & RET_HELPLESS)
210             pr("H");
211         if (rflags & RET_BOMBED)
212             pr("B");
213         if (rflags & RET_DCHRGED)
214             pr("D");
215         if (rflags & RET_BOARDED)
216             pr("U");
217         pr("\n");
218     }
219     what = type == EF_SHIP ? "ship" : "unit";
220     if (nunits == 0) {
221         if (player->argp[1])
222             pr("%s: No %s(s)\n", player->argp[1], what);
223         else
224             pr("%s: No %s(s)\n", "", what);
225         return RET_FAIL;
226     } else
227         pr("%d %s%s\n", nunits, what, splur(nunits));
228     return RET_OK;
229 }