]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/look.c
Fix trailing whitespace
[empserver] / src / lib / commands / look.c
index 57447ee284d34d0f606c7525d14e12289f3363d4..45e316fc8900d71fa22ad5f72aedf582b3cbb7b5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                           Ken Stevens, Steve McClure
  *
  *  This program is free software; you can redistribute it and/or modify
  *
  *  ---
  *
- *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- *  related information and legal notices. It is expected that any future
- *  projects/authors will amend these files as needed.
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
  *
  *  ---
  *
  *  look.c: Lookout from a ship or land unit
- * 
+ *
  *  Known contributors to this file:
- *     
+ *     Ron Koenderink, 2006-2007
  */
 
-#include "misc.h"
-#include "player.h"
-#include "var.h"
-#include "xy.h"
-#include "sect.h"
-#include "ship.h"
-#include "land.h"
-#include "plane.h"
-#include "nsc.h"
-#include "nat.h"
-#include "path.h"
-#include "file.h"
-#include <fcntl.h>
+#include <config.h>
+
 #include "commands.h"
+#include "empobj.h"
+#include "map.h"
 #include "optlist.h"
+#include "path.h"
 
-static void look_ship(register struct shpstr *lookship);
+static void look_ship(struct shpstr *lookship);
+static void look_land(struct lndstr *lookland);
 
 int
 look(void)
 {
-       register int i;
-       struct  nstr_item ni;
-       struct  shpstr myship;
-       struct  sctstr sect;
-       int     x, y;
-       int     civ;
-       int     mil;
-       u_char  *bitmap;
-       int     changed = 0;
+    return do_look(EF_SHIP);
+}
 
-       if (!snxtitem(&ni, EF_SHIP, player->argp[1]))
-               return RET_SYN;
-       if ((bitmap = (u_char *)malloc((WORLD_X * WORLD_Y) / 8)) == 0) {
-           logerror("malloc failed in look\n");
-           pr("Memory error.  Tell the deity.\n");
-           return RET_FAIL;
-       }
-       bzero((s_char *)bitmap, (WORLD_X * WORLD_Y) / 8);
-       while (nxtitem(&ni, (s_char *)&myship)) {
-               if (!player->owner)
-                       continue;
-               look_ship(&myship);
-               for (i = 0; i <= 6; i++) {
-                       x = diroff[i][0] + myship.shp_x;
-                       y = diroff[i][1] + myship.shp_y;
-                       if (emp_getbit(x, y, bitmap))
-                               continue;
-                       emp_setbit(x, y, bitmap);
-                       getsect(x, y, &sect);
-                       if (sect.sct_type == SCT_WATER)
-                               continue;
-                       if (player->owner)
-                               pr("Your ");
-                       else
-                               pr("%s (#%d) ", cname(sect.sct_own),
-                                       sect.sct_own);
-                       pr(dchr[sect.sct_type].d_name);
-                       changed += map_set(player->cnum, x, y,
-                               dchr[sect.sct_type].d_mnem, 0);
-                       pr(" %d%% efficient ", player->owner ? sect.sct_effic :
-                               roundintby((int)sect.sct_effic, 10));
-                       civ = getvar(V_CIVIL, (s_char *)&sect, EF_SECTOR);
-                       mil = getvar(V_MILIT, (s_char *)&sect, EF_SECTOR);
-                       if (civ)
-                               pr("with %s%d civ ", player->owner ? "" : "approx ",
-                                       player->owner ? civ : roundintby(civ, 10));
-                       if (mil)
-                               pr("with %s%d mil ", player->owner ? "" : "approx ",
-                                       player->owner ? mil : roundintby(mil, 10));
-                       pr("@ %s\n", xyas(x, y, player->cnum));
-                       if (opt_HIDDEN) {
-                           setcont(player->cnum, sect.sct_own, FOUND_LOOK);
-                       }
-               }
-       }
-       if (changed)
-               writemap(player->cnum);
-       free((s_char *)bitmap);
-       return RET_OK;
+int
+llook(void)
+{
+    return do_look(EF_LAND);
 }
 
-static void
-look_ship(register struct shpstr *lookship)
+int
+do_look(short type)
 {
-       register struct shpstr *sp;
-       register struct mchrstr *smcp;
-       register struct mchrstr *tmcp;
-       extern  int     ship_max_interdiction_range;
-       struct  sctstr sect;
-       int     range;
-       int     vrange;
-       int     i;
-       int     dist;
+    int i;
+    struct nstr_item ni;
+    union empobj_storage unit;
+    struct sctstr sect;
+    int x, y;
+    int civ;
+    int mil;
+    unsigned char *bitmap;
+    int changed = 0;
 
-       range = (int) techfact(lookship->shp_tech,
-               (double) mchr[(int)lookship->shp_type].m_vrnge);
-       range = range * (lookship->shp_effic / 100.0);
-       smcp = &mchr[(int)lookship->shp_type];
-       if (smcp->m_flags & M_SUB)
-               range = min(range, 1);
-       for (i=0; NULL != (sp = getshipp(i)); i++) {
-               if (sp->shp_own == player->cnum || sp->shp_own == 0)
-                       continue;
-               dist = mapdist(sp->shp_x, sp->shp_y,
-                       lookship->shp_x, lookship->shp_y);
-               if (dist > ship_max_interdiction_range)
-                       continue;
-               tmcp = &mchr[(int)sp->shp_type];
-               if (smcp->m_flags & M_SUB)
-                       vrange = (int)(sp->shp_visib * range/30.0);
-               else
-                       vrange = (int)(sp->shp_visib * range/20.0);
-               getsect(sp->shp_x, sp->shp_y, &sect);
-               if (sect.sct_type != SCT_WATER)
-                       vrange = max(1, vrange);
-               if (dist > vrange)
-                       continue;
-               if (smcp->m_flags & M_SUB) {
-                       if (tmcp->m_flags & M_SONAR && dist < 2) {
-                               if(sp->shp_own != 0)
-                               wu(0, sp->shp_own,
-                                  "%s detected surfacing noises in %s.\n",
-                                  prship(sp),
-                                  xyas(lookship->shp_x, lookship->shp_y,
-                                       sp->shp_own));
-                       }
-                       if (dist == 0 && (tmcp->m_flags & M_SUB) == 0)
-                               if(sp->shp_own != 0)
-                               wu(0, sp->shp_own,
-                               "Periscope spotted in %s by %s\n",
-                                  xyas(lookship->shp_x, lookship->shp_y,
-                                       sp->shp_own),
-                                  prship(sp));
-               }
-               /* subs at sea only seen by sonar */
-               if (tmcp->m_flags & M_SUB && sect.sct_type == SCT_WATER)
-                       continue;
-               pr("%s (#%d) %s @ %s\n",
-                  cname(sp->shp_own), sp->shp_own, prship(sp),
-                  xyas(sp->shp_x, sp->shp_y, player->cnum));
+    if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
+       type = EF_SHIP;
+
+    if (!snxtitem(&ni, type, player->argp[1], NULL))
+       return RET_SYN;
+    bitmap = calloc(WORLD_SZ() / 8, 1);
+    if (!bitmap) {
+       logerror("malloc failed in do_look\n");
+       pr("Memory error.  Tell the deity.\n");
+       return RET_FAIL;
+    }
+    while (nxtitem(&ni, &unit)) {
+       if (!player->owner)
+           continue;
+       if (type == EF_LAND) {
+           if (unit.land.lnd_ship >= 0)
+               continue;
+           if (unit.land.lnd_land >= 0)
+               continue;
+           /* Spies don't need military to do a "llook".  Other
+              units do */
+           if ((unit.land.lnd_item[I_MILIT] <= 0) &&
+               !(lchr[(int)unit.land.lnd_type].l_flags & L_SPY))
+               continue;
+           look_land(&unit.land);
+       } else
+           look_ship(&unit.ship);
+       for (i = 0; i <= 6; i++) {
+           x = diroff[i][0] + unit.gen.x;
+           y = diroff[i][1] + unit.gen.y;
+           if (emp_getbit(x, y, bitmap))
+               continue;
+           emp_setbit(x, y, bitmap);
+           getsect(x, y, &sect);
+           if (sect.sct_type == SCT_WATER)
+               continue;
+           if (player->owner)
+               pr("Your ");
+           else
+               pr("%s (#%d) ", cname(sect.sct_own), sect.sct_own);
+           pr("%s", dchr[sect.sct_type].d_name);
+           changed += map_set(player->cnum, x, y,
+                              dchr[sect.sct_type].d_mnem, 0);
+           pr(" %d%% efficient ", player->owner ? sect.sct_effic :
+              roundintby((int)sect.sct_effic, 10));
+           civ = sect.sct_item[I_CIVIL];
+           mil = sect.sct_item[I_MILIT];
+           if (civ)
+               pr("with %s%d civ ",
+                  player->owner ? "" : "approx ",
+                  player->owner ? civ : roundintby(civ, 10));
+           if (mil)
+               pr("with %s%d mil ",
+                  player->owner ? "" : "approx ",
+                  player->owner ? mil : roundintby(mil, 10));
+           pr("@ %s\n", xyas(x, y, player->cnum));
+           if (opt_HIDDEN) {
+               setcont(player->cnum, sect.sct_own, FOUND_LOOK);
+           }
        }
+    }
+    if (changed)
+       writemap(player->cnum);
+    free(bitmap);
+    return RET_OK;
 }
 
-static void look_land(register struct lndstr *lookland);
-
-int
-llook(void)
+static void
+look_ship(struct shpstr *lookship)
 {
-       register int i;
-       struct  nstr_item ni;
-       struct  lndstr myland;
-       struct  sctstr sect;
-       int     x, y;
-       int     civ;
-       int     mil;
-       u_char  *bitmap;
-       int     changed = 0;
+    struct shpstr *sp;
+    struct mchrstr *smcp;
+    struct mchrstr *tmcp;
+    struct sctstr sect;
+    int range;
+    int vrange;
+    int i;
+    int dist;
 
-       if (!snxtitem(&ni, EF_LAND, player->argp[1]))
-               return RET_SYN;
-       if ((bitmap = (u_char *)malloc((WORLD_X * WORLD_Y) / 8)) == 0) {
-           logerror("malloc failed in llook\n");
-           pr("Memory error.  Tell the deity.\n");
-           return RET_FAIL;
-       }
-       bzero((s_char *)bitmap, (WORLD_X * WORLD_Y) / 8);
-       while (nxtitem(&ni, (s_char *)&myland)) {
-               if (!player->owner)
-                       continue;
-               if (myland.lnd_ship >= 0)
-                       continue;
-               if (myland.lnd_land >= 0)
-                   continue;
-               /* Spies don't need military to do a "llook".  Other
-                  units do */
-               if ((lnd_getmil(&myland) <= 0) && 
-                   !(lchr[(int)myland.lnd_type].l_flags & L_SPY))
-                   continue;
-               look_land(&myland);
-               for (i = 0; i <= 6; i++) {
-                       x = diroff[i][0] + myland.lnd_x;
-                       y = diroff[i][1] + myland.lnd_y;
-                       if (emp_getbit(x, y, bitmap))
-                               continue;
-                       emp_setbit(x, y, bitmap);
-                       getsect(x, y, &sect);
-                       if (sect.sct_type == SCT_WATER)
-                               continue;
-                       if (player->owner)
-                               pr("Your ");
-                       else
-                               pr("%s (#%d) ", cname(sect.sct_own),
-                                       sect.sct_own);
-                       pr(dchr[sect.sct_type].d_name);
-                       changed += map_set(player->cnum, x, y,
-                               dchr[sect.sct_type].d_mnem, 0);
-                       pr(" %d%% efficient ", player->owner ? sect.sct_effic :
-                               roundintby((int)sect.sct_effic, 10));
-                       civ = getvar(V_CIVIL, (s_char *)&sect, EF_SECTOR);
-                       mil = getvar(V_MILIT, (s_char *)&sect, EF_SECTOR);
-                       if (civ)
-                               pr("with %s%d civ ", player->owner ? "" :
-                                       "approx ",
-                                       player->owner ? civ : roundintby(civ, 10));
-                       if (mil)
-                               pr("with %s%d mil ", player->owner ? "" :
-                                       "approx ",
-                                       player->owner ? mil : roundintby(mil, 10));
-                       pr("@ %s\n", xyas(x, y, player->cnum));
-                       if (opt_HIDDEN) {
-                           setcont(player->cnum, sect.sct_own, FOUND_LOOK);
-                       }
-               }
+    range = (int)techfact(lookship->shp_tech,
+                         mchr[(int)lookship->shp_type].m_vrnge);
+    range = range * (lookship->shp_effic / 100.0);
+    smcp = &mchr[(int)lookship->shp_type];
+    if (smcp->m_flags & M_SUB)
+       range = MIN(range, 1);
+    for (i = 0; NULL != (sp = getshipp(i)); i++) {
+       if (sp->shp_own == player->cnum || sp->shp_own == 0)
+           continue;
+       dist = mapdist(sp->shp_x, sp->shp_y,
+                      lookship->shp_x, lookship->shp_y);
+       if (dist > ship_max_interdiction_range)
+           continue;
+       tmcp = &mchr[(int)sp->shp_type];
+       if (smcp->m_flags & M_SUB)
+           vrange = (int)(shp_visib(sp) * range / 30.0);
+       else
+           vrange = (int)(shp_visib(sp) * range / 20.0);
+       getsect(sp->shp_x, sp->shp_y, &sect);
+       if (sect.sct_type != SCT_WATER)
+           vrange = MAX(1, vrange);
+       if (dist > vrange)
+           continue;
+       if (smcp->m_flags & M_SUB) {
+           if (tmcp->m_flags & M_SONAR && dist < 2) {
+               if (sp->shp_own != 0)
+                   wu(0, sp->shp_own,
+                      "%s detected surfacing noises in %s.\n",
+                      prship(sp),
+                      xyas(lookship->shp_x, lookship->shp_y,
+                           sp->shp_own));
+           }
+           if (dist == 0 && (tmcp->m_flags & M_SUB) == 0)
+               if (sp->shp_own != 0)
+                   wu(0, sp->shp_own,
+                      "Periscope spotted in %s by %s\n",
+                      xyas(lookship->shp_x, lookship->shp_y,
+                           sp->shp_own), prship(sp));
        }
-       if (changed)
-               writemap(player->cnum);
-       free((s_char *)bitmap);
-       return RET_OK;
+       /* subs at sea only seen by sonar */
+       if (tmcp->m_flags & M_SUB && sect.sct_type == SCT_WATER)
+           continue;
+       pr("%s (#%d) %s @ %s\n",
+          cname(sp->shp_own), sp->shp_own, prship(sp),
+          xyas(sp->shp_x, sp->shp_y, player->cnum));
+       if (opt_HIDDEN)
+           setcont(player->cnum, sp->shp_own, FOUND_LOOK);
+    }
 }
 
 static void
-look_land(register struct lndstr *lookland)
+look_land(struct lndstr *lookland)
 {
-       register struct plnstr *pp;
-       register struct lndstr *lp;
-       double  drange;
-       int     range;
-       int     vrange;
-       int     i;
-       int     dist;
-       double  techfact(int, double);
-       double odds;
-
-       drange = techfact(lookland->lnd_tech,
-               (double) lookland->lnd_spy);
-       drange = (drange * ((double)lookland->lnd_effic / 100.0));
-       range = ldround(drange,1);
+    struct plnstr *pp;
+    struct lndstr *lp;
+    double drange;
+    int range;
+    int vrange;
+    int i;
+    int dist;
 
-       if (range == 0)
-               return;
+    drange = techfact(lookland->lnd_tech, lchr[lookland->lnd_type].l_spy);
+    drange *= lookland->lnd_effic / 100.0;
+    range = ldround(drange, 1);
 
-       for (i=0; NULL != (lp = getlandp(i)); i++) {
-               if (lp->lnd_own == player->cnum || lp->lnd_own == 0)
-                       continue;
-               if (lp->lnd_ship >= 0)
-                   continue;
-               /* Don't always see spies */
-               if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
-                   /* If it's on a ship or unit, assume it's hidden
-                      enough not to be seen */
-                   if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
-                       continue;
-                   odds = (double)(100 - lp->lnd_effic) + 0.10;
-                   if (!(chance(odds)))
-                       continue;
-               }
-               vrange = ldround((double)((lp->lnd_vis
-                               * range)/20.0),1);
-               dist = mapdist(lp->lnd_x, lp->lnd_y,
-                       lookland->lnd_x, lookland->lnd_y);
-               if (dist > vrange)
-                       continue;
+    if (range == 0)
+       return;
 
-               pr("%s (#%d) %s (approx %d mil) @ %s\n",
-                  cname(lp->lnd_own), lp->lnd_own,
-                  prland(lp), ldround((double)total_mil(lp), 20),
-                  xyas(lp->lnd_x, lp->lnd_y, player->cnum));
+    for (i = 0; NULL != (lp = getlandp(i)); i++) {
+       if (lp->lnd_own == player->cnum || lp->lnd_own == 0)
+           continue;
+       if (lp->lnd_ship >= 0)
+           continue;
+       /* Don't always see spies */
+       if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
+           /* If it's on a ship or unit, assume it's hidden
+              enough not to be seen */
+           if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
+               continue;
+           if (!(chance(LND_SPY_DETECT_CHANCE(lp->lnd_effic))))
+               continue;
        }
-       for (i=0; NULL != (pp = getplanep(i)); i++) {
-               if (pp->pln_own == player->cnum || pp->pln_own == 0)
-                       continue;
-               if (pp->pln_ship >= 0)
-                       continue;
-               if (pp->pln_flags & PLN_LAUNCHED)
-                   continue;
-               vrange = ldround((double)((10* range)/20.0),1);
-               dist = mapdist(pp->pln_x, pp->pln_y,
-                       lookland->lnd_x, lookland->lnd_y);
-               if (dist > vrange)
-                       continue;
+       vrange = ldround((lnd_vis(lp) * range) / 20.0, 1);
+       dist = mapdist(lp->lnd_x, lp->lnd_y,
+                      lookland->lnd_x, lookland->lnd_y);
+       if (dist > vrange)
+           continue;
 
-               pr("%s (#%d) %s @ %s\n",
-                       cname(pp->pln_own), pp->pln_own,
-                       prplane(pp),
-                       xyas(pp->pln_x, pp->pln_y, player->cnum));
-       }
+       pr("%s (#%d) %s (approx %d mil) @ %s\n",
+          cname(lp->lnd_own), lp->lnd_own,
+          prland(lp), roundintby(lp->lnd_item[I_MILIT], 20),
+          xyas(lp->lnd_x, lp->lnd_y, player->cnum));
+       if (opt_HIDDEN)
+           setcont(player->cnum, lp->lnd_own, FOUND_LOOK);
+    }
+    for (i = 0; NULL != (pp = getplanep(i)); i++) {
+       if (pp->pln_own == player->cnum || pp->pln_own == 0)
+           continue;
+       if (pp->pln_ship >= 0)
+           continue;
+       if (pp->pln_flags & PLN_LAUNCHED)
+           continue;
+       vrange = ldround((10 * range) / 20.0, 1);
+       dist = mapdist(pp->pln_x, pp->pln_y,
+                      lookland->lnd_x, lookland->lnd_y);
+       if (dist > vrange)
+           continue;
+
+       pr("%s (#%d) %s @ %s\n",
+          cname(pp->pln_own), pp->pln_own,
+          prplane(pp), xyas(pp->pln_x, pp->pln_y, player->cnum));
+       if (opt_HIDDEN)
+           setcont(player->cnum, pp->pln_own, FOUND_LOOK);
+    }
 }