]> git.pond.sub.org Git - empserver/blob - src/lib/commands/retr.c
4aed39140a574e52a44a13eb4795e87ca6bc3844
[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  *     Markus Armbruster, 2008
34  */
35
36 #include <config.h>
37
38 #include <ctype.h>
39 #include "commands.h"
40 #include "empobj.h"
41 #include "land.h"
42 #include "path.h"
43 #include "retreat.h"
44 #include "ship.h"
45
46 /*
47  * Retreat flag characters
48  * 'X' means flag is not available
49  * Must agree with RET_ defines.
50  */
51 static char shp_rflagsc[] = "Xitshbdu";
52 static char lnd_rflagsc[] = "XiXXhbXX";
53
54 static int retreat(short);
55
56 int
57 retr(void)
58 {
59     return retreat(EF_SHIP);
60 }
61
62 int
63 lretr(void)
64 {
65     return retreat(EF_LAND);
66 }
67
68 static int
69 retreat(short type)
70 {
71     char *pq, *fl;
72     int nunits;
73     struct nstr_item ni;
74     union empobj_storage unit;
75     int rflags, ch, j;
76     unsigned i;
77     char *rflagsc, *p, *name, *rpath, *what;
78     int *rflagsp;
79     char buf1[1024];
80     char buf2[1024];
81
82     if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
83         type = EF_SHIP;
84     rflagsc = type == EF_SHIP ? shp_rflagsc : lnd_rflagsc;
85
86     if (!snxtitem(&ni, type, player->argp[1], NULL))
87         return RET_SYN;
88     nunits = 0;
89     if (player->argp[2] != NULL)
90         pq = getstarg(player->argp[2], "Retreat path? ", buf1);
91     else
92         pq = NULL;
93
94     rflags = 0;
95     if (pq != NULL) {
96     again:
97         fl = getstarg(player->argp[3],
98                       "Retreat conditions ('?' to list available ones)? ",
99                       buf2);
100         if (!fl)
101             return RET_SYN;
102
103         for (i = 0; fl[i]; i++) {
104             ch = tolower(fl[i]);
105             if (ch == 'C') {
106                 *pq = 0;
107                 return 0;
108             }
109             if (ch == '?') {
110                 for (j = 1; rflagsc[j]; j++) {
111                     if (rflagsc[j] != 'X')
112                         pr("%c\tretreat when %s\n",
113                            rflagsc[j],
114                            symbol_by_value(1 << j, retreat_flags));
115                 }
116                 pr("c\tcancel retreat order\n");
117                 goto again;
118             }
119             p = strchr(rflagsc, ch);
120             if (!p) {
121                 pr("Bad retreat condition '%c'\n", fl[i]);
122                 return RET_SYN;
123             }
124             rflags |= 1 << (p - rflagsc);
125         }
126         if (*pq && !rflags) {
127             pr("Must give retreat conditions!\n");
128             return RET_FAIL;
129         }
130         if (ni.sel == NS_GROUP && ni.group)
131             rflags |= RET_GROUP;
132         if (!*pq)
133             rflags = 0;
134     }
135
136     while (nxtitem(&ni, &unit)) {
137         if (!player->owner || unit.gen.own == 0)
138             continue;
139         if (type == EF_SHIP) {
140             if (nunits++ == 0) {
141                 if (player->god)
142                     pr("own ");
143                 pr("shp#     ship type       x,y   fl path       as flt?  flags\n");
144             }
145             name = mchr[unit.ship.shp_type].m_name;
146             rpath = unit.ship.shp_rpath;
147             rflagsp = &unit.ship.shp_rflags;
148         } else {
149             if (nunits++ == 0) {
150                 if (player->god)
151                     pr("own ");
152                 pr("lnd#     unit type       x,y   ar path       as army? flags\n");
153             }
154             name = lchr[unit.land.lnd_type].l_name;
155             rpath = unit.land.lnd_rpath;
156             rflagsp = &unit.land.lnd_rflags;
157         }
158         if (pq) {
159             strncpy(rpath, pq, RET_LEN - 1);
160             *rflagsp = rflags;
161             put_empobj(type, unit.gen.uid, &unit);
162         }
163         if (player->god)
164             pr("%3d ", unit.gen.own);
165         pr("%4d ", ni.cur);
166         pr("%-16.16s ", name);
167         prxy("%4d,%-4d ", unit.gen.x, unit.gen.y, player->cnum);
168         pr("%1.1s", &unit.gen.group);
169         pr(" %-11s", rpath);
170         rflags = *rflagsp;
171         if (rflags & RET_GROUP)
172             pr("Yes      ");
173         else
174             pr("         ");
175         for (j = 1; rflagsc[j]; j++) {
176             if ((1 << j) & rflags) {
177                 if (CANT_HAPPEN(rflagsc[j] == 'X'))
178                     continue;
179                 pr("%c", rflagsc[j]);
180             }
181         }
182         pr("\n");
183     }
184     what = type == EF_SHIP ? "ship" : "unit";
185     if (nunits == 0) {
186         if (player->argp[1])
187             pr("%s: No %s(s)\n", player->argp[1], what);
188         else
189             pr("%s: No %s(s)\n", "", what);
190         return RET_FAIL;
191     } else
192         pr("%d %s%s\n", nunits, what, splur(nunits));
193     return RET_OK;
194 }