]> git.pond.sub.org Git - empserver/blob - src/lib/subs/list.c
Fix tracking of planes flying a sortie
[empserver] / src / lib / subs / list.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  *  list.c: List ships, planes, units at a given x,y
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1986
32  */
33
34 #include <config.h>
35
36 #include <ctype.h>
37 #include "file.h"
38 #include "land.h"
39 #include "misc.h"
40 #include "nat.h"
41 #include "nsc.h"
42 #include "path.h"
43 #include "plane.h"
44 #include "player.h"
45 #include "prototypes.h"
46 #include "sect.h"
47 #include "ship.h"
48 #include "xy.h"
49
50 int
51 shipsatxy(coord x, coord y, int wantflags, int nowantflags)
52 {
53     int first;
54     int ships;
55     struct nstr_item ni;
56     struct mchrstr *mp;
57     struct shpstr ship;
58
59     first = 1;
60     ships = 0;
61     snxtitem_xy(&ni, EF_SHIP, x, y);
62     while (nxtitem(&ni, &ship)) {
63         if (player->owner)
64             continue;
65         if (ship.shp_effic < SHIP_MINEFF || ship.shp_own == 0)
66             continue;
67         mp = &mchr[(int)ship.shp_type];
68         if (wantflags) {
69             if ((mp->m_flags & wantflags) == 0)
70                 continue;
71         }
72         if (nowantflags) {
73             if (mp->m_flags & nowantflags)
74                 continue;
75         }
76         if (first) {
77             pr(" #          owner           eff       type\n");
78             first = 0;
79         }
80         pr("(#%3d) %10.10s  %12.12s  %s\n", ni.cur,
81            cname(ship.shp_own), effadv(ship.shp_effic), prship(&ship));
82         ships++;
83     }
84     return ships;
85 }
86
87 /* This one only shows owned or allied ships */
88
89 int
90 carriersatxy(coord x, coord y, natid own)
91 {
92     int first;
93     int ships;
94     struct nstr_item ni;
95     struct shpstr ship;
96
97     first = 1;
98     ships = 0;
99     snxtitem_xy(&ni, EF_SHIP, x, y);
100     while (nxtitem(&ni, &ship)) {
101         if (ship.shp_effic < SHIP_MINEFF || ship.shp_own == 0)
102             continue;
103         if (ship.shp_own != own
104             && getrel(getnatp(ship.shp_own), own) != ALLIED)
105             continue;
106         if ((carrier_planes(&ship, 0) & (P_L | P_K)) == 0)
107             continue;
108         if (first) {
109             pr(" #          owner           eff       type\n");
110             first = 0;
111         }
112         pr("(#%3d) %10.10s  %12.12s  %s\n", ni.cur,
113            cname(ship.shp_own), effadv(ship.shp_effic), prship(&ship));
114         ships++;
115     }
116     return ships;
117 }
118
119 int
120 unitsatxy(coord x, coord y, int wantflags, int nowantflags)
121 {
122     int first;
123     int units;
124     struct nstr_item ni;
125     struct lchrstr *lp;
126     struct lndstr land;
127
128     first = 1;
129     units = 0;
130     snxtitem_xy(&ni, EF_LAND, x, y);
131     while (nxtitem(&ni, &land)) {
132         if (land.lnd_effic < LAND_MINEFF || land.lnd_own == 0)
133             continue;
134         /* Can't bomb units on ships or other units */
135         if (land.lnd_ship >= 0 || land.lnd_land >= 0)
136             continue;
137         lp = &lchr[(int)land.lnd_type];
138
139         if (wantflags) {
140             if ((lp->l_flags & wantflags) == 0)
141                 continue;
142         }
143         if (nowantflags) {
144             if (lp->l_flags & nowantflags)
145                 continue;
146         }
147
148         if (lp->l_flags & L_SPY) {
149             if (!(chance(LND_SPY_DETECT_CHANCE(land.lnd_effic))))
150                 continue;
151         }
152
153         if (first) {
154             pr(" #          owner           eff       type\n");
155             first = 0;
156         }
157         pr("(#%3d) %10.10s  %12.12s  %s\n", ni.cur,
158            cname(land.lnd_own), effadv(land.lnd_effic), prland(&land));
159         units++;
160     }
161     return units;
162 }
163
164 int
165 planesatxy(coord x, coord y, int wantflags, int nowantflags)
166 {
167     int first;
168     int planes;
169     struct plnstr plane;
170     struct nstr_item ni;
171     struct plchrstr *plp;
172
173     planes = 0;
174     first = 1;
175     snxtitem_xy(&ni, EF_PLANE, x, y);
176     while (nxtitem(&ni, &plane)) {
177         if (plane.pln_effic < PLANE_MINEFF || plane.pln_own == 0)
178             continue;
179         if (plane.pln_flags & PLN_LAUNCHED)
180             continue;
181         plp = &plchr[(int)plane.pln_type];
182         if (first) {
183             pr(" #          owner           eff       type\n");
184             first = 0;
185         }
186         if (wantflags) {
187             if ((plp->pl_flags & wantflags) == 0)
188                 continue;
189         }
190         if (nowantflags) {
191             if (plp->pl_flags & nowantflags)
192                 continue;
193         }
194         pr("(#%3d) %10.10s  %12.12s  %s\n", ni.cur,
195            cname(plane.pln_own), effadv(plane.pln_effic), prplane(&plane));
196         planes++;
197     }
198     return planes;
199 }
200
201 int
202 asw_shipsatxy(coord x, coord y, int wantflags, int nowantflags,
203               struct plnstr *pp, struct shiplist **head)
204 {
205     int first;
206     int ships;
207     struct nstr_item ni;
208     struct mchrstr *mp;
209     struct shpstr ship;
210
211     first = 1;
212     ships = 0;
213     snxtitem_xy(&ni, EF_SHIP, x, y);
214     while (nxtitem(&ni, &ship)) {
215         if (player->owner)
216             continue;
217         if (ship.shp_effic < SHIP_MINEFF || ship.shp_own == 0)
218             continue;
219         mp = &mchr[(int)ship.shp_type];
220         if (wantflags) {
221             if ((mp->m_flags & wantflags) == 0)
222                 continue;
223         }
224         if (nowantflags) {
225             if (mp->m_flags & nowantflags)
226                 continue;
227         }
228         if (mp->m_flags & M_SUB) {
229             if (roll(100) > pln_hitchance(pp,
230                                           shp_hardtarget(&ship), EF_SHIP))
231                 continue;
232         }
233         add_shiplist(ship.shp_uid, head);
234         if (first) {
235             pr(" #          owner           eff       type\n");
236             first = 0;
237         }
238         pr("(#%3d) %10.10s  %12.12s  %s\n", ni.cur,
239            cname(ship.shp_own), effadv(ship.shp_effic), prship(&ship));
240         ships++;
241     }
242     return ships;
243 }
244
245 int
246 num_shipsatxy(coord x, coord y, int wantflags, int nowantflags)
247 {
248     int ships;
249     struct nstr_item ni;
250     struct mchrstr *mp;
251     struct shpstr ship;
252
253     ships = 0;
254     snxtitem_xy(&ni, EF_SHIP, x, y);
255     while (nxtitem(&ni, &ship)) {
256         if (ship.shp_effic < SHIP_MINEFF || ship.shp_own == 0)
257             continue;
258         mp = &mchr[(int)ship.shp_type];
259         if (wantflags) {
260             if ((mp->m_flags & wantflags) == 0)
261                 continue;
262         }
263         if (nowantflags) {
264             if (mp->m_flags & nowantflags)
265                 continue;
266         }
267         ships++;
268     }
269     return ships;
270 }
271
272 int
273 adj_units(coord x, coord y, natid own)
274 {
275     int i;
276     struct sctstr sect;
277
278     for (i = DIR_FIRST; i <= DIR_LAST; i++) {
279         getsect(x + diroff[i][0], y + diroff[i][1], &sect);
280         if (has_units(sect.sct_x, sect.sct_y, own, 0))
281             return 1;
282     }
283     return 0;
284 }
285
286 int
287 has_units(coord x, coord y, natid cn, struct lndstr *lp)
288 {
289     int n;
290     struct lndstr land;
291
292     for (n = 0; ef_read(EF_LAND, n, &land); n++) {
293         if (land.lnd_x != x || land.lnd_y != y)
294             continue;
295         if (lp) {
296             /* Check this unit.  If it is this one, we don't want
297                it included in the count. */
298             if (lp->lnd_uid == land.lnd_uid)
299                 continue;
300         }
301         if (land.lnd_own == cn)
302             return 1;
303     }
304
305     return 0;
306 }
307
308 /*
309  * is p a list of ships/planes/units?
310  */
311
312 int
313 islist(char *p)
314 {
315     for (; *p; p++) {
316         if (!isdigit(*p) && *p != '/')
317             return 0;
318     }
319     return 1;
320 }