]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/maps.c
Update copyright notice
[empserver] / src / lib / subs / maps.c
index 2a1d4dcce4db9cae37a265ff2600a2817f1c3a97..a1c3f575daf2a43257bd061f61f903f0408351a8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2011, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2016, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                Ken Stevens, Steve McClure, Markus Armbruster
  *
  *  Empire is free software: you can redistribute it and/or modify
@@ -45,7 +45,6 @@
 #include "misc.h"
 #include "nat.h"
 #include "nsc.h"
-#include "nuke.h"
 #include "optlist.h"
 #include "plane.h"
 #include "player.h"
 /* whether to revert bmap, internal to do_map() */
 #define MAP_BMAP_REVERT        bit(7)
 
+static int parse_map_arg(int, char *, struct nstr_sect *, char *);
 static int parse_map_flags(int, char *);
 static int revert_bmap(struct nstr_sect *);
 static int draw_map(char, int, struct nstr_sect *);
 static int bmnxtsct(struct nstr_sect *);
 static char map_char(int, natid, int);
 static int unit_map(int, int, struct nstr_sect *, char *);
+static void snxtsct_around(struct nstr_sect *, coord, coord);
 
 int
-do_map(int bmap, int unit_type, char *arg, char *map_flags_arg)
+do_map(int bmap, int unit_type, char *arg1, char *arg2)
 {
     struct nstr_sect ns;
-    char origin = '\0';
-    int map_flags;
+    char origin;
+    int res, map_flags;
+
+    res = parse_map_arg(unit_type, arg1, &ns, &origin);
+    if (res != RET_OK)
+       return res;
+
+    map_flags = parse_map_flags(bmap, arg2);
+    if (map_flags < 0)
+       return RET_SYN;
+
+    if (map_flags & MAP_BMAP_REVERT)
+       return revert_bmap(&ns);
+    return draw_map(origin, map_flags, &ns);
+}
 
+static int
+parse_map_arg(int unit_type, char *arg,
+             struct nstr_sect *nsp, char *originp)
+{
     switch (sarg_type(arg)) {
     case NS_DIST:
     case NS_AREA:
     case NS_ALL:
-       if (!snxtsct(&ns, arg))
+       if (!snxtsct(nsp, arg))
            return RET_SYN;
+       *originp = 0;
        break;
     default:
-       if (unit_map(unit_type, atoi(arg), &ns, &origin) < 0) {
+       if (unit_map(unit_type, atoi(arg), nsp, originp) < 0) {
            pr("No such %s\n", ef_nameof(unit_type));
            return RET_FAIL;
        }
     }
-
-    map_flags = parse_map_flags(bmap, map_flags_arg);
-    if (map_flags < 0) 
-       return RET_SYN;
-
-    if (map_flags & MAP_BMAP_REVERT)
-       return revert_bmap(&ns);
-    return draw_map(origin, map_flags, &ns);
-}
-
-static void
-warn_deprecated_arg(char *what, char *arg, char *use)
-{
-    pr("%s '%s' is deprecated and will go away in a future release.\n"
-       "Use %s instead.\n",
-       what, arg, use);
+    return RET_OK;
 }
 
 static int
@@ -120,8 +124,6 @@ parse_map_flags(int bmap, char *str)
 {
     int map_flags;
     char *p;
-    int tflags = 0;
-    char *tp = NULL;
 
     switch (bmap) {
     default: CANT_REACH();
@@ -131,7 +133,7 @@ parse_map_flags(int bmap, char *str)
     case 0:   map_flags = 0;
     }
 
-    if (!str)
+    if (!str || !*str)
        return map_flags;
 
     /* special case "revert" */
@@ -167,28 +169,9 @@ parse_map_flags(int bmap, char *str)
            if (bmap != 'b')
                goto bad_flag;
            map_flags |= MAP_ALT;
-           /*
-            * Flags following 't' used to be ignored.  That breaks
-            * perfectly sensible "ts".  Try to continue, but save
-            * state for when a bad flag is found.
-            */
-           if (!tflags) {
-               tflags = map_flags;
-               tp = p;
-           }
            break;
-       case 'r':
-           if (bmap != 'b' || tflags)
-               goto bad_flag;
-           warn_deprecated_arg("Map flag", "r", "argument 'revert'");
-           return MAP_BMAP_REVERT;
        default:
        bad_flag:
-           if (tflags) {
-               /* ignore bad flags following 't' */
-               warn_deprecated_arg("Argument", tp, "map flag 't'");
-               return tflags;
-           }
            pr("Bad flag %c!\n", *p);
            return -1;
        }
@@ -328,7 +311,7 @@ draw_map(char origin, int map_flags, struct nstr_sect *nsp)
 
        yval = yrel(np, y);
        wmap[i][nsp->range.width] = '\0';
-       pr("%4d %s %-4d\n", yval, wmap[i], yval);
+       pr("%4d %s %d\n", yval, wmap[i], yval);
        if (y >= WORLD_Y)
            y -= WORLD_Y;
     }
@@ -367,12 +350,11 @@ bmnxtsct(struct nstr_sect *np)
        np->id = sctoff(np->x, np->y);
        return 1;
     }
-    /*NOTREACHED*/
 }
 
 /*
- * Return character to use in maps for sector type TYPE owned by OWN.
- * If OWNER_OR_GOD, the map is for the sector's owner or a deity.
+ * Return character to use in maps for sector type @type owned by @own.
+ * If @owner_or_god, the map is for the sector's owner or a deity.
  */
 static char
 map_char(int type, natid own, int owner_or_god)
@@ -390,7 +372,6 @@ static int
 unit_map(int unit_type, int uid, struct nstr_sect *nsp, char *originp)
 {
     union empobj_storage unit;
-    struct range range;
     char *name;
 
     if (CANT_HAPPEN((ef_flags(unit_type) & (EFF_OWNER | EFF_XY))
@@ -409,32 +390,107 @@ unit_map(int unit_type, int uid, struct nstr_sect *nsp, char *originp)
        *originp = *name;
     }
 
-    range.lx = xnorm(unit.gen.x - 10);
-    range.hx = xnorm(unit.gen.x + 10);
-    range.ly = ynorm(unit.gen.y - 5);
-    range.hy = ynorm(unit.gen.y + 5);
+    snxtsct_around(nsp, unit.gen.x, unit.gen.y);
+    return 0;
+}
+
+static void
+snxtsct_around(struct nstr_sect *nsp, coord x, coord y)
+{
+    struct range range;
+
+    range.lx = xnorm(x - 10);
+    range.hx = xnorm(x + 10);
+    range.ly = ynorm(y - 5);
+    range.hy = ynorm(y + 5);
     xysize_range(&range);
     snxtsct_area(nsp, &range);
-    return 0;
 }
 
 int
 display_region_map(int bmap, int unit_type, coord curx, coord cury,
                   char *arg1, char *arg2)
 {
-    char coordinates[80];
+    struct nstr_sect ns;
+    char origin;
+    int res, map_flags;
 
-    if (!arg1 || !*arg1) {
-       struct natstr *np;
+    if (arg1 && *arg1) {
+       res = parse_map_arg(unit_type, arg1, &ns, &origin);
+       if (res != RET_OK)
+           return res;
 
-       np = getnatp(player->cnum);
-       sprintf(coordinates, "%d:%d,%d:%d",
-           xrel(np, curx - 10), xrel(np, curx + 10),
-           yrel(np, cury - 5), yrel(np, cury + 5));
-       arg1 = coordinates;
+       map_flags = parse_map_flags(bmap, arg2);
+       if (map_flags < 0)
+           return RET_SYN;
+    } else {
+       snxtsct_around(&ns, curx, cury);
+       map_flags = 0;
+       origin = 0;
+    }
+
+    if (map_flags & MAP_BMAP_REVERT)
+       return revert_bmap(&ns);
+    return draw_map(origin, map_flags, &ns);
+}
+
+int
+nav_map(int x, int y, int show_designations)
+{
+    char *ptr;
+    struct nstr_sect ns;
+    struct sctstr sect;
+    int i;
+    /* Note this is not re-entrant anyway, so we keep the buffers
+       around */
+    static char *wmapbuf = NULL;
+    static char **wmap = NULL;
+    int changed = 0;
+
+    if (!wmapbuf)
+       wmapbuf = malloc(WORLD_Y * MAPWIDTH(1));
+    if (!wmap) {
+       wmap = malloc(WORLD_Y * sizeof(*wmap));
+       if (wmap && wmapbuf) {
+           for (i = 0; i < WORLD_Y; i++)
+               wmap[i] = &wmapbuf[MAPWIDTH(1) * i];
+       } else if (wmap) {
+           free(wmap);
+           wmap = NULL;
+       }
+    }
+    if (!wmapbuf || !wmap) {
+       pr("Memory error, tell the deity.\n");
+       logerror("malloc failed in navi\n");
+       return RET_FAIL;
     }
-    player->condarg = NULL;
-    return do_map(bmap, unit_type, arg1, arg2);
+    snxtsct_dist(&ns, x, y, 1);
+    blankfill(wmapbuf, &ns.range, 1);
+    while (nxtsct(&ns, &sect)) {
+       ptr = &wmap[ns.dy][ns.dx];
+       *ptr = dchr[sect.sct_type].d_mnem;
+       if (!show_designations &&
+           sect.sct_own != player->cnum &&
+           sect.sct_type != SCT_WATER &&
+           sect.sct_type != SCT_BSPAN && sect.sct_type != SCT_HARBR)
+           *ptr = '?';
+       changed += map_set(player->cnum, sect.sct_x, sect.sct_y, *ptr, 0);
+       /*
+        * We do it this way so that 'x' and 'X'
+        * bdesignations will show up. This can
+        * be used to mark mined sectors. So, the
+        * player will see the current des, UNLESS
+        * they've marked the sector 'x' or 'X',
+        * in which case they'll see that.
+        * --ts
+        */
+       *ptr = player->bmap[sect.sct_uid];
+    }
+    if (changed)
+       writemap(player->cnum);
+    for (i = 0; i < ns.range.height; i++)
+       pr("%s\n", wmap[i]);
+    return RET_OK;
 }
 
 int