2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2012, 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-2011
50 static void spy_report(struct sctstr *sp);
51 static void prplanes(int, int);
52 static void prunits(int, int);
53 static char *player_relstr(natid);
65 unsigned char *bitmap;
67 struct nstr_sect nstr;
77 * first arg should be the range of sectors
79 if (!snxtsct(&nstr, player->argp[1]))
81 nsects = (nstr.range.width + 1) * nstr.range.height / 2;
82 btucost = (nsects / 40) + 1;
83 natp = getnatp(player->cnum);
84 if (natp->nat_btu < btucost) {
85 pr("You don't have the BTU's for spying on that scale!\n");
88 bitmap = calloc((WORLD_SZ() + 7) / 8, 1);
90 logerror("malloc failed in do_look\n");
91 pr("Memory error. Tell the deity.\n");
97 pr(" old sct rd rl def\n");
98 pr(" sect de own own eff eff eff eff civ mil shl gun pet food bars\n");
99 while (nxtsct(&nstr, &from)) {
100 if (!player->owner && !player->god)
102 military = from.sct_item[I_MILIT];
108 snxtitem_xy(&ni, EF_LAND, x, y);
109 while (nxtitem(&ni, &land)) {
110 if (lchr[(int)land.lnd_type].l_flags & L_RECON)
113 /* Print out the units/planes in this sector */
117 * check the neighboring sectors.
119 for (i = 1; i <= 6; i++) {
122 nx = x + diroff[i][0];
123 ny = y + diroff[i][1];
124 if (emp_getbit(nx, ny, bitmap))
125 continue; /* spied already */
126 getsect(nx, ny, &dsect);
127 if (player->owner || dsect.sct_type == SCT_WATER)
131 relat = relations_with(own, player->cnum);
133 && chance(dsect.sct_item[I_MILIT] / 200.0)) {
135 if (relat == NEUTRAL) {
137 pr("Spy deported from %s\n",
138 xyas(nx, ny, player->cnum));
140 wu(0, own, "%s (#%d) spy deported from %s\n",
141 cname(player->cnum), player->cnum,
145 pr("BANG!! A spy was shot in %s\n",
146 xyas(nx, ny, player->cnum));
149 wu(0, own, "%s (#%d) spy caught in %s\n",
150 cname(player->cnum), player->cnum,
152 nreport(player->cnum, N_SPY_SHOT, own, 1);
155 setcont(own, player->cnum, FOUND_SPY);
156 if (!nrecon) /* unless you have a recon unit */
157 continue; /* no report from caught spy */
161 emp_setbit(nx, ny, bitmap);
163 changed += map_set(player->cnum, dsect.sct_x, dsect.sct_y,
164 dchr[dsect.sct_type].d_mnem, 0);
166 setcont(player->cnum, own, FOUND_SPY);
168 /* subtract any military if necessary */
169 if (from.sct_item[I_MILIT] != military) {
170 from.sct_item[I_MILIT] = military;
175 writemap(player->cnum);
176 player->btused += btucost;
182 spy_report(struct sctstr *sp)
184 prxy("%4d,%-4d", sp->sct_x, sp->sct_y);
185 pr(" %c%c %3d %3d %3d %3d %3d %3d %4d %4d %4d %3d %4d %4d %4d\n",
186 dchr[sp->sct_type].d_mnem,
187 sp->sct_newtype == sp->sct_type ? ' ' : dchr[sp->sct_newtype].d_mnem,
190 roundintby((int)sp->sct_effic, 10),
191 roundintby((int)sp->sct_road, 10),
192 opt_RAILWAYS ? !!sct_rail_track(sp) : roundintby(sp->sct_rail, 10),
193 roundintby((int)sp->sct_defense, 10),
194 roundintby(sp->sct_item[I_CIVIL], 10),
195 roundintby(sp->sct_item[I_MILIT], 10),
196 roundintby(sp->sct_item[I_SHELL], 10),
197 roundintby(sp->sct_item[I_GUN], 10),
198 roundintby(sp->sct_item[I_PETROL], 10),
199 roundintby(sp->sct_item[I_FOOD], 10),
200 roundintby(sp->sct_item[I_BAR], 10));
201 prunits(sp->sct_x, sp->sct_y);
202 prplanes(sp->sct_x, sp->sct_y);
206 prunits(int x, int y)
212 snxtitem_xy(&ni, EF_LAND, x, y);
213 while (nxtitem(&ni, &land)) {
214 if (land.lnd_own == player->cnum || land.lnd_own == 0)
216 if (land.lnd_ship >= 0 || land.lnd_land >= 0)
218 /* Don't always see spies */
219 if (lchr[(int)land.lnd_type].l_flags & L_SPY) {
220 if (!(chance(LND_SPY_DETECT_CHANCE(land.lnd_effic))))
223 sprintf(report, "%s (%s) unit in %s: ",
224 player_relstr(land.lnd_own),
226 xyas(land.lnd_x, land.lnd_y, player->cnum));
227 intelligence_report(player->cnum, &land, 3, report);
232 prplanes(int x, int y)
237 snxtitem_xy(&ni, EF_PLANE, x, y);
238 while (nxtitem(&ni, &plane)) {
239 if (plane.pln_own == player->cnum || plane.pln_own == 0)
241 if (plane.pln_ship >= 0 || plane.pln_land >= 0)
243 if (plane.pln_flags & PLN_LAUNCHED)
245 pr("%s (%s) plane in %s: %s\n",
246 player_relstr(plane.pln_own),
247 cname(plane.pln_own),
248 xyas(plane.pln_x, plane.pln_y, player->cnum),
254 player_relstr(natid them)
256 int rel = relations_with(player->cnum, them);