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
00035 #include <config.h>
00036
00037 #include "commands.h"
00038 #include "map.h"
00039 #include "optlist.h"
00040 #include "path.h"
00041 #include "empobj.h"
00042 #include "unit.h"
00043
00044 static void pr_leader_change(struct empobj *leader);
00045 static struct empobj *get_leader(struct emp_qelem *list);
00046 static void switch_leader(struct emp_qelem *list, int uid);
00047
00048 int
00049 navi(void)
00050 {
00051 struct nstr_item ni_ship;
00052 struct emp_qelem ship_list;
00053 double minmob, maxmob;
00054 int together;
00055
00056 if (!snxtitem(&ni_ship, EF_SHIP, player->argp[1]))
00057 return RET_SYN;
00058 shp_sel(&ni_ship, &ship_list);
00059 shp_nav(&ship_list, &minmob, &maxmob, &together, player->cnum);
00060 if (QEMPTY(&ship_list)) {
00061 pr("No ships\n");
00062 return RET_FAIL;
00063 }
00064
00065 return do_unit_move(&ship_list, &together, &minmob, &maxmob);
00066 }
00067
00068 int
00069 do_unit_move(struct emp_qelem *ulist, int *together,
00070 double *minmob, double *maxmob)
00071 {
00072 char *cp = NULL;
00073 int leader_uid;
00074 struct empobj *leader;
00075 int dir;
00076 int stopping = 0;
00077 int skip = 0;
00078 char buf[1024];
00079 char prompt[128];
00080 char scanspace[1024];
00081 char pathtaken[1024];
00082 char *pt = pathtaken;
00083 char bmap_flag;
00084 int ac;
00085 short type;
00086
00087 leader = get_leader(ulist);
00088 leader_uid = leader->uid;
00089 type = leader->ef_type;
00090 pr("%s is %s\n",
00091 type == EF_SHIP ? "Flagship" : "Leader",
00092 obj_nameof(leader));
00093
00094 if (player->argp[2]) {
00095 strcpy(buf, player->argp[2]);
00096 if (!(cp = unit_path(*together, leader, buf)))
00097 cp = player->argp[2];
00098 }
00099
00100 *pt = '\0';
00101 while (!QEMPTY(ulist)) {
00102 char dp[80];
00103
00104 if (cp == NULL || *cp == '\0' || stopping) {
00105 stopping = 0;
00106 if (type == EF_SHIP)
00107 shp_nav(ulist, minmob, maxmob, together, player->cnum);
00108 else
00109 lnd_mar(ulist, minmob, maxmob, together, player->cnum);
00110 if (QEMPTY(ulist)) {
00111 pr("No %s left\n",
00112 type == EF_SHIP ? "ships" : "lands");
00113 if (type == EF_SHIP && strlen(pathtaken) > 1) {
00114 pathtaken[strlen(pathtaken) - 1] = '\0';
00115 pr("Path taken: %s\n", pathtaken);
00116 }
00117 return RET_OK;
00118 }
00119 leader = get_leader(ulist);
00120 if (leader->uid != leader_uid) {
00121 leader_uid = leader->uid;
00122 pr_leader_change(leader);
00123 stopping = 1;
00124 continue;
00125 }
00126 if (!skip)
00127 nav_map(leader->x, leader->y,
00128 type == EF_SHIP ?
00129 !(mchr[(int)leader->type].m_flags & M_SUB) : 1);
00130 else
00131 skip = 0;
00132 sprintf(prompt, "<%.1f:%.1f: %s> ", *maxmob,
00133 *minmob, xyas(leader->x, leader->y, player->cnum));
00134 cp = getstring(prompt, buf);
00135
00136
00137
00138 if (type == EF_SHIP)
00139 shp_nav(ulist, minmob, maxmob, together, player->cnum);
00140 else
00141 lnd_mar(ulist, minmob, maxmob, together, player->cnum);
00142 if (QEMPTY(ulist)) {
00143 pr("No %s left\n",
00144 type == EF_SHIP ? "ships" : "lands");
00145 if (type == EF_SHIP && strlen(pathtaken) > 1) {
00146 pathtaken[strlen(pathtaken) - 1] = '\0';
00147 pr("Path taken: %s\n", pathtaken);
00148 }
00149 return RET_OK;
00150 }
00151 leader = get_leader(ulist);
00152 if (leader->uid != leader_uid) {
00153 leader_uid = leader->uid;
00154 pr_leader_change(leader);
00155 stopping = 1;
00156 continue;
00157 }
00158 if (!(cp = unit_path(*together, leader, buf)))
00159 cp = buf;
00160 }
00161 if (type == EF_SHIP) {
00162 radmapnopr(leader->x, leader->y, (int)leader->effic,
00163 (int)techfact(leader->tech,
00164 mchr[(int)leader->type].m_vrnge),
00165 (mchr[(int)leader->type].m_flags & M_SONAR)
00166 ? techfact(leader->tech, 1.0) : 0.0);
00167 }
00168 if (cp == NULL || *cp == '\0')
00169 cp = &dirch[DIR_STOP];
00170 dir = chkdir(*cp, DIR_STOP, DIR_LAST);
00171 if (dir >= 0) {
00172 if (type == EF_SHIP) {
00173 stopping |= shp_nav_one_sector(ulist, dir,
00174 player->cnum, *together);
00175 if (stopping != 2) {
00176 *pt++ = dirch[dir];
00177 *pt = '\0';
00178 }
00179 } else
00180 stopping |=
00181 lnd_mar_one_sector(ulist, dir, player->cnum,
00182 *together);
00183 cp++;
00184 continue;
00185 }
00186 ac = parse(cp, scanspace, player->argp, NULL, NULL, NULL);
00187 if (ac <= 1) {
00188 sprintf(dp, "%d", leader->uid);
00189 player->argp[1] = dp;
00190 cp++;
00191 } else
00192 cp = NULL;
00193 bmap_flag = 0;
00194 switch (*player->argp[0]) {
00195 case 'B':
00196 bmap_flag = 'b';
00197
00198
00199
00200 case 'M':
00201 do_map(bmap_flag, leader->ef_type, player->argp[1],
00202 player->argp[2]);
00203 skip = 1;
00204 continue;
00205 case 'f':
00206 if (ac <= 1)
00207 switch_leader(ulist, -1);
00208 else
00209 switch_leader(ulist, atoi(player->argp[1]));
00210 leader = get_leader(ulist);
00211 if (leader->uid != leader_uid) {
00212 leader_uid = leader->uid;
00213 pr_leader_change(leader);
00214 }
00215 continue;
00216 case 'i':
00217 unit_list(ulist);
00218 continue;
00219 case 'm':
00220 if (type == EF_SHIP)
00221 stopping |= shp_sweep(ulist, 1, 1, player->cnum);
00222 else {
00223 lnd_sweep(ulist, 1, 1, player->cnum);
00224 stopping |= lnd_check_mines(ulist);
00225 }
00226 continue;
00227 case 'r':
00228 radar(leader->ef_type);
00229 skip = 1;
00230 player->btused++;
00231 continue;
00232 case 'l':
00233 do_look(type);
00234 player->btused++;
00235 continue;
00236 case 's':
00237 if (leader->ef_type != EF_SHIP)
00238 break;
00239 sona();
00240 player->btused++;
00241 skip = 1;
00242 continue;
00243 case 'd':
00244 if (ac == 2) {
00245 player->argp[2] = player->argp[1];
00246 sprintf(dp, "%d", leader->uid);
00247 player->argp[1] = dp;
00248 }
00249 if (type == EF_SHIP)
00250 mine();
00251 else
00252 landmine();
00253 skip = 1;
00254 player->btused++;
00255 continue;
00256 case 'v':
00257 unit_view(ulist);
00258 continue;
00259 }
00260 direrr("`%c' to stop", ", `%c' to view", NULL);
00261 pr(", `i' to list %s, `f' to change %s,\n",
00262 type == EF_SHIP ? "ships" : "units",
00263 type == EF_SHIP ? "flagship" : "leader");
00264 pr("`r' to radar, %s`l' to look, `M' to map, `B' to bmap,\n",
00265 type == EF_SHIP ? "`s' to sonar, " : "");
00266 pr("`d' to drop mines, and `m' to minesweep\n");
00267 stopping = 1;
00268 }
00269 if (type == EF_SHIP && strlen(pathtaken) > 1) {
00270 pathtaken[strlen(pathtaken) - 1] = '\0';
00271 pr("Path taken: %s\n", pathtaken);
00272 }
00273 return RET_OK;
00274 }
00275
00276 int
00277 nav_map(int x, int y, int show_designations)
00278 {
00279 char *ptr;
00280 struct nstr_sect ns;
00281 struct natstr *np;
00282 struct sctstr sect;
00283 struct range range;
00284 int i;
00285
00286
00287 static char *wmapbuf = NULL;
00288 static char **wmap = NULL;
00289 int changed = 0;
00290
00291 if (!wmapbuf)
00292 wmapbuf = malloc(WORLD_Y * MAPWIDTH(1));
00293 if (!wmap) {
00294 wmap = malloc(WORLD_Y * sizeof(*wmap));
00295 if (wmap && wmapbuf) {
00296 for (i = 0; i < WORLD_Y; i++)
00297 wmap[i] = &wmapbuf[MAPWIDTH(1) * i];
00298 } else if (wmap) {
00299 free(wmap);
00300 wmap = NULL;
00301 }
00302 }
00303 if (!wmapbuf || !wmap) {
00304 pr("Memory error, tell the deity.\n");
00305 logerror("malloc failed in navi\n");
00306 return RET_FAIL;
00307 }
00308 snxtsct_dist(&ns, x, y, 1);
00309 np = getnatp(player->cnum);
00310 xyrelrange(np, &ns.range, &range);
00311 blankfill(wmapbuf, &ns.range, 1);
00312 while (nxtsct(&ns, §)) {
00313 ptr = &wmap[ns.dy][ns.dx];
00314 *ptr = dchr[sect.sct_type].d_mnem;
00315 if (!show_designations &&
00316 sect.sct_own != player->cnum &&
00317 sect.sct_type != SCT_WATER &&
00318 sect.sct_type != SCT_BSPAN && sect.sct_type != SCT_HARBR)
00319 *ptr = '?';
00320 changed += map_set(player->cnum, sect.sct_x, sect.sct_y, *ptr, 0);
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 *ptr = player->bmap[sctoff(sect.sct_x, sect.sct_y)];
00331 }
00332 if (changed)
00333 writemap(player->cnum);
00334 for (i = 0; i < ns.range.height; i++)
00335 pr("%s\n", wmap[i]);
00336 return RET_OK;
00337 }
00338
00339 static void
00340 pr_leader_change(struct empobj *leader)
00341 {
00342 pr("Changing %s to %s\n",
00343 leader->ef_type == EF_SHIP ? "flagship" : "leader",
00344 obj_nameof(leader));
00345 }
00346
00347 static struct empobj *
00348 get_leader(struct emp_qelem *list)
00349 {
00350 return &((struct ulist *)(list->q_back))->unit.gen;
00351 }
00352
00353 static void
00354 switch_leader(struct emp_qelem *list, int uid)
00355 {
00356 struct emp_qelem *qp, *save;
00357 struct ulist *ulp;
00358
00359 if (QEMPTY(list))
00360 return;
00361
00362 save = qp = list->q_back;
00363 do {
00364 emp_remque(qp);
00365 emp_insque(qp, list);
00366 qp = list->q_back;
00367 ulp = (struct ulist *)qp;
00368 if (ulp->unit.gen.uid == uid || uid == -1)
00369 break;
00370 } while (list->q_back != save);
00371 }