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