2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure, Markus Armbruster
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.
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.
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/>.
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.
27 * spy.c: Spy on your neighbors
29 * Known contributors to this file:
31 * Steve McClure, 1998-2000
32 * Markus Armbruster, 2005-2013
51 static void spy_report(struct sctstr *sp);
52 static void prplanes(int, int);
53 static void prunits(int, int);
54 static char *player_relstr(natid);
66 unsigned char *bitmap;
68 struct nstr_sect nstr;
78 * first arg should be the range of sectors
80 if (!snxtsct(&nstr, player->argp[1]))
82 nsects = (nstr.range.width + 1) * nstr.range.height / 2;
83 btucost = (nsects / 40) + 1;
84 natp = getnatp(player->cnum);
85 if (natp->nat_btu < btucost) {
86 pr("You don't have the BTU's for spying on that scale!\n");
89 bitmap = calloc((WORLD_SZ() + 7) / 8, 1);
91 logerror("malloc failed in do_look\n");
92 pr("Memory error. Tell the deity.\n");
98 pr(" old sct rd rl def\n");
99 pr(" sect de own own eff eff eff eff civ mil shl gun pet food bars\n");
100 while (nxtsct(&nstr, &from)) {
101 if (!player->owner && !player->god)
103 military = from.sct_item[I_MILIT];
109 snxtitem_xy(&ni, EF_LAND, x, y);
110 while (nxtitem(&ni, &land)) {
111 if (lchr[(int)land.lnd_type].l_flags & L_RECON)
114 /* Print out the units/planes in this sector */
118 * check the neighboring sectors.
120 for (i = 1; i <= 6; i++) {
123 nx = x + diroff[i][0];
124 ny = y + diroff[i][1];
125 if (emp_getbit(nx, ny, bitmap))
126 continue; /* spied already */
127 getsect(nx, ny, &dsect);
128 if (player->owner || dsect.sct_type == SCT_WATER)
132 relat = relations_with(own, player->cnum);
134 && chance(dsect.sct_item[I_MILIT] / 200.0)) {
136 if (relat == NEUTRAL) {
138 pr("Spy deported from %s\n",
139 xyas(nx, ny, player->cnum));
141 wu(0, own, "%s spy deported from %s\n",
142 prnat(natp), xyas(nx, ny, own));
145 pr("BANG!! A spy was shot in %s\n",
146 xyas(nx, ny, player->cnum));
149 wu(0, own, "%s spy caught in %s\n",
150 prnat(natp), xyas(nx, ny, own));
151 nreport(player->cnum, N_SPY_SHOT, own, 1);
154 setcont(own, player->cnum, FOUND_SPY);
155 if (!nrecon) /* unless you have a recon unit */
156 continue; /* no report from caught spy */
160 emp_setbit(nx, ny, bitmap);
162 changed += map_set(player->cnum, dsect.sct_x, dsect.sct_y,
163 dchr[dsect.sct_type].d_mnem, 0);
165 setcont(player->cnum, own, FOUND_SPY);
167 /* subtract any military if necessary */
168 if (from.sct_item[I_MILIT] != military) {
169 from.sct_item[I_MILIT] = military;
174 writemap(player->cnum);
175 player->btused += btucost;
181 spy_report(struct sctstr *sp)
183 prxy("%4d,%-4d", sp->sct_x, sp->sct_y);
184 pr(" %c%c %3d %3d %3d %3d %3d %3d %4d %4d %4d %3d %4d %4d %4d\n",
185 dchr[sp->sct_type].d_mnem,
186 sp->sct_newtype == sp->sct_type ? ' ' : dchr[sp->sct_newtype].d_mnem,
189 roundintby((int)sp->sct_effic, 10),
190 roundintby((int)sp->sct_road, 10),
191 opt_RAILWAYS ? !!sct_rail_track(sp) : roundintby(sp->sct_rail, 10),
192 roundintby((int)sp->sct_defense, 10),
193 roundintby(sp->sct_item[I_CIVIL], 10),
194 roundintby(sp->sct_item[I_MILIT], 10),
195 roundintby(sp->sct_item[I_SHELL], 10),
196 roundintby(sp->sct_item[I_GUN], 10),
197 roundintby(sp->sct_item[I_PETROL], 10),
198 roundintby(sp->sct_item[I_FOOD], 10),
199 roundintby(sp->sct_item[I_BAR], 10));
200 prunits(sp->sct_x, sp->sct_y);
201 prplanes(sp->sct_x, sp->sct_y);
205 prunits(int x, int y)
211 snxtitem_xy(&ni, EF_LAND, x, y);
212 while (nxtitem(&ni, &land)) {
213 if (land.lnd_own == player->cnum || land.lnd_own == 0)
215 if (land.lnd_ship >= 0 || land.lnd_land >= 0)
217 /* Don't always see spies */
218 if (lchr[(int)land.lnd_type].l_flags & L_SPY) {
219 if (!(chance(LND_SPY_DETECT_CHANCE(land.lnd_effic))))
222 sprintf(report, "%s (%s) unit in %s: ",
223 player_relstr(land.lnd_own),
225 xyas(land.lnd_x, land.lnd_y, player->cnum));
226 intelligence_report(player->cnum, &land, 3, report);
231 prplanes(int x, int y)
236 snxtitem_xy(&ni, EF_PLANE, x, y);
237 while (nxtitem(&ni, &plane)) {
238 if (plane.pln_own == player->cnum || plane.pln_own == 0)
240 if (plane.pln_ship >= 0 || plane.pln_land >= 0)
242 if (plane.pln_flags & PLN_LAUNCHED)
244 pr("%s (%s) plane in %s: %s\n",
245 player_relstr(plane.pln_own),
246 cname(plane.pln_own),
247 xyas(plane.pln_x, plane.pln_y, player->cnum),
253 player_relstr(natid them)
255 int rel = relations_with(player->cnum, them);