]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/move.c
Use the new path finder for land paths, drop old A*
[empserver] / src / lib / subs / move.c
index e21e4fa436b2348db85acdb3befd7a0c0a2cca97..57abc754388357f26a291ef6dff92d78ce9694fe 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2011, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
- *  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.
  *
  *  ---
  *
  *  move.c: Move something somewhere.
- * 
+ *
  *  Known contributors to this file:
- *     
+ *
  */
 
-#include "misc.h"
-#include "player.h"
-#include "var.h"
-#include "sect.h"
-#include "item.h"
+#include <config.h>
+
+#include <ctype.h>
+#include "damage.h"
 #include "file.h"
-#include "deity.h"
-#include "xy.h"
-#include "path.h"
-#include "nat.h"
 #include "map.h"
-#include "nsc.h"
-#include "damage.h"
+#include "path.h"
+#include "player.h"
 #include "prototypes.h"
+#include "sect.h"
 
-static int move_map(s_char *what, coord curx, coord cury, s_char *arg);
+static int move_map(coord curx, coord cury, char *arg);
 
 int
-move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
-           double weight, s_char *path,
-           int (*map)(s_char *, coord, coord, s_char *), int exploring,
+move_ground(struct sctstr *start, struct sctstr *end,
+           double weight, char *path,
+           int (*map)(coord, coord, char *), int exploring,
            int *dam)
 {
     struct sctstr sect, ending_sect;
     struct sctstr next, dsect;
-    int vec[I_MAX + 1];
     coord curx, cury, oldx, oldy;
     coord tmpx, tmpy;
     coord dx, dy;
-    s_char *movstr;
+    char *movstr;
     double sect_mcost;
     double total_mcost;
     double mv_cost;
-    double mobility = (double)start->sct_mobil;
+    double mobility = start->sct_mobil;
     int dir;
     int intcost;
-    int takedam = (*dam), out = 0;
-    s_char bpath[512];
-    s_char buf2[512];
-    s_char prompt[128];
-    s_char buf[1024];
+    int takedam = *dam;
+    int out = 0;
+    char bpath[1024];
+    char buf2[1024];
+    char prompt[128];
+    char buf[1024];
 
     *end = *start;
     if (mobility <= 0.0)
@@ -85,10 +80,10 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
        }
        pr("Looking for best path to %s\n", path);
        path = BestLandPath(buf2, start, &ending_sect, &total_mcost,
-                           MOB_ROAD);
-       if (exploring && (path != (s_char *)0)) /* take off the 'h' */
-           *(path + strlen(path) - 1) = '\0';
-       if (path == (s_char *)0)
+                           MOB_MOVE);
+       if (exploring && path)  /* take off the 'h' */
+           path[strlen(path) - 1] = '\0';
+       if (!path)
            pr("No owned path exists!\n");
        else {
            pr("Using best path '%s', movement cost %1.3f\n",
@@ -112,11 +107,11 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
     for (;;) {
        oldx = curx;
        oldy = cury;
-       if (movstr == 0 || *movstr == 0) {
+       if (!movstr || *movstr == 0) {
            if (exploring) {
-               map(what, curx, cury, (s_char *)0);
+               map(curx, cury, NULL);
            } else {
-               move_map(what, curx, cury, (s_char *)0);
+               move_map(curx, cury, NULL);
            }
            sprintf(prompt, "<%.1f: %c %s> ", mobility,
                    dchr[sect.sct_type].d_mnem,
@@ -126,20 +121,19 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
        if (movstr && sarg_xy(movstr, &dx, &dy)) {
            if (getsect(dx, dy, &dsect)) {
                movstr = BestLandPath(buf2, &sect, &dsect, &mv_cost,
-                                     MOB_ROAD);
+                                     MOB_MOVE);
            } else {
                pr("Invalid destination sector!\n");
-               movstr = (s_char *)0;
+               movstr = NULL;
            }
 
-           if (movstr == (s_char *)0) {
+           if (movstr == NULL) {
                pr("Can't get to %s from here!\n",
                   xyas(dx, dy, player->cnum));
-               movstr = (s_char *)0;
            } else {
                if ((mv_cost * weight) > mobility) {
                    pr("Not enough mobility to go all the way. Nothing moved.\n");
-                   movstr = (s_char *)0;
+                   movstr = NULL;
                } else {
                    pr("Using best path '%s', movement cost %1.3f\n",
                       movstr, mv_cost);
@@ -148,7 +142,7 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
                }
            }
        }
-       if (movstr == 0 || *movstr == 0) {
+       if (!movstr || *movstr == 0) {
            buf2[0] = dirch[DIR_STOP];
            buf2[1] = 0;
            movstr = buf2;
@@ -159,18 +153,17 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
            *movstr = 0;
            continue;
        }
-       movstr++;
+       do  movstr++; while (isspace(*movstr));
        if (dir == DIR_MAP) {
            if (!exploring)
-               map(what, curx, cury, movstr + 1);
+               map(curx, cury, movstr);
            *movstr = 0;
            continue;
        } else if (dir == DIR_STOP)
            break;
        else if (dir == DIR_VIEW) {
            pr("%d%% %s with %d civilians.\n", sect.sct_effic,
-              dchr[sect.sct_type].d_name,
-              getvar(V_CIVIL, (s_char *)&sect, EF_SECTOR));
+              dchr[sect.sct_type].d_name, sect.sct_item[I_CIVIL]);
            continue;
        }
        /*
@@ -192,9 +185,10 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
                *movstr = 0;
                continue;
            }
-           getvec(VT_ITEM, vec, (s_char *)&next, EF_SECTOR);
-           sect_mcost = sector_mcost(&next, MOB_ROAD);
-           if ((!player->owner && (!exploring || vec[I_MILIT] || vec[I_CIVIL]))
+           sect_mcost = sector_mcost(&next, MOB_MOVE);
+           if ((!player->owner && (!exploring
+                                   || next.sct_item[I_MILIT]
+                                   || next.sct_item[I_CIVIL]))
                || sect_mcost == -1.0) {
                /* already-owned, or prohibited terrain */
                pr("You can't go there...\n");
@@ -211,8 +205,8 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
            mobility -= sect_mcost;
            total_mcost += sect_mcost;
        }
-       curx = tmpx;
-       cury = tmpy;
+       curx = next.sct_x;
+       cury = next.sct_y;
        if (cury != start->sct_y)
            out = 1;
        if (curx != start->sct_x)
@@ -229,8 +223,8 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
         */
        if (takedam && chance(weight / 100.0) &&
            ((curx != oldx) || (cury != oldy)))
-           (*dam) += ground_interdict(curx, cury, player->cnum,
-                                      "commodities");
+           *dam += ground_interdict(curx, cury, player->cnum,
+                                    "commodities");
        if (*dam >= 100)
            break;
     }
@@ -250,32 +244,18 @@ move_ground(s_char *what, struct sctstr *start, struct sctstr *end,
 
 /*ARGSUSED*/
 static int
-move_map(s_char *what, coord curx, coord cury, s_char *arg)
+move_map(coord curx, coord cury, char *arg)
 {
     struct nstr_sect ns;
-    struct natstr *np;
     struct sctstr sect;
-    coord rel_x, rel_y;
-    s_char range[128];
-    s_char view[7];
+    char view[7];
     int i;
-    int vec[I_MAX + 1];
     int changed = 0;
 
-    np = getnatp(player->cnum);
-    rel_x = xrel(np, curx);
-    rel_y = yrel(np, cury);
-    sprintf(range, "%d:%d,%d:%d", rel_x - 2, rel_x + 2, rel_y - 1,
-           rel_y + 1);
-    player->condarg = 0;
-    /* This is necessary, otherwise move_map would attempt to pay */
-    /* attention to the conditional arguments left behind by such */
-    /* a command as "tran p -1,-1 ?eff=100".. It'd then only see  */
-    /* 100% efficienct sects, and get all screwed up         --ts */
-    if (!snxtsct(&ns, range))
-       return RET_FAIL;
+    snxtsct_dist(&ns, curx, cury, 1);
     i = 0;
     while (i < 7 && nxtsct(&ns, &sect)) {
+       /* Nasty: this relies on the iteration order */
        view[i] = dchr[sect.sct_type].d_mnem;
        switch (sect.sct_type) {
        case SCT_WATER:
@@ -296,13 +276,13 @@ move_map(s_char *what, coord curx, coord cury, s_char *arg)
        writemap(player->cnum);
     if (!getsect(curx, cury, &sect))
        return RET_FAIL;
-    getvec(VT_ITEM, vec, (s_char *)&sect, EF_SECTOR);
     pr("    %c %c      eff   mob   civ  mil   uw food  work  avail\n",
        view[0], view[1]);
     pr("   %c %c %c     %3d   %3d  %4d %4d %4d %4d   %3d   %3d\n",
        view[2], view[3], view[4],
-       sect.sct_effic, sect.sct_mobil, vec[I_CIVIL], vec[I_MILIT],
-       vec[I_UW], vec[I_FOOD], sect.sct_work, sect.sct_avail);
+       sect.sct_effic, sect.sct_mobil,
+       sect.sct_item[I_CIVIL], sect.sct_item[I_MILIT], sect.sct_item[I_UW],
+       sect.sct_item[I_FOOD], sect.sct_work, sect.sct_avail);
     pr("    %c %c\n", view[5], view[6]);
     return RET_OK;
 }
@@ -311,29 +291,15 @@ int
 fly_map(coord curx, coord cury)
 {
     struct nstr_sect ns;
-    struct natstr *np;
     struct sctstr sect;
-    coord rel_x, rel_y;
-    s_char view[7];
+    char view[7];
     int i;
-    s_char range[128];
-
-    np = getnatp(player->cnum);
-    rel_x = xrel(np, curx);
-    rel_y = yrel(np, cury);
-    sprintf(range, "%d:%d,%d:%d", rel_x - 2, rel_x + 2, rel_y - 1,
-           rel_y + 1);
-    player->condarg = 0;
-    /* This is necessary, otherwise move_map would attempt to pay */
-    /* attention to the conditional arguments left behind by such */
-    /* a command as "tran p -1,-1 ?eff=100".. It'd then only see  */
-    /* 100% efficienct sects, and get all screwed up         --ts */
 
-    if (!snxtsct(&ns, range))
-       return RET_FAIL;
+    snxtsct_dist(&ns, curx, cury, 1);
     i = 0;
     while (i < 7 && nxtsct(&ns, &sect)) {
-       if (!(view[i] = player->bmap[sctoff(ns.x, ns.y)]))
+       /* Nasty: this relies on the iteration order */
+       if (!(view[i] = player->bmap[sect.sct_uid]))
            view[i] = ' ';
        i++;
     }
@@ -348,20 +314,17 @@ int
 check_lmines(coord x, coord y, double weight)
 {
     struct sctstr sect;
-    int mines;
     int dam = 0;
 
     getsect(x, y, &sect);
-    mines = getvar(V_MINE, (s_char *)&sect, EF_SECTOR);
-    if (mines > 0 &&
+    if (SCT_LANDMINES(&sect) > 0 &&
        sect.sct_oldown != player->cnum &&
-       chance(DMINE_LHITCHANCE(mines)) && chance(weight / 100.0)) {
+       chance(DMINE_LHITCHANCE(sect.sct_mines)) && chance(weight / 100.0)) {
        pr_beep();
        pr("Blammo! Landmines detected! in %s  ",
           xyas(sect.sct_x, sect.sct_y, player->cnum));
        dam = roll(20);
-       --mines;
-       putvar(V_MINE, mines, (s_char *)&sect, EF_SECTOR);
+       --sect.sct_mines;
        putsect(&sect);
        pr("%d damage sustained.\n", dam);
     }