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 "file.h"
00037 #include "path.h"
00038 #include "player.h"
00039 #include "prototypes.h"
00040 #include "sect.h"
00041
00042 int
00043 chkdir(char dir_char, int min_dir, int max_dir)
00044 {
00045 int i;
00046
00047 for (i = min_dir; i <= max_dir; i++)
00048 if (dir_char == dirch[i])
00049 return i;
00050 return -1;
00051 }
00052
00053 void
00054 direrr(char *stop_msg, char *view_msg, char *map_msg)
00055 {
00056 pr("Legal directions are:\n");
00057 pr(" %c %c\n", dirch[DIR_UL], dirch[DIR_UR]);
00058 pr("%c %c\n", dirch[DIR_L], dirch[DIR_R]);
00059 pr(" %c %c\n", dirch[DIR_DL], dirch[DIR_DR]);
00060 if (stop_msg != 0)
00061 pr(stop_msg, dirch[DIR_STOP]);
00062 if (view_msg != 0)
00063 pr(view_msg, dirch[DIR_VIEW]);
00064 if (map_msg != 0)
00065 pr(map_msg, dirch[DIR_MAP]);
00066 }
00067
00068
00069
00070
00071
00072 int
00073 diridx(char dir)
00074 {
00075 unsigned i = dir - 'a';
00076
00077 if (CANT_HAPPEN(i >= sizeof(dirindex) / sizeof(*dirindex)
00078 || dirindex[i] < 0))
00079 return DIR_STOP;
00080 return dirindex[i];
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 char *
00091 getpath(char *buf, char *arg, coord x, coord y, int onlyown,
00092 int showdes, enum p_mode destinations)
00093 {
00094 char buf2[1024];
00095 char *p = buf;
00096 char *bp;
00097 char prompt[128];
00098 coord dx, dy;
00099 struct sctstr sect;
00100 coord nx, ny;
00101 int dir;
00102
00103 if (arg) {
00104 strncpy(buf, arg, MAX_PATH_LEN - 1);
00105 buf[MAX_PATH_LEN - 1] = 0;
00106 } else {
00107 *p = 0;
00108 }
00109
00110 getsect(x, y, §);
00111 nx = x;
00112 ny = y;
00113
00114 more:
00115 while (*p) {
00116 if (sarg_xy(p, &dx, &dy)) {
00117 bp = NULL;
00118 switch (destinations) {
00119 case P_NONE:
00120 pr("Destination sectors not allowed here!\n");
00121 break;
00122 case P_FLYING:
00123 bp = BestAirPath(buf2, nx, ny, dx, dy);
00124 break;
00125 case P_SAILING:
00126 bp = BestShipPath(buf2, nx, ny, dx, dy, player->cnum);
00127 break;
00128 }
00129 if (bp && p + strlen(bp) + 1 < buf + MAX_PATH_LEN) {
00130 strcpy(p, bp);
00131 pr("Using best path '%s'\n", p);
00132 pr("Using total path '%s'\n", buf);
00133 return buf;
00134 } else {
00135 pr("Can't get to %s from here!\n",
00136 xyas(dx, dy, player->cnum));
00137 }
00138 break;
00139 }
00140 dir = chkdir(*p, DIR_STOP, DIR_LAST);
00141 if (dir < 0) {
00142 pr("\"%c\" is not legal...", *p);
00143 direrr("'%c' to stop\n", NULL, NULL);
00144 break;
00145 }
00146 nx = x + diroff[dir][0];
00147 ny = y + diroff[dir][1];
00148 getsect(nx, ny, §);
00149 if (onlyown && sect.sct_own != player->cnum) {
00150 pr("You don't own %s; you can't go there!\n",
00151 xyas(nx, ny, player->cnum));
00152 break;
00153 }
00154 if (dir == DIR_STOP) {
00155 p[1] = 0;
00156 return buf;
00157 }
00158 ++p;
00159 x = nx;
00160 y = ny;
00161 }
00162 fly_map(x, y);
00163 if (showdes) {
00164 getsect(x, y, §);
00165 sprintf(prompt, "<%c: %s> ", dchr[sect.sct_type].d_mnem,
00166 xyas(x, y, player->cnum));
00167 } else {
00168 sprintf(prompt, "<%d: %s> ", (int)(p - buf),
00169 xyas(x, y, player->cnum));
00170 }
00171 bp = getstring(prompt, buf2);
00172 if (bp && p + strlen(bp) + 1 >= buf + MAX_PATH_LEN) {
00173 pr("Path length may not exceed %d.\n", MAX_PATH_LEN);
00174 pr("Aborting...\n");
00175 bp = NULL;
00176 }
00177 if (!bp)
00178 return NULL;
00179 strcpy(p, bp);
00180 if (*bp)
00181 goto more;
00182 return buf;
00183 }
00184
00185
00186
00187
00188
00189 double
00190 fcost(struct sctstr *sp, natid own)
00191 {
00192 return 1.0;
00193 }
00194
00195
00196
00197
00198
00199 double
00200 ncost(struct sctstr *sp, natid own)
00201 {
00202 return 1.0;
00203 }
00204
00205
00206
00207
00208
00209 double
00210 pathtoxy(char *path, coord *xp, coord *yp,
00211 double (*cost)(struct sctstr *, natid))
00212 {
00213 struct sctstr s;
00214 char *pp;
00215 coord x;
00216 coord y;
00217 int val;
00218 double m;
00219
00220 x = *xp;
00221 y = *yp;
00222 m = 0.0;
00223 for (pp = path; *pp; pp++) {
00224 if ((val = diridx(*pp)) == DIR_STOP)
00225 break;
00226 x += diroff[val][0];
00227 y += diroff[val][1];
00228 if (!getsect(x, y, &s))
00229 return -1.0;
00230 m += cost(&s, s.sct_own);
00231 }
00232 *xp = xnorm(x);
00233 *yp = ynorm(y);
00234 return m;
00235 }
00236
00237 void
00238 pathrange(coord cx, coord cy, char *pp, int border, struct range *range)
00239 {
00240 int dir;
00241
00242 range->lx = cx;
00243 range->hx = cx;
00244 range->ly = cy;
00245 range->hy = cy;
00246 range->width = 0;
00247 range->height = 0;
00248 for (; *pp; pp++) {
00249 dir = diridx(*pp);
00250 if (dir == DIR_STOP)
00251 break;
00252 cx += diroff[dir][0];
00253 cy += diroff[dir][1];
00254 if (cx < range->lx)
00255 range->lx = cx;
00256 if (cx > range->hx)
00257 range->hx = cx;
00258 if (cy < range->ly)
00259 range->ly = cy;
00260 if (cy > range->hy)
00261 range->hy = cy;
00262 }
00263 range->lx = xnorm(range->lx - border * 2);
00264 range->ly = ynorm(range->ly - border);
00265 range->hx = xnorm(range->hx + border * 2 + 1);
00266 range->hy = ynorm(range->hy + border + 1);
00267 xysize_range(range);
00268 }