]> git.pond.sub.org Git - empserver/blob - src/lib/commands/path.c
License upgrade to GPL version 3 or later
[empserver] / src / lib / commands / path.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2011, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
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.
10  *
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.
15  *
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/>.
18  *
19  *  ---
20  *
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.
24  *
25  *  ---
26  *
27  *  path.c: Show empire distribution paths
28  *
29  *  Known contributors to this file:
30  *     David Muir Sharnoff, 1986
31  *     (unknown rewrite), 1989
32  */
33
34 #include <config.h>
35
36 #include "commands.h"
37 #include "map.h"
38 #include "optlist.h"
39 #include "path.h"
40
41 int
42 path(void)
43 {
44
45     struct nstr_sect ns;
46     struct natstr *natp;
47     struct range absrange;
48     struct range relrange;
49     struct sctstr sect, dsect;
50     coord cx, cy;
51     int i;
52     int y;
53     char *pp, *p;
54     /* Note this is not re-entrant anyway, so we keep the buffers
55        around */
56     static char *mapbuf = NULL;
57     static char **map = NULL;
58     double move_cost;
59     char buf[1024];
60
61     if (!(p = getstarg(player->argp[1], "from sector : ", buf)) ||
62         !sarg_xy(p, &cx, &cy) || !getsect(cx, cy, &sect))
63         return RET_SYN;
64     if ((sect.sct_own != player->cnum) && !player->god) {
65         pr("Not yours\n");
66         return RET_FAIL;
67     }
68     getsect(sect.sct_dist_x, sect.sct_dist_y, &dsect);
69     pp = BestDistPath(buf, &sect, &dsect, &move_cost);
70     if (!pp) {
71         pr("No path possible from %s to distribution sector %s\n",
72            xyas(sect.sct_x, sect.sct_y, player->cnum),
73            xyas(dsect.sct_x, dsect.sct_y, player->cnum));
74         return RET_FAIL;
75     }
76     if (!mapbuf)
77         mapbuf = malloc(WORLD_Y * MAPWIDTH(3));
78     if (!map) {
79         map = malloc(WORLD_Y * sizeof(char *));
80         if (map && mapbuf) {
81             for (i = 0; i < WORLD_Y; i++)
82                 map[i] = &mapbuf[MAPWIDTH(3) * i];
83         } else if (map) {
84             free(map);
85             map = NULL;
86         }
87     }
88     if (!mapbuf || !map) {
89         pr("Memory error, tell the deity.\n");
90         logerror("malloc failed in path\n");
91         return RET_FAIL;
92     }
93     pathrange(cx, cy, pp, 1, &absrange);
94     snxtsct_area(&ns, &absrange);
95     natp = getnatp(player->cnum);
96     xyrelrange(natp, &absrange, &relrange);
97     blankfill(mapbuf, &ns.range, 3);
98     for (; *pp; ++pp) {
99         i = diridx(*pp);
100         if (i == DIR_STOP)
101             break;
102         memcpy(&map[delty(&ns.range, cy)][deltx(&ns.range, cx) * 2],
103                routech[i], 3);
104         cx = xnorm(cx + diroff[i][0]);
105         cy = ynorm(cy + diroff[i][1]);
106     }
107     border(&relrange, "     ", " ");
108     while (nxtsct(&ns, &sect)) {
109         if (!player->owner)
110             continue;
111         map[ns.dy][ns.dx * 2 + 1] = dchr[sect.sct_type].d_mnem;
112     }
113     for (y = ns.range.ly, i = 0; i < ns.range.height; y++, i++) {
114         cy = yrel(natp, y);
115         pr("%4d %s %-4d\n", cy, map[i], cy);
116         if (y >= WORLD_Y)
117             y -= WORLD_Y;
118     }
119     border(&relrange, "     ", " ");
120     return RET_OK;
121 }