/* * survey type <sarg> ?cond * */ int surv(void) { int nsect; struct nstr_sect nstr; int y; struct valstr val; struct natstr *np; struct sctstr sect; struct range range; char *ptr; struct nscstr cond[NS_NCOND]; int ncond; int i; char buf[1024]; /* Note this is not re-entrant anyway, so we keep the buffers around */ static char *mapbuf = NULL; static char **map = NULL; nsect = 0; ptr = getstarg(player->argp[1], "commodity or variable? ", buf); if (!ptr || !*ptr) return RET_SYN; ptr = nstr_comp_val(ptr, &val, EF_SECTOR); if (!ptr) return RET_SYN; if (val.val_cat != NSC_OFF || nstr_promote(val.val_type) != NSC_LONG) { pr("Can't survey this\n"); return RET_SYN; } for (; isspace(*ptr); ++ptr) ; if (*ptr) return RET_SYN; if (!snxtsct(&nstr, player->argp[2])) return RET_SYN; if (!mapbuf) mapbuf = malloc(WORLD_Y * MAPWIDTH(1)); if (!map) { map = malloc(WORLD_Y * sizeof(char *)); if (map && mapbuf) { for (i = 0; i < WORLD_Y; i++) map[i] = &mapbuf[MAPWIDTH(1) * i]; } else if (map) { free(map); map = NULL; } } if (!mapbuf || !map) { pr("Memory error, tell the deity.\n"); logerror("malloc failed in sect\n"); return RET_FAIL; } ncond = nstr.ncond; memcpy(cond, nstr.cond, sizeof(struct nscstr) * ncond); nstr.ncond = 0; np = getnatp(player->cnum); xyrelrange(np, &nstr.range, &range); border(&range, " ", ""); blankfill(mapbuf, &nstr.range, 1); while (nxtsct(&nstr, §)) { if (!player->owner) continue; ptr = &map[nstr.dy][nstr.dx]; if (nstr_exec(cond, ncond, §)) { ++nsect; *ptr = 0x80 | code_char(val, §); } else { *ptr = dchr[sect.sct_type].d_mnem; } } for (y = nstr.range.ly, i = 0; i < nstr.range.height; y++, i++) { int yval; yval = yrel(np, y); pr("%4d %s %4d\n", yval, map[i], yval); if (y >= WORLD_Y) y -= WORLD_Y; } border(&range, " ", ""); if (nsect > 0) pr("\n%d sector%s.\n", nsect, splur(nsect)); return RET_OK; }
int nxtitem(struct nstr_item *np, void *ptr) { struct empobj *gp; int selected; if (np->sel == NS_UNDEF) return 0; gp = (struct empobj *)ptr; do { if (np->sel == NS_LIST) { np->index++; if (np->index >= np->size) return 0; np->cur = np->list[np->index]; } else if (np->sel == NS_CARGO) { if (np->next < 0) return 0; np->cur = np->next; np->next = unit_cargo_next(np->type, np->next); } else { np->cur++; } if (!ef_read(np->type, np->cur, ptr)) return 0; selected = 1; switch (np->sel) { case NS_LIST: case NS_CARGO: case NS_ALL: break; case NS_DIST: if (CANT_HAPPEN(!(ef_flags(np->type) & EFF_XY))) return 0; if (!xyinrange(gp->x, gp->y, &np->range)) { selected = 0; break; } np->curdist = mapdist(gp->x, gp->y, np->cx, np->cy); if (np->curdist > np->dist) selected = 0; break; case NS_AREA: if (CANT_HAPPEN(!(ef_flags(np->type) & EFF_XY))) return 0; if (!xyinrange(gp->x, gp->y, &np->range)) selected = 0; break; case NS_XY: if (CANT_HAPPEN(!(ef_flags(np->type) & EFF_XY))) return 0; if (xnorm(gp->x) != np->cx || ynorm(gp->y) != np->cy) selected = 0; break; case NS_GROUP: if (CANT_HAPPEN(!(ef_flags(np->type) & EFF_GROUP))) return 0; if (np->group != gp->group) selected = 0; break; default: CANT_REACH(); return 0; } if (selected && np->ncond) { /* nstr_exec is expensive, so we do it last */ if (!nstr_exec(np->cond, np->ncond, ptr)) selected = 0; } } while (!selected); return 1; }
int rout(void) { struct ichrstr *ip; struct nstr_sect ns; struct natstr *natp; struct sctstr sect; struct nscstr cond[NS_NCOND]; int ncond; struct range relrange; int row; int y; int ry; i_type i_del; int dir; char *p; /* Note this is not re-entrant anyway, so we keep the buffers around */ static char *mapbuf = NULL; static char **map = NULL; int i; if (!(ip = whatitem(player->argp[1], "What item? "))) return RET_SYN; i_del = ip->i_uid;; if (!snxtsct(&ns, player->argp[2])) return RET_SYN; if (!mapbuf) mapbuf = malloc(WORLD_Y * MAPWIDTH(3)); if (!map) { map = malloc(WORLD_Y * sizeof(char *)); if (map && mapbuf) { for (i = 0; i < WORLD_Y; i++) map[i] = &mapbuf[MAPWIDTH(3) * i]; } else if (map) { free(map); map = NULL; } } if (!mapbuf || !map) { pr("Memory error, tell the deity.\n"); logerror("malloc failed in rout\n"); return RET_FAIL; } ncond = ns.ncond; memcpy(cond, ns.cond, sizeof(struct nscstr) * ncond); ns.ncond = 0; natp = getnatp(player->cnum); xyrelrange(natp, &ns.range, &relrange); blankfill(mapbuf, &ns.range, 3); border(&relrange, " ", " "); while (nxtsct(&ns, §)) { if (!player->owner) continue; p = &map[ns.dy][ns.dx * 2]; dir = sect.sct_del[i_del] & 0x7; if (dir && nstr_exec(cond, ncond, §)) memcpy(p, routech[dir], 3); p[1] = dchr[sect.sct_type].d_mnem; } for (row = 0, y = ns.range.ly; row < ns.range.height; y++, row++) { ry = yrel(natp, y); pr("%4d %s %-4d\n", ry, map[row], ry); if (y >= WORLD_Y) y -= WORLD_Y; } border(&relrange, " ", " "); return RET_OK; }