00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include "commands.h"
00037 #include "empobj.h"
00038 #include "map.h"
00039 #include "optlist.h"
00040 #include "path.h"
00041
00042 static void look_ship(struct shpstr *lookship);
00043 static void look_land(struct lndstr *lookland);
00044
00045 int
00046 look(void)
00047 {
00048 return do_look(EF_SHIP);
00049 }
00050
00051 int
00052 llook(void)
00053 {
00054 return do_look(EF_LAND);
00055 }
00056
00057 int
00058 do_look(short type)
00059 {
00060 int i;
00061 struct nstr_item ni;
00062 union empobj_storage unit;
00063 struct sctstr sect;
00064 int x, y;
00065 int civ;
00066 int mil;
00067 unsigned char *bitmap;
00068 int changed = 0;
00069
00070 if (!snxtitem(&ni, type, player->argp[1]))
00071 return RET_SYN;
00072 if ((bitmap = malloc((WORLD_X * WORLD_Y) / 8)) == 0) {
00073 logerror("malloc failed in do_look\n");
00074 pr("Memory error. Tell the deity.\n");
00075 return RET_FAIL;
00076 }
00077 memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
00078 while (nxtitem(&ni, &unit)) {
00079 if (!player->owner)
00080 continue;
00081 if (type == EF_LAND) {
00082 if (unit.land.lnd_ship >= 0)
00083 continue;
00084 if (unit.land.lnd_land >= 0)
00085 continue;
00086
00087
00088 if ((unit.land.lnd_item[I_MILIT] <= 0) &&
00089 !(lchr[(int)unit.land.lnd_type].l_flags & L_SPY))
00090 continue;
00091 look_land(&unit.land);
00092 } else
00093 look_ship(&unit.ship);
00094 for (i = 0; i <= 6; i++) {
00095 x = diroff[i][0] + unit.gen.x;
00096 y = diroff[i][1] + unit.gen.y;
00097 if (emp_getbit(x, y, bitmap))
00098 continue;
00099 emp_setbit(x, y, bitmap);
00100 getsect(x, y, §);
00101 if (sect.sct_type == SCT_WATER)
00102 continue;
00103 if (player->owner)
00104 pr("Your ");
00105 else
00106 pr("%s (#%d) ", cname(sect.sct_own), sect.sct_own);
00107 pr("%s", dchr[sect.sct_type].d_name);
00108 changed += map_set(player->cnum, x, y,
00109 dchr[sect.sct_type].d_mnem, 0);
00110 pr(" %d%% efficient ", player->owner ? sect.sct_effic :
00111 roundintby((int)sect.sct_effic, 10));
00112 civ = sect.sct_item[I_CIVIL];
00113 mil = sect.sct_item[I_MILIT];
00114 if (civ)
00115 pr("with %s%d civ ",
00116 player->owner ? "" : "approx ",
00117 player->owner ? civ : roundintby(civ, 10));
00118 if (mil)
00119 pr("with %s%d mil ",
00120 player->owner ? "" : "approx ",
00121 player->owner ? mil : roundintby(mil, 10));
00122 pr("@ %s\n", xyas(x, y, player->cnum));
00123 if (opt_HIDDEN) {
00124 setcont(player->cnum, sect.sct_own, FOUND_LOOK);
00125 }
00126 }
00127 }
00128 if (changed)
00129 writemap(player->cnum);
00130 free(bitmap);
00131 return RET_OK;
00132 }
00133
00134 static void
00135 look_ship(struct shpstr *lookship)
00136 {
00137 struct shpstr *sp;
00138 struct mchrstr *smcp;
00139 struct mchrstr *tmcp;
00140 struct sctstr sect;
00141 int range;
00142 int vrange;
00143 int i;
00144 int dist;
00145
00146 range = (int)techfact(lookship->shp_tech,
00147 mchr[(int)lookship->shp_type].m_vrnge);
00148 range = range * (lookship->shp_effic / 100.0);
00149 smcp = &mchr[(int)lookship->shp_type];
00150 if (smcp->m_flags & M_SUB)
00151 range = MIN(range, 1);
00152 for (i = 0; NULL != (sp = getshipp(i)); i++) {
00153 if (sp->shp_own == player->cnum || sp->shp_own == 0)
00154 continue;
00155 dist = mapdist(sp->shp_x, sp->shp_y,
00156 lookship->shp_x, lookship->shp_y);
00157 if (dist > ship_max_interdiction_range)
00158 continue;
00159 tmcp = &mchr[(int)sp->shp_type];
00160 if (smcp->m_flags & M_SUB)
00161 vrange = (int)(sp->shp_visib * range / 30.0);
00162 else
00163 vrange = (int)(sp->shp_visib * range / 20.0);
00164 getsect(sp->shp_x, sp->shp_y, §);
00165 if (sect.sct_type != SCT_WATER)
00166 vrange = MAX(1, vrange);
00167 if (dist > vrange)
00168 continue;
00169 if (smcp->m_flags & M_SUB) {
00170 if (tmcp->m_flags & M_SONAR && dist < 2) {
00171 if (sp->shp_own != 0)
00172 wu(0, sp->shp_own,
00173 "%s detected surfacing noises in %s.\n",
00174 prship(sp),
00175 xyas(lookship->shp_x, lookship->shp_y,
00176 sp->shp_own));
00177 }
00178 if (dist == 0 && (tmcp->m_flags & M_SUB) == 0)
00179 if (sp->shp_own != 0)
00180 wu(0, sp->shp_own,
00181 "Periscope spotted in %s by %s\n",
00182 xyas(lookship->shp_x, lookship->shp_y,
00183 sp->shp_own), prship(sp));
00184 }
00185
00186 if (tmcp->m_flags & M_SUB && sect.sct_type == SCT_WATER)
00187 continue;
00188 pr("%s (#%d) %s @ %s\n",
00189 cname(sp->shp_own), sp->shp_own, prship(sp),
00190 xyas(sp->shp_x, sp->shp_y, player->cnum));
00191 if (opt_HIDDEN)
00192 setcont(player->cnum, sp->shp_own, FOUND_LOOK);
00193 }
00194 }
00195
00196 static void
00197 look_land(struct lndstr *lookland)
00198 {
00199 struct plnstr *pp;
00200 struct lndstr *lp;
00201 double drange;
00202 int range;
00203 int vrange;
00204 int i;
00205 int dist;
00206
00207 drange = techfact(lookland->lnd_tech, lookland->lnd_spy);
00208 drange *= lookland->lnd_effic / 100.0;
00209 range = ldround(drange, 1);
00210
00211 if (range == 0)
00212 return;
00213
00214 for (i = 0; NULL != (lp = getlandp(i)); i++) {
00215 if (lp->lnd_own == player->cnum || lp->lnd_own == 0)
00216 continue;
00217 if (lp->lnd_ship >= 0)
00218 continue;
00219
00220 if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
00221
00222
00223 if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
00224 continue;
00225 if (!(chance(LND_SPY_DETECT_CHANCE(lp->lnd_effic))))
00226 continue;
00227 }
00228 vrange = ldround((lp->lnd_vis * range) / 20.0, 1);
00229 dist = mapdist(lp->lnd_x, lp->lnd_y,
00230 lookland->lnd_x, lookland->lnd_y);
00231 if (dist > vrange)
00232 continue;
00233
00234 pr("%s (#%d) %s (approx %d mil) @ %s\n",
00235 cname(lp->lnd_own), lp->lnd_own,
00236 prland(lp), roundintby(lp->lnd_item[I_MILIT], 20),
00237 xyas(lp->lnd_x, lp->lnd_y, player->cnum));
00238 if (opt_HIDDEN)
00239 setcont(player->cnum, lp->lnd_own, FOUND_LOOK);
00240 }
00241 for (i = 0; NULL != (pp = getplanep(i)); i++) {
00242 if (pp->pln_own == player->cnum || pp->pln_own == 0)
00243 continue;
00244 if (pp->pln_ship >= 0)
00245 continue;
00246 if (pp->pln_flags & PLN_LAUNCHED)
00247 continue;
00248 vrange = ldround((10 * range) / 20.0, 1);
00249 dist = mapdist(pp->pln_x, pp->pln_y,
00250 lookland->lnd_x, lookland->lnd_y);
00251 if (dist > vrange)
00252 continue;
00253
00254 pr("%s (#%d) %s @ %s\n",
00255 cname(pp->pln_own), pp->pln_own,
00256 prplane(pp), xyas(pp->pln_x, pp->pln_y, player->cnum));
00257 if (opt_HIDDEN)
00258 setcont(player->cnum, pp->pln_own, FOUND_LOOK);
00259 }
00260 }