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