/* * Dump items of type @type selected by @arg to @xd. * Return RET_OK on success, RET_SYN on error. */ static int xditem(struct xdstr *xd, int type, char *arg) { struct castr *ca; struct nstr_item ni; int n; unsigned char buf[EF_WITH_CADEF_MAX_ENTRY_SIZE]; ca = ef_cadef(type); if (!ca) return RET_SYN; if (!snxtitem(&ni, type, arg, NULL)) return RET_SYN; xdhdr(xd, ef_nameof(type), 0); n = 0; while (nxtitem(&ni, buf)) { if (!xdvisible(type, buf)) continue; ++n; xdflds(xd, ca, buf); xd->pr("\n"); } xdftr(xd, n); return RET_OK; }
/* * Get planes and escorts argument. * Read planes into *NI_BOMB, and (optional) escorts into *NI_ESC. * If INPUT_BOMB is not empty, use it, else prompt for more input. * Same for INPUT_ESC. * If we got a plane argument, initialize *NI_BOMB and *NI_ESC, and * return 0. * Else return -1 (*NI_BOMB and *NI_ESC may be modified). */ int get_planes(struct nstr_item *ni_bomb, struct nstr_item *ni_esc, char *input_bomb, char *input_esc) { if (!snxtitem(ni_bomb, EF_PLANE, input_bomb, NULL)) return -1; if (!snxtitem(ni_esc, EF_PLANE, input_esc, "escort(s)? ")) { if (player->aborted) return -1; pr("No escorts...\n"); } return 0; }
int wing(void) { struct plnstr plane; int count; char *cp; char c; struct nstr_item nstr; char buf[1024]; if (!(cp = getstarg(player->argp[1], "wing? ", buf))) return RET_SYN; c = *cp; if (!isalpha(c) && c != '~') { pr("Specify wing, (1 alpha char or '~')\n"); return RET_SYN; } if (c == '~') c = 0; if (!snxtitem(&nstr, EF_PLANE, player->argp[2], NULL)) return RET_SYN; count = 0; while (nxtitem(&nstr, &plane)) { if (plane.pln_own != player->cnum) continue; if (plane.pln_wing == c) continue; plane.pln_wing = c; putplane(plane.pln_uid, &plane); count++; } pr("%d plane%s added to wing `%1.1s'\n", count, splur(count), &c); return RET_OK; }
int reje(void) { static char *what[] = { "teles", "annos", "loans" }; char *p; enum rej_comm rej; int do_undo; struct natstr nat; struct nstr_item ni; char buf[1024]; if (!(p = getstarg(player->argp[1], "reject or accept? ", buf))) return RET_SYN; switch (*p) { case 'r': do_undo = 1; break; case 'a': do_undo = 0; break; default: pr("That's not one of the choices!\n"); return RET_SYN; } p = getstarg(player->argp[2], "mail, loans, or announcements? ", buf); if (!p) return RET_SYN; switch (*p) { case 'a': rej = REJ_ANNO; break; case 'l': rej = REJ_LOAN; break; case 'm': rej = REJ_TELE; break; default: pr("That's not one of the choices!\n"); return RET_SYN; } if (!snxtitem(&ni, EF_NATION, player->argp[3], NULL)) return RET_SYN; while (nxtitem(&ni, &nat)) { if (nat.nat_stat == STAT_GOD) { pr("You may not reject/accept stuff from %s\n" "because they are a deity.\n", nat.nat_cnam); continue; } if (nat.nat_stat == STAT_UNUSED) continue; pr("%s %s from %s\n", (do_undo == 1 ? "Rejecting" : "Accepting"), what[rej], nat.nat_cnam); setrej(player->cnum, (natid)ni.cur, do_undo, rej); } return RET_OK; }
int supp(void) { int nunits; struct nstr_item ni; struct lndstr land; if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL)) return RET_SYN; nunits = 0; while (nxtitem(&ni, &land)) { if (!player->owner || land.lnd_own == 0) continue; nunits++; if (lnd_supply_all(&land)) pr("%s has supplies\n", prland(&land)); else pr("%s is out of supply\n", prland(&land)); } if (nunits == 0) { if (player->argp[1]) pr("%s: No unit(s)\n", player->argp[1]); else pr("%s: No unit(s)\n", ""); return RET_FAIL; } else pr("%d unit%s\n", nunits, splur(nunits)); return RET_OK; }
int do_look(int type) { int i; struct nstr_item ni; union empobj_storage unit; struct sctstr sect; int x, y; unsigned char *bitmap; int changed = 0; if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP)) type = EF_SHIP; if (!snxtitem(&ni, type, player->argp[1], NULL)) return RET_SYN; bitmap = calloc((WORLD_SZ() + 7) / 8, 1); if (!bitmap) { logerror("malloc failed in do_look\n"); pr("Memory error. Tell the deity.\n"); return RET_FAIL; } while (nxtitem(&ni, &unit)) { if (!player->owner) continue; if (type == EF_LAND) { if (unit.land.lnd_ship >= 0) continue; if (unit.land.lnd_land >= 0) continue; /* Spies don't need military to do a "llook". Other units do */ if ((unit.land.lnd_item[I_MILIT] <= 0) && !(lchr[(int)unit.land.lnd_type].l_flags & L_SPY)) continue; look_land(&unit.land); } else look_ship(&unit.ship); for (i = 0; i <= 6; i++) { x = diroff[i][0] + unit.gen.x; y = diroff[i][1] + unit.gen.y; if (emp_getbit(x, y, bitmap)) continue; emp_setbit(x, y, bitmap); getsect(x, y, §); if (sect.sct_type == SCT_WATER) continue; look_at_sect(§, 10); changed += map_set(player->cnum, x, y, dchr[sect.sct_type].d_mnem, 0); if (opt_HIDDEN) { setcont(player->cnum, sect.sct_own, FOUND_LOOK); } } } if (changed) writemap(player->cnum); free(bitmap); return RET_OK; }
int range(void) { struct nstr_item np; struct plnstr plane; int i, rmax; char *p; char buf[1024]; if (!snxtitem(&np, EF_PLANE, player->argp[1], NULL)) return RET_SYN; while (nxtitem(&np, &plane)) { if (!player->owner || plane.pln_own == 0) continue; p = getstarg(player->argp[2], "New range? ", buf); if (!p) return RET_FAIL; if (!check_plane_ok(&plane)) return RET_SYN; if ((i = atoi(p)) < 0) continue; rmax = pln_range_max(&plane); plane.pln_range = MIN(rmax, i); pr("Plane %d range changed to %d\n", plane.pln_uid, plane.pln_range); putplane(plane.pln_uid, &plane); } return RET_OK; }
int qorde(void) { int nships = 0; int i; struct nstr_item nb; struct shpstr ship; if (!snxtitem(&nb, EF_SHIP, player->argp[1], NULL)) return RET_SYN; while (nxtitem(&nb, (&ship))) { if (!player->owner || ship.shp_own == 0) continue; if (!(ship.shp_autonav & AN_AUTONAV) && (!opt_SAIL || !ship.shp_path[0])) continue; if (!nships) { /* 1st ship, print banner */ if (player->god) pr("own "); pr("shp# ship type "); pr("[Starting] (Ending) \n"); } nships++; if (player->god) pr("%3d ", ship.shp_own); pr("%4d", nb.cur); pr(" %-16.16s", mchr[(int)ship.shp_type].m_name); if (ship.shp_autonav & AN_AUTONAV) { pr(" ["); for (i = 0; i < TMAX; i++) prhold(i, ship.shp_tend[i], ship.shp_lend[i]); pr("] , ("); for (i = 0; i < TMAX; i++) prhold(i, ship.shp_tstart[i], ship.shp_lstart[i]); pr(")"); if (ship.shp_autonav & AN_SCUTTLE) pr(" scuttling"); pr("\n"); } else pr(" has a sail path\n"); if (ship.shp_name[0] != 0) { if (player->god) pr(" "); pr(" %s\n", ship.shp_name); } } if (!nships) { if (player->argp[1]) pr("%s: No ship(s)\n", player->argp[1]); else pr("%s: No ship(s)\n", ""); return RET_FAIL; } else pr("%d ship%s\n", nships, splur(nships)); return RET_OK; }
int nuke(void) { int nnukes, noff; struct nstr_item nstr; struct nukstr nuk; struct plnstr plane; if (!snxtitem(&nstr, EF_NUKE, player->argp[1], NULL)) return RET_SYN; nnukes = noff = 0; while (nxtitem(&nstr, &nuk)) { if (!player->owner || nuk.nuk_own == 0) continue; if (nnukes++ == 0) { if (player->god) pr("own "); pr(" # nuke type x,y s eff tech carry burst\n"); } if (nuk.nuk_off) noff++; if (player->god) pr("%-3d ", nuk.nuk_own); pr("%4d %-19.19s ", nstr.cur, nchr[(int)nuk.nuk_type].n_name); prxy("%4d,%-4d", nuk.nuk_x, nuk.nuk_y); pr(" %1.1s %c%3d%% %4d", &nuk.nuk_stockpile, nuk.nuk_off ? '!' : ' ', nuk.nuk_effic, nuk.nuk_tech); if (nuk.nuk_plane >= 0) { getplane(nuk.nuk_plane, &plane); pr("%5dP %s", nuk.nuk_plane, plane.pln_flags & PLN_AIRBURST ? " air" : "ground"); } pr("\n"); } if (nnukes == 0) { if (player->argp[1]) pr("%s: No nuke(s)\n", player->argp[1]); else pr("%s: No nuke(s)\n", ""); return RET_FAIL; } else { pr("%d nuke%s", nnukes, splur(nnukes)); if (noff) pr(", %d stopped (eff marked with !)", noff); pr("\n"); } return RET_OK; }
int navi(void) { struct nstr_item ni_ship; struct emp_qelem ship_list; if (!snxtitem(&ni_ship, EF_SHIP, player->argp[1], NULL)) return RET_SYN; shp_sel(&ni_ship, &ship_list); if (QEMPTY(&ship_list)) { pr("No ships\n"); return RET_FAIL; } return unit_move(&ship_list); }
int march(void) { struct nstr_item ni_land; struct emp_qelem land_list; if (!snxtitem(&ni_land, EF_LAND, player->argp[1], NULL)) return RET_SYN; lnd_sel(&ni_land, &land_list); if (QEMPTY(&land_list)) { pr("No lands\n"); return RET_FAIL; } return unit_move(&land_list); }
int coun(void) { struct nstr_item ni; struct natstr nat; if (!snxtitem(&ni, EF_NATION, player->argp[1], NULL)) return RET_SYN; prdate(); pr(" # last access %sstatus country name\n", player->god ? "BTU " : ""); while (nxtitem(&ni, &nat)) { if (nat.nat_stat == STAT_UNUSED) continue; coun_list(&nat); } return RET_OK; }
int ndump(void) { struct nstr_item nstr; struct nukstr nuk; time_t now; int nnukes; if (!snxtitem(&nstr, EF_NUKE, player->argp[1], NULL)) return RET_SYN; prdate(); if (player->god) pr(" "); time(&now); pr("DUMP NUKES %ld\n", (long)now); if (player->god) pr("own "); pr("id x y num type\n"); nnukes = 0; while (nxtitem(&nstr, &nuk)) { if (!player->god && !player->owner) continue; if (nuk.nuk_own == 0) continue; nnukes++; if (player->god) pr("%d ", nuk.nuk_own); pr("%d ", nuk.nuk_uid); prxy("%d %d", nuk.nuk_x, nuk.nuk_y); pr(" %d", 1); pr(" %.5s", nchr[(int)nuk.nuk_type].n_name); pr("\n"); } if (nnukes == 0) { if (player->argp[1]) pr("%s: No nuke(s)\n", player->argp[1]); else pr("%s: No nuke(s)\n", ""); return RET_FAIL; } else pr("%d nuke%s\n", nnukes, splur(nnukes)); return RET_OK; }
int lsta(void) { int nunits; struct nstr_item ni; struct lndstr land; struct lchrstr *lcp; if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL)) return RET_SYN; nunits = 0; while (nxtitem(&ni, &land)) { if (!player->owner || land.lnd_own == 0) continue; lcp = lchr + land.lnd_type; if (nunits++ == 0) { pr(" %16.16s s v s r r a f a a\n", ""); pr(" %16.16s p i p a n c i m a\n", ""); pr("lnd# %16.16s x,y eff tech att def vul d s y d g c r m f\n", "unit-type"); } pr("%4d %-16.16s ", land.lnd_uid, lcp->l_name); prxy("%4d,%-4d", land.lnd_x, land.lnd_y); pr(" %3d%% %3d %1.1f %1.1f %3d ", land.lnd_effic, land.lnd_tech, lnd_att(&land), lnd_def(&land), lnd_vul(&land)); pr("%2d %2d %2d %2d ", lnd_spd(&land), lnd_vis(&land), lcp->l_spy, lcp->l_rad); pr("%2d %2d %2d %2d %2d ", lnd_frg(&land), lnd_acc(&land), lnd_dam(&land), lcp->l_ammo, lnd_aaf(&land)); pr("\n"); } if (nunits == 0) { if (player->argp[1]) pr("%s: No unit(s)\n", player->argp[1]); else pr("%s: No unit(s)\n", ""); return RET_FAIL; } else pr("%d unit%s\n", nunits, splur(nunits)); return RET_OK; }
static void starv_units(char *range) { struct nstr_item ni; struct lndstr land; int nunit = 0; int s; if (!snxtitem(&ni, EF_LAND, range, NULL)) return; while (nxtitem(&ni, &land)) { if (!player->owner || !land.lnd_own) continue; s = famine_victims(land.lnd_item, etu_per_update); if (s == 0) continue; if (nunit++ == 0) unit_hdr(); if (player->god) pr("%3d ", land.lnd_own); pr("%5d ", land.lnd_uid); pr("%-16.16s ", lchr[(int)land.lnd_type].l_name); starv_people(land.lnd_item, s); } if (nunit == 0) { if (range) pr("%s: No unit(s)\n", range); else pr("%s: No unit(s)\n", ""); return; } else pr("%d unit%s\n", nunit, splur(nunit)); return; }
/* * format: fina */ int fina(void) { struct lonstr loan; struct nstr_item ni; time_t now; if (!opt_LOANS) { pr("Loans are not enabled.\n"); return RET_FAIL; } if (!snxtitem(&ni, EF_LOAN, "*", NULL)) return RET_SYN; (void)time(&now); pr("\n"); pr(" -= Empire Financial Status Report =-\n"); pr(" "); prdate(); pr("Loan From To Rate Dur Paid Total\n"); while (nxtitem(&ni, &loan)) { if (loan.l_status != LS_SIGNED) continue; pr(" %-2d (%3d) %-8.8s (%3d) %-8.8s ", ni.cur, loan.l_loner, cname(loan.l_loner), loan.l_lonee, cname(loan.l_lonee)); pr("%3d%% %3d %5d %7.0f", loan.l_irate, loan.l_ldur, loan.l_amtpaid, ceil(loan_owed(&loan, now))); if (now > loan.l_duedate) pr(" (in arrears)\n"); else pr("\n"); } pr("\n"); return RET_OK; }
static void starv_ships(char *range) { struct nstr_item ni; struct shpstr ship; int nship = 0; int s; if (!snxtitem(&ni, EF_SHIP, range, NULL)) return; while (nxtitem(&ni, &ship)) { if (!player->owner || !ship.shp_own) continue; s = famine_victims(ship.shp_item, etu_per_update); if (s == 0) continue; if (nship++ == 0) ship_hdr(); if (player->god) pr("%3d ", ship.shp_own); pr("%5d ", ship.shp_uid); pr("%-16.16s ", mchr[(int)ship.shp_type].m_name); starv_people(ship.shp_item, s); } if (nship == 0) { if (range) pr("%s: No ship(s)\n", range); else pr("%s: No ship(s)\n", ""); return; } else pr("%d ship%s\n", nship, splur(nship)); return; }
static int load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy, int load_unload, int *nunitsp) { struct nstr_item ni; struct lndstr land; int loaded = 0; char *p; char prompt[512]; char buf[1024]; if (load_unload == LOAD && lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) { if (noisy) { if (lchr[lp->lnd_type].l_nland) pr("%s doesn't have room for any more land units!\n", prland(lp)); else pr("%s cannot carry land units!\n", prland(lp)); } return 0; } sprintf(prompt, "Land unit(s) to %s %s? ", load_unload == LOAD ? "load onto" : "unload from", prland(lp)); p = getstarg(player->argp[3], prompt, buf); if (!p) return RET_SYN; if (!snxtitem(&ni, EF_LAND, p, NULL)) return RET_SYN; if (!still_ok_land(sectp, lp)) return RET_SYN; if (noisy && p && *p) noisy = isdigit(*p); while (nxtitem(&ni, &land)) { if (!player->owner) continue; if (load_unload == LOAD) { if (land.lnd_ship > -1) { if (noisy) pr("%s is already on ship #%d!\n", prland(&land), land.lnd_ship); continue; } if (land.lnd_land > -1) { if (noisy) pr("%s is already on land #%d!\n", prland(&land), land.lnd_land); continue; } if (lnd_first_on_land(&land) >= 0) { if (noisy) pr("%s cannot be loaded since it is carrying units\n", prland(&land)); continue; } if (land.lnd_uid == lp->lnd_uid) { if (noisy) pr("%s can't be loaded onto itself!\n", prland(&land)); continue; } if (lchr[(int)land.lnd_type].l_flags & (L_HEAVY | L_TRAIN)) { if (noisy) pr("%s is too heavy to load.\n", prland(&land)); continue; } } /* Unit sanity done */ /* Find the right ship */ if (load_unload == UNLOAD) { if (land.lnd_land != lp->lnd_uid) continue; if (land.lnd_ship > -1) continue; } else if (lp->lnd_x != land.lnd_x || lp->lnd_y != land.lnd_y) continue; /* Fit unit on ship */ if (load_unload == LOAD) { if (lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) { if (noisy) { if (lchr[lp->lnd_type].l_nland) pr("%s doesn't have room for any more land units!\n", prland(lp)); else pr("%s cannot carry land units!\n", prland(lp)); } break; } sprintf(buf, "loaded on your %s at %s", prland(lp), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own)); gift(lp->lnd_own, player->cnum, &land, buf); land.lnd_land = lp->lnd_uid; land.lnd_harden = 0; putland(land.lnd_uid, &land); #if 0 /* FIXME same issue as in load_land_ship() */ if (!lnd_supply_all(&land)) pr("WARNING: %s is out of supply!\n", prland(&land)); #else if (!lnd_in_supply(&land)) pr("WARNING: %s is out of supply!\n", prland(&land)); #endif } else { sprintf(buf, "unloaded in your %s at %s", dchr[sectp->sct_type].d_name, xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own)); gift(sectp->sct_own, player->cnum, &land, buf); land.lnd_land = -1; putland(land.lnd_uid, &land); } pr("%s %s %s at %s.\n", prland(&land), (load_unload == UNLOAD) ? "unloaded from" : "loaded onto", prland(lp), xyas(lp->lnd_x, lp->lnd_y, player->cnum)); loaded = 1; } *nunitsp += loaded; return 0; }
static int load_plane_land(struct sctstr *sectp, struct lndstr *lp, int noisy, int load_unload, int *nunitsp) { struct nstr_item ni; struct plnstr pln; int loaded = 0; char *p; char prompt[512]; char buf[1024]; struct lchrstr *lcp = lchr + lp->lnd_type; if (!lcp->l_nxlight) { if (noisy) pr("%s cannot carry extra-light planes.\n", prland(lp)); return 0; } if (load_unload == LOAD && lnd_nxlight(lp) >= lcp->l_nxlight) { if (noisy) pr("%s doesn't have room for any more extra-light planes\n", prland(lp)); return 0; } sprintf(prompt, "Plane(s) to %s %s? ", load_unload == LOAD ? "load onto" : "unload from", prland(lp)); p = getstarg(player->argp[3], prompt, buf); if (!p) return RET_SYN; if (!snxtitem(&ni, EF_PLANE, p, NULL)) return RET_SYN; if (!still_ok_land(sectp, lp)) return RET_SYN; if (noisy && p && *p) noisy = isdigit(*p); while (nxtitem(&ni, &pln)) { if (!player->owner) continue; if (!(plchr[(int)pln.pln_type].pl_flags & P_E)) { if (noisy) pr("You can only load xlight planes onto units.\n"); continue; } if (load_unload == LOAD && pln.pln_ship > -1) { if (noisy) pr("%s is already on ship #%d!\n", prplane(&pln), pln.pln_ship); continue; } if (load_unload == LOAD && pln.pln_land > -1) { if (noisy) pr("%s is already on unit #%d!\n", prplane(&pln), pln.pln_land); continue; } if (pln.pln_harden != 0) { if (noisy) pr("%s has been hardened and can't be loaded\n", prplane(&pln)); continue; } /* Plane sanity done */ /* Find the right unit */ if (load_unload == UNLOAD) { if (pln.pln_land != lp->lnd_uid) continue; } else if (lp->lnd_x != pln.pln_x || lp->lnd_y != pln.pln_y) continue; /* Fit plane on unit */ if (load_unload == LOAD) { if (!put_plane_on_land(&pln, lp)) { if (noisy) pr("Can't put plane %d on this unit!\n", pln.pln_uid); continue; } sprintf(buf, "loaded on %s at %s", prland(lp), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own)); gift(lp->lnd_own, player->cnum, &pln, buf); putplane(pln.pln_uid, &pln); } else { pln.pln_land = -1; sprintf(buf, "unloaded at your sector at %s", xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own)); gift(sectp->sct_own, player->cnum, &pln, buf); putplane(pln.pln_uid, &pln); } pr("%s %s %s at %s.\n", prplane(&pln), (load_unload == UNLOAD) ? "unloaded from" : "loaded onto", prland(lp), xyas(lp->lnd_x, lp->lnd_y, player->cnum)); loaded = 1; } *nunitsp += loaded; return 0; }
int load(void) { int noisy; int load_unload; int type; struct nstr_item nbst; struct ichrstr *ich; int nships; struct sctstr sect; struct shpstr ship; int retval; char *p; char buf[1024]; p = getstarg(player->argp[1], "What commodity (or 'plane' or 'land')? ", buf); if (!p || !*p) return RET_SYN; if (!strncmp(p, "plane", 5)) type = EF_PLANE; else if (!strncmp(p, "land", 4)) type = EF_LAND; else if (NULL != (ich = item_by_name(p))) type = EF_SECTOR; else { pr("Can't load '%s'\n", p); return RET_SYN; } p = getstarg(player->argp[2], "Ship(s): ", buf); if (!p || !*p) return RET_SYN; noisy = isdigit(*p); if (!snxtitem(&nbst, EF_SHIP, p, NULL)) return RET_SYN; load_unload = **player->argp == 'l' ? LOAD : UNLOAD; nships = 0; while (nxtitem(&nbst, &ship)) { if (!ship.shp_own) continue; if (!player->owner) { if (load_unload == UNLOAD || !noisy) continue; if (relations_with(ship.shp_own, player->cnum) < FRIENDLY) continue; } if (!getsect(ship.shp_x, ship.shp_y, §)) /* XXX */ continue; if (!sect.sct_own) continue; if (!player->owner) { if (ship.shp_own != player->cnum) continue; if (!sect_has_dock(§)) continue; if (load_unload == LOAD) { if (noisy) pr("You don't own %s\n", xyas(sect.sct_x, sect.sct_y, player->cnum)); continue; } } if (!sect_has_dock(§)) { if (noisy) pr("Sector %s is not a harbor or canal.\n", xyas(sect.sct_x, sect.sct_y, player->cnum)); continue; } if (load_unload == UNLOAD && !player->owner && relations_with(sect.sct_own, player->cnum) < FRIENDLY) { if (noisy) pr("You can't unload into an unfriendly %s\n", dchr[sect.sct_type].d_name); continue; } if (sect.sct_effic < 2) { if (noisy) pr("The %s at %s is not 2%% efficient yet.\n", dchr[sect.sct_type].d_name, xyas(sect.sct_x, sect.sct_y, player->cnum)); continue; } if (opt_MARKET) { if (ontradingblock(EF_SHIP, &ship)) { pr("You cannot load/unload an item on the trading block!\n"); continue; } } switch (type) { case EF_PLANE: retval = load_plane_ship(§, &ship, noisy, load_unload, &nships); if (retval != 0) return retval; break; case EF_LAND: retval = load_land_ship(§, &ship, noisy, load_unload, &nships); if (retval != 0) return retval; break; case EF_SECTOR: retval = load_comm_ship(§, &ship, ich, load_unload, &nships); if (retval != 0) return retval; } /* load/unload plague */ if (sect.sct_pstage == PLG_INFECT && ship.shp_pstage == PLG_HEALTHY) ship.shp_pstage = PLG_EXPOSED; if (ship.shp_pstage == PLG_INFECT && sect.sct_pstage == PLG_HEALTHY) sect.sct_pstage = PLG_EXPOSED; putsect(§); putship(ship.shp_uid, &ship); } if (!nships) pr("No ships affected\n"); else pr("%d ship%s %sloaded\n", nships, splur(nships), load_unload == UNLOAD ? "un" : ""); return RET_OK; }
static int load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy, int load_unload, int *nshipsp) { struct nstr_item ni; struct lndstr land; int loaded = 0; char *p; char prompt[512]; char buf[1024]; int load_spy = 0; if (load_unload == LOAD) { if ((mchr[(int)sp->shp_type].m_flags & M_SUB) && (mchr[(int)sp->shp_type].m_nland == 0)) { if (shp_nland(sp) >= 2) { pr("Non-land unit carrying subs can only carry up to two spy units.\n"); return 0; } /* Eh, let 'em load a spy only */ load_spy = 1; } if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) { if (noisy) { if (mchr[(int)sp->shp_type].m_nland) pr("%s doesn't have room for any more land units!\n", prship(sp)); else pr("%s cannot carry land units!\n", prship(sp)); } return 0; } } sprintf(prompt, "Land unit(s) to %s %s? ", load_unload == LOAD ? "load onto" : "unload from", prship(sp)); p = getstarg(player->argp[3], prompt, buf); if (!p) return RET_SYN; if (!snxtitem(&ni, EF_LAND, p, NULL)) return RET_SYN; if (!still_ok_ship(sectp, sp)) return RET_SYN; if (noisy && p && *p) noisy = isdigit(*p); while (nxtitem(&ni, &land)) { if (!player->owner) continue; if (load_unload == LOAD) { if (land.lnd_ship > -1) { if (noisy) pr("%s is already on ship #%d!\n", prland(&land), land.lnd_ship); continue; } if (land.lnd_land > -1) { if (noisy) pr("%s is already on land #%d!\n", prland(&land), land.lnd_land); continue; } if (lnd_first_on_land(&land) >= 0) { if (noisy) pr("%s cannot be loaded since it is carrying units\n", prland(&land)); continue; } if (lchr[(int)land.lnd_type].l_flags & L_HEAVY) { if (noisy) pr("%s is too heavy to load.\n", prland(&land)); continue; } if (load_spy && !(lchr[(int)land.lnd_type].l_flags & L_SPY)) { if (noisy) pr("Subs can only carry spy units.\n"); continue; } } /* Unit sanity done */ /* Find the right ship */ if (load_unload == UNLOAD) { if (land.lnd_ship != sp->shp_uid) continue; if (land.lnd_land > -1) continue; } else if (sp->shp_x != land.lnd_x || sp->shp_y != land.lnd_y) continue; if ((!(lchr[(int)land.lnd_type].l_flags & L_LIGHT)) && (!((mchr[(int)sp->shp_type].m_flags & M_SUPPLY) && (!(mchr[(int)sp->shp_type].m_flags & M_SUB))))) { if (noisy) { pr("You can only load light units onto ships,\n"); pr("unless the ship is a non-sub supply ship\n"); pr("%s not loaded\n", prland(&land)); } continue; } /* Fit unit on ship */ if (load_unload == LOAD) { /* We have to check again, since it may have changed */ if ((mchr[(int)sp->shp_type].m_flags & M_SUB) && (mchr[(int)sp->shp_type].m_nland == 0)) { if (shp_nland(sp) >= 2) { pr("Non-land unit carrying subs can only carry up to two spy units.\n"); return 0; } /* Eh, let 'em load a spy only */ load_spy = 1; } if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) { if (noisy) { if (mchr[(int)sp->shp_type].m_nland) pr("%s doesn't have room for any more land units!\n", prship(sp)); else pr("%s cannot carry land units!\n", prship(sp)); } return 0; } sprintf(buf, "loaded on your %s at %s", prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own)); gift(sp->shp_own, player->cnum, &land, buf); land.lnd_ship = sp->shp_uid; land.lnd_harden = 0; putland(land.lnd_uid, &land); #if 0 /* * FIXME if this supplies from the sector, the putsect in * load() / lload() duplicates those supplies, causing a * seqno mismatch */ if (!lnd_supply_all(&land)) pr("WARNING: %s is out of supply!\n", prland(&land)); #else if (!lnd_in_supply(&land)) pr("WARNING: %s is out of supply!\n", prland(&land)); #endif } else { sprintf(buf, "unloaded in your %s at %s", dchr[sectp->sct_type].d_name, xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own)); /* Spies are unloaded quietly, others aren't */ if (!(lchr[(int)land.lnd_type].l_flags & L_SPY)) gift(sectp->sct_own, player->cnum, &land, buf); land.lnd_ship = -1; putland(land.lnd_uid, &land); } pr("%s %s %s at %s.\n", prland(&land), (load_unload == UNLOAD) ? "unloaded from" : "loaded onto", prship(sp), xyas(sp->shp_x, sp->shp_y, player->cnum)); loaded = 1; } *nshipsp += loaded; return 0; }
static int load_plane_ship(struct sctstr *sectp, struct shpstr *sp, int noisy, int load_unload, int *nshipsp) { struct nstr_item ni; struct plnstr pln; int loaded = 0; char buf[1024]; char *p; char prompt[512]; struct mchrstr *mcp = mchr + sp->shp_type; if (mcp->m_nplanes + mcp->m_nchoppers + mcp->m_nxlight == 0) { if (noisy) pr("%s cannot carry planes\n", prship(sp)); return 0; } if (load_unload == LOAD && shp_nplane(sp, NULL, NULL, NULL) >= mcp->m_nchoppers + mcp->m_nxlight + mcp->m_nplanes) { if (noisy) pr("%s doesn't have room for any more planes\n", prship(sp)); return 0; } sprintf(prompt, "Plane(s) to %s %s? ", load_unload == LOAD ? "load onto" : "unload from", prship(sp)); p = getstarg(player->argp[3], prompt, buf); if (!p) return RET_SYN; if (!snxtitem(&ni, EF_PLANE, p, NULL)) return RET_SYN; if (!still_ok_ship(sectp, sp)) return RET_SYN; if (noisy && p && *p) noisy = isdigit(*p); while (nxtitem(&ni, &pln)) { if (!player->owner) continue; if (!(plchr[(int)pln.pln_type].pl_flags & P_L) && !(plchr[(int)pln.pln_type].pl_flags & P_E) && !(plchr[(int)pln.pln_type].pl_flags & P_K) && !(plchr[(int)pln.pln_type].pl_flags & P_M) ) { if (noisy) pr("You can only load light planes, helos, xtra-light, or missiles onto ships.\n"); continue; } if (load_unload == LOAD && pln.pln_ship > -1) { if (noisy) pr("%s is already on ship #%d!\n", prplane(&pln), pln.pln_ship); continue; } if (load_unload == LOAD && pln.pln_land > -1) { if (noisy) pr("%s is already on land unit #%d!\n", prplane(&pln), pln.pln_land); continue; } if (pln.pln_harden != 0) { if (noisy) pr("%s has been hardened and can't be loaded\n", prplane(&pln)); continue; } if (load_unload == UNLOAD) { if (pln.pln_ship != sp->shp_uid) continue; } else if (sp->shp_x != pln.pln_x || sp->shp_y != pln.pln_y) continue; if (!could_be_on_ship(&pln, sp)) { if (noisy) { if (plchr[(int)pln.pln_type].pl_flags & P_K) p = "choppers"; else if (plchr[(int)pln.pln_type].pl_flags & P_E) p = "extra light planes"; else if (plchr[(int)pln.pln_type].pl_flags & P_M) p = "missiles"; else p = "planes"; pr("%s cannot carry %s.\n", prship(sp), p); } continue; } /* Fit plane on ship */ if (load_unload == LOAD) { if (!put_plane_on_ship(&pln, sp)) { if (noisy) pr("Can't put plane %d on this ship!\n", pln.pln_uid); continue; } sprintf(buf, "loaded on your %s at %s", prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own)); gift(sp->shp_own, player->cnum, &pln, buf); putplane(pln.pln_uid, &pln); } else { pln.pln_ship = -1; sprintf(buf, "unloaded in your %s at %s", dchr[sectp->sct_type].d_name, xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own)); gift(sectp->sct_own, player->cnum, &pln, buf); putplane(pln.pln_uid, &pln); } pr("%s %s %s at %s.\n", prplane(&pln), (load_unload == UNLOAD) ? "unloaded from" : "loaded onto", prship(sp), xyas(sp->shp_x, sp->shp_y, player->cnum)); loaded = 1; } *nshipsp += loaded; return 0; }
int lload(void) { int noisy; int load_unload; int type; struct nstr_item nbst; struct ichrstr *ich; int nunits; struct sctstr sect; struct lndstr land; int retval; char *p; char buf[1024]; p = getstarg(player->argp[1], "What commodity (or 'plane' or 'land')? ", buf); if (!p || !*p) return RET_SYN; if (!strncmp(p, "plane", 5)) type = EF_PLANE; else if (!strncmp(p, "land", 4)) type = EF_LAND; else if (NULL != (ich = item_by_name(p))) type = EF_SECTOR; else { pr("Can't load '%s'\n", p); return RET_SYN; } p = getstarg(player->argp[2], "Unit(s): ", buf); if (!p || !*p) return RET_SYN; noisy = isdigit(*p); if (!snxtitem(&nbst, EF_LAND, p, NULL)) return RET_SYN; load_unload = player->argp[0][1] == 'l' ? LOAD : UNLOAD; nunits = 0; while (nxtitem(&nbst, &land)) { if (land.lnd_own == 0) continue; if (!player->owner) { if (load_unload == UNLOAD || !noisy) continue; if (relations_with(land.lnd_own, player->cnum) != ALLIED) continue; } if (!getsect(land.lnd_x, land.lnd_y, §)) /* XXX */ continue; if (!player->owner) { if (land.lnd_own != player->cnum) continue; if (load_unload == LOAD) { if (noisy) pr("Sector %s is not yours.\n", xyas(sect.sct_x, sect.sct_y, player->cnum)); continue; } if (relations_with(sect.sct_own, player->cnum) != ALLIED) { pr("Sector %s is not yours.\n", xyas(sect.sct_x, sect.sct_y, player->cnum)); continue; } } if (opt_MARKET) { if (ontradingblock(EF_LAND, &land)) { pr("You cannot load/unload an item on the trading block!\n"); continue; } } switch (type) { case EF_LAND: retval = load_land_land(§, &land, noisy, load_unload, &nunits); if (retval != 0) return retval; break; case EF_PLANE: retval = load_plane_land(§, &land, noisy, load_unload, &nunits); if (retval != 0) return retval; break; case EF_SECTOR: retval = load_comm_land(§, &land, ich, load_unload, &nunits); if (retval != 0) return retval; } /* load/unload plague */ if (sect.sct_pstage == PLG_INFECT && land.lnd_pstage == PLG_HEALTHY) land.lnd_pstage = PLG_EXPOSED; if (land.lnd_pstage == PLG_INFECT && sect.sct_pstage == PLG_HEALTHY) sect.sct_pstage = PLG_EXPOSED; putsect(§); putland(land.lnd_uid, &land); } if (nunits == 0) pr("No units affected\n"); else pr("%d unit%s %sloaded\n", nunits, splur(nunits), load_unload == UNLOAD ? "un" : ""); return RET_OK; }
/* * format: set <type> <SHIP/NUKE> <PRICE> */ int set(void) { static int ef_saleable[] = { EF_SHIP, EF_PLANE, EF_LAND, EF_NUKE, EF_BAD }; char *p; int type; int price; char prompt[80]; struct trdstr trade; struct nstr_item ni; struct nstr_item ni_trade; union empobj_storage item; struct sctstr sect; int freeslot; int foundslot; int id; time_t now; char buf[1024]; if (!opt_MARKET) { pr("The market is disabled.\n"); return RET_FAIL; } check_market(); check_trade(); p = getstarg(player->argp[1], "Ship, plane, land unit or nuke? ", buf); if (!p) return RET_SYN; if ((type = ef_byname_from(p, ef_saleable)) < 0) { pr("You can sell only ships, planes, land units or nukes\n"); return RET_SYN; } if (!snxtitem(&ni, type, player->argp[2], NULL)) return RET_SYN; while (nxtitem(&ni, &item)) { if (!player->owner && !player->god) continue; getsect(item.gen.x, item.gen.y, §); if (!military_control(§)) { pr("Military control required to sell goods.\n"); return RET_FAIL; } trade.trd_type = type; sprintf(prompt, "%s #%d; price? ", trade_nameof(&trade, &item.gen), ni.cur); if (!(p = getstarg(player->argp[3], prompt, buf))) return RET_FAIL; if (!check_obj_ok(&item.gen)) return RET_FAIL; if ((price = atoi(p)) < 0) continue; foundslot = -1; freeslot = -1; snxtitem_all(&ni_trade, EF_TRADE); while (nxtitem(&ni_trade, &trade)) { if (trade.trd_owner == 0) freeslot = ni_trade.cur; if (trade.trd_unitid == ni.cur && trade.trd_type == type) { foundslot = ni_trade.cur; break; } } if (price <= 0) { if (foundslot >= 0) { pr("%s #%d (lot #%d) removed from trading\n", trade_nameof(&trade, &item.gen), ni.cur, foundslot); trade.trd_owner = 0; puttrade(ni_trade.cur, &trade); } } else { if (trade_has_unsalable_cargo(&item.gen, 1)) return RET_FAIL; if (foundslot >= 0) id = foundslot; else if (freeslot >= 0) id = freeslot; else id = ni_trade.cur; ef_blank(EF_TRADE, id, &trade); trade.trd_x = 1; trade.trd_y = 0; trade.trd_type = type; trade.trd_owner = player->cnum; trade.trd_unitid = ni.cur; trade.trd_price = price; (void)time(&now); trade.trd_markettime = now; trade.trd_maxbidder = player->cnum; puttrade(id, &trade); pr("%s #%d (lot #%d) price %s to $%d\n", trade_nameof(&trade, &item.gen), ni.cur, id, foundslot >= 0 ? "reset" : "set", price); } } return RET_OK; }
int tend(void) { struct nstr_item targets; struct nstr_item tenders; struct shpstr tender; struct shpstr target; struct ichrstr *ip; struct mchrstr *vbase; int amt; int retval; int ontender; int ontarget; int maxtender; int maxtarget; int transfer; int total; int type; char *p; char prompt[512]; char buf[1024]; p = getstarg(player->argp[1], "Tend what commodity (or 'land')? ", buf); if (!p || !*p) return RET_SYN; if (!strncmp(p, "land", 4)) type = EF_LAND; else if (NULL != (ip = item_by_name(p))) type = EF_SECTOR; else { pr("Can't tend '%s'\n", p); return RET_SYN; } if (!snxtitem(&tenders, EF_SHIP, player->argp[2], "Tender(s)? ")) return RET_SYN; while (nxtitem(&tenders, &tender)) { if (!player->owner) continue; if (type == EF_LAND) { sprintf(prompt, "Land unit(s) to tend from %s? ", prship(&tender)); p = getstarg(player->argp[3], prompt, buf); if (!p) return RET_FAIL; if (!*p) continue; if (!check_ship_ok(&tender)) return RET_SYN; if (0 != (retval = tend_land(&tender, p))) return retval; continue; } sprintf(prompt, "Number of %s to tend from %s? ", ip->i_name, prship(&tender)); p = getstarg(player->argp[3], prompt, buf); if (!p) return RET_FAIL; if (!*p) continue; if (!check_ship_ok(&tender)) return RET_SYN; if (!(amt = atoi(p))) { pr("Amount must be non-zero!\n"); return RET_SYN; } ontender = tender.shp_item[ip->i_uid]; if (ontender == 0 && amt > 0) { pr("No %s on %s\n", ip->i_name, prship(&tender)); return RET_FAIL; } vbase = &mchr[(int)tender.shp_type]; maxtender = vbase->m_item[ip->i_uid]; if (maxtender == 0) { pr("A %s cannot hold any %s\n", mchr[(int)tender.shp_type].m_name, ip->i_name); break; } if (!snxtitem(&targets, EF_SHIP, player->argp[4], "Ships to be tended? ")) return RET_FAIL; if (!check_ship_ok(&tender)) return RET_SYN; total = 0; while (nxtitem(&targets, &target)) { if (!player->owner && relations_with(target.shp_own, player->cnum) < FRIENDLY) continue; if (target.shp_uid == tender.shp_uid) continue; if (tender.shp_x != target.shp_x || tender.shp_y != target.shp_y) continue; if (ip->i_uid == I_CIVIL && tender.shp_own != target.shp_own) continue; ontarget = target.shp_item[ip->i_uid]; vbase = &mchr[(int)target.shp_type]; maxtarget = vbase->m_item[ip->i_uid]; if (amt < 0) { /* take from target and give to tender */ if (!player->owner) continue; if (ontarget == 0) { pr("No %s on %s\n", ip->i_name, prship(&target)); continue; } transfer = MIN(ontarget, -amt); transfer = MIN(maxtender - ontender, transfer); if (transfer == 0) continue; target.shp_item[ip->i_uid] = ontarget - transfer; ontender += transfer; total += transfer; } else { /* give to target from tender */ transfer = MIN(ontender, amt); transfer = MIN(transfer, maxtarget - ontarget); if (transfer == 0) continue; target.shp_item[ip->i_uid] = ontarget + transfer; ontender -= transfer; total += transfer; if (transfer && target.shp_own != player->cnum) { wu(0, target.shp_own, "%s tended %d %s to %s\n", cname(player->cnum), total, ip->i_name, prship(&target)); } } expose_ship(&tender, &target); putship(target.shp_uid, &target); if (amt > 0 && ontender == 0) { pr("%s out of %s\n", prship(&tender), ip->i_name); break; } } pr("%d total %s transferred %s %s\n", total, ip->i_name, (amt > 0) ? "off of" : "to", prship(&tender)); tender.shp_item[ip->i_uid] = ontender; tender.shp_mission = 0; putship(tender.shp_uid, &tender); } return RET_OK; }
int sona(void) { struct nstr_item ni, nit; struct sctstr sect; struct shpstr ship; struct shpstr targ; struct natstr *natp; struct mchrstr *mcp; struct mchrstr *tmcp; struct nstr_sect ns; int range; int visib, pingrange; int srange; int vrange; int dist; int x, y; int cx, cy; int changed = 0; int row; /* Where these are used are non-re-entrant, so we keep 'em around */ static char **rad = NULL; static char *radbuf = NULL; static signed char **vis = NULL; static signed char *visbuf = NULL; if (!snxtitem(&ni, EF_SHIP, player->argp[1], NULL)) return RET_SYN; if (!radbuf) radbuf = malloc(WORLD_Y * MAPWIDTH(1)); if (!visbuf) visbuf = malloc(WORLD_Y * MAPWIDTH(1)); if (!rad && radbuf) { rad = malloc(WORLD_Y * sizeof(char *)); if (rad) { for (x = 0; x < WORLD_Y; x++) { rad[x] = &radbuf[(WORLD_X + 1) * x]; } } } if (!vis && visbuf) { vis = malloc(WORLD_Y * sizeof(signed char *)); if (vis) { for (x = 0; x < WORLD_Y; x++) { vis[x] = &visbuf[(WORLD_X + 1) * x]; } } } if (!radbuf || !visbuf || !rad || !vis) { pr("Memory error, tell the deity.\n"); logerror("malloc failed in sona\n"); return RET_FAIL; } while (nxtitem(&ni, &ship)) { if (!player->owner) continue; mcp = &mchr[(int)ship.shp_type]; if (!(mcp->m_flags & M_SONAR)) continue; getsect(ship.shp_x, ship.shp_y, §); if (sect.sct_type != SCT_WATER) continue; range = (int)techfact(ship.shp_tech, mcp->m_vrnge); srange = MIN(7, 7 * range * ship.shp_effic / 200); pr("%s at %s efficiency %d%%, max range %d\n", prship(&ship), xyas(ship.shp_x, ship.shp_y, player->cnum), ship.shp_effic, srange); snxtsct_dist(&ns, ship.shp_x, ship.shp_y, srange); blankfill(radbuf, &ns.range, 1); while (nxtsct(&ns, §)) { if (player->owner || sect.sct_type == SCT_WATER) rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem; else { rad[ns.dy][ns.dx] = '?'; } } snxtsct_dist(&ns, ship.shp_x, ship.shp_y, srange); cx = deltx(&ns.range, ship.shp_x); cy = delty(&ns.range, ship.shp_y); while (nxtsct(&ns, §)) { if (!line_of_sight(rad, cx, cy, ns.dx, ns.dy)) { rad[ns.dy][ns.dx] = ' '; continue; } if (ship.shp_tech >= 310 && sect.sct_type == SCT_WATER) { if (sect.sct_mines) { pr("Sonar detects %d mines in %s!\n", sect.sct_mines, xyas(sect.sct_x, sect.sct_y, player->cnum)); rad[ns.dy][ns.dx] = 'X'; } } changed |= map_set(player->cnum, sect.sct_x, sect.sct_y, rad[ns.dy][ns.dx], 0); } memset(visbuf, 0, (WORLD_Y * (WORLD_X + 1))); snxtitem_dist(&nit, EF_SHIP, ship.shp_x, ship.shp_y, range); while (nxtitem(&nit, &targ)) { if (targ.shp_own == player->cnum || targ.shp_own == 0) continue; tmcp = &mchr[(int)targ.shp_type]; visib = shp_visib(&targ); pingrange = MIN(7, MAX(visib, 10) * range / 10); vrange = pingrange * ship.shp_effic / 200; dist = mapdist(targ.shp_x, targ.shp_y, ship.shp_x, ship.shp_y); pingrange = (MAX(pingrange, 2) * targ.shp_effic) / 100; if (dist > pingrange) continue; if (tmcp->m_flags & M_SONAR && targ.shp_own) { natp = getnatp(targ.shp_own); if (natp->nat_flags & NF_SONAR) wu(0, targ.shp_own, "Sonar ping from %s detected by %s!\n", xyas(ship.shp_x, ship.shp_y, targ.shp_own), prship(&targ)); if (targ.shp_rflags & RET_SONARED) retreat_ship(&targ, targ.shp_own, 's'); } if (dist > vrange) continue; x = deltx(&ns.range, (int)targ.shp_x); y = delty(&ns.range, (int)targ.shp_y); if (rad[y][x] != dchr[SCT_WATER].d_mnem && rad[y][x] != 'X') continue; if (tmcp->m_flags & M_SUB && relations_with(targ.shp_own, player->cnum) < FRIENDLY) { if (mcp->m_vrnge + visib < 8) pr("Sonar detects sub #%d @ %s\n", targ.shp_uid, xyas(targ.shp_x, targ.shp_y, player->cnum)); else if (mcp->m_vrnge + visib < 10) pr("Sonar detects %s @ %s\n", prship(&targ), xyas(targ.shp_x, targ.shp_y, player->cnum)); else pr("Sonar detects %s %s @ %s\n", cname(targ.shp_own), prship(&targ), xyas(targ.shp_x, targ.shp_y, player->cnum)); } else pr("Sonar detects %s %s @ %s\n", cname(targ.shp_own), prship(&targ), xyas(targ.shp_x, targ.shp_y, player->cnum)); if (visib > vis[y][x]) { vis[y][x] = visib; /* &~0x20 makes it a cap letter */ rad[y][x] = (*mchr[(int)targ.shp_type].m_name) & ~0x20; } } if (!player->argp[2]) { rad[cy][cx] = '0'; for (row = 0; row < ns.range.height; row++) if (!blankrow(rad[row])) pr("%s\n", rad[row]); } pr("\n"); } if (changed) writemap(player->cnum); return RET_OK; }
int work(void) { int nunits; struct nstr_item ni; struct sctstr sect; struct lndstr land; int work_amt, eff_amt, w; char *p; char buf[1024]; double cost; struct natstr *natp = getnatp(player->cnum); if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL)) return RET_SYN; p = getstarg(player->argp[2], "Amount: ", buf); if (!p || !*p) return RET_SYN; work_amt = atoi(p); if ((work_amt < 0) || (work_amt > land_mob_max)) { pr("Mobility used must be from 0 to %d\n", land_mob_max); return RET_FAIL; } nunits = 0; while (nxtitem(&ni, &land)) { if (!player->owner || land.lnd_own == 0) continue; if (!(lchr[(int)land.lnd_type].l_flags & L_ENGINEER)) continue; if (land.lnd_mobil <= 0) { pr("%s has no mobility!\n", prland(&land)); continue; } getsect(land.lnd_x, land.lnd_y, §); if (sect.sct_effic >= 100 && sect.sct_type == sect.sct_newtype) { pr("Nothing to do for %s in %s\n", prland(&land), xyas(sect.sct_x, sect.sct_y, player->cnum)); continue; } eff_amt = MIN(land.lnd_mobil, work_amt); w = (eff_amt * land.lnd_effic) / 600; if (w < 1) { pr("%s doesn't work enough to change efficiency (try increasing amount)\n", prland(&land)); continue; } cost = 0.0; w = buildeff(§, w, &cost); if (w == 0) { pr("%s can't change efficiency in %s\n", prland(&land), xyas(land.lnd_x, land.lnd_y, player->cnum)); continue; } if (player->dolcost + cost > natp->nat_money) { pr("You can't afford to work that much in %s!\n", xyas(land.lnd_x, land.lnd_y, player->cnum)); break; } player->dolcost += cost; land.lnd_mission = 0; land.lnd_mobil -= roundavg(w * 600.0 / land.lnd_effic); nunits++; pr("%s %s efficiency at %s to %d\n", prland(&land), sect.sct_type == sect.sct_newtype ? "raised" : "lowered", xyas(land.lnd_x, land.lnd_y, player->cnum), sect.sct_effic); putland(land.lnd_uid, &land); putsect(§); } if (nunits == 0) { if (player->argp[1]) pr("%s: No unit(s)\n", player->argp[1]); else pr("%s: No unit(s)\n", ""); return RET_FAIL; } else pr("%d unit%s\n", nunits, splur(nunits)); return RET_OK; }
int sabo(void) { struct nstr_item ni; struct lndstr land, tmp; struct sctstr sect; double odds; int dam; if (!snxtitem(&ni, EF_LAND, player->argp[1], NULL)) return RET_SYN; while (nxtitem(&ni, &land)) { if (!player->owner) continue; if (!(lchr[(int)land.lnd_type].l_flags & L_SPY)) { pr("%s is not a spy.\n", prland(&land)); continue; } if (land.lnd_ship >= 0) { pr("%s is on ship %d.\n", prland(&land), land.lnd_ship); continue; } if (land.lnd_land >= 0) { pr("%s is on unit %d.\n", prland(&land), land.lnd_land); continue; } if (!getsect(land.lnd_x, land.lnd_y, §)) continue; if (land.lnd_item[I_SHELL] == 0) { pr("%s has no shells.\n", prland(&land)); continue; } odds = LND_SPY_DETECT_CHANCE(land.lnd_effic); if (chance(odds)) { wu(0, sect.sct_own, "%s spy shot in %s during sabotage attempt.\n", cname(player->cnum), xyas(sect.sct_x, sect.sct_y, sect.sct_own)); pr("%s was shot and killed.\n", prland(&land)); land.lnd_effic = 0; putland(land.lnd_uid, &land); continue; } dam = lnd_sabo(&land, sect.sct_item); if (dam < 0) continue; pr("Explosion in %s causes %d damage.\n", xyas(land.lnd_x, land.lnd_y, player->cnum), dam); if (sect.sct_own) { wu(0, sect.sct_own, "Sabotage in sector %s caused %d damage.\n", xyas(sect.sct_x, sect.sct_y, sect.sct_own), dam); } /* hack: hide the spy so it don't gets blasted by sectdamage() */ tmp = land; tmp.lnd_own = 0; putland(land.lnd_uid, &tmp); land.lnd_seqno = tmp.lnd_seqno; sectdamage(§, dam); putsect(§); if (chance(odds)) { pr("%s dies in explosion.\n", prland(&land)); land.lnd_effic = 0; } putland(land.lnd_uid, &land); } return RET_OK; }
int pdump(void) { int nplanes; struct nstr_item np; struct plnstr plane; struct nukstr nuke; int field[128]; struct natstr *natp; int n, i; time_t now; if (!snxtitem(&np, EF_PLANE, player->argp[1], NULL)) return RET_SYN; prdate(); if (!player->argp[2]) { for (n = 1; n <= 32; n++) field[n - 1] = n; field[n - 1] = 0; } else { n = 2; i = 0; while (player->argp[n]) { if (!strcmp("type", player->argp[n])) { field[i++] = 1; } else if (!strcmp("x", player->argp[n])) { field[i++] = 2; } else if (!strcmp("y", player->argp[n])) { field[i++] = 3; } else if (!strcmp("wing", player->argp[n])) { field[i++] = 4; } else if (!strcmp("eff", player->argp[n])) { field[i++] = 5; } else if (!strcmp("mob", player->argp[n])) { field[i++] = 6; } else if (!strcmp("tech", player->argp[n])) { field[i++] = 7; } else if (!strcmp("att", player->argp[n])) { field[i++] = 8; } else if (!strcmp("def", player->argp[n])) { field[i++] = 9; } else if (!strcmp("acc", player->argp[n])) { field[i++] = 10; } else if (!strcmp("react", player->argp[n])) { field[i++] = 11; } else if (!strcmp("range", player->argp[n])) { field[i++] = 12; } else if (!strcmp("load", player->argp[n])) { field[i++] = 13; } else if (!strcmp("fuel", player->argp[n])) { field[i++] = 14; } else if (!strcmp("hard", player->argp[n])) { field[i++] = 15; } else if (!strcmp("ship", player->argp[n])) { field[i++] = 16; } else if (!strcmp("land", player->argp[n])) { field[i++] = 17; } else if (!strcmp("laun", player->argp[n])) { field[i++] = 18; } else if (!strcmp("orb", player->argp[n])) { field[i++] = 19; } else if (!strcmp("nuke", player->argp[n])) { field[i++] = 20; } else if (!strcmp("grd", player->argp[n])) { field[i++] = 21; } else { pr("Unrecognized field %s\n", player->argp[n]); } if (n++ > 100) { pr("Too many fields\n"); return RET_FAIL; } } field[i] = 0; } if (player->god) pr(" "); time(&now); pr("DUMP PLANES %ld\n", (long)now); if (player->god) pr("own "); pr("id"); n = 0; while (field[n]) { switch (field[n]) { case 1: pr(" type"); break; case 2: pr(" x"); break; case 3: pr(" y"); break; case 4: pr(" wing"); break; case 5: pr(" eff"); break; case 6: pr(" mob"); break; case 7: pr(" tech"); break; case 8: pr(" att"); break; case 9: pr(" def"); break; case 10: pr(" acc"); break; case 11: pr(" react"); break; case 12: pr(" range"); break; case 13: pr(" load"); break; case 14: pr(" fuel"); break; case 15: pr(" hard"); break; case 16: pr(" ship"); break; case 17: pr(" land"); break; case 18: pr(" laun"); break; case 19: pr(" orb"); break; case 20: pr(" nuke"); break; case 21: pr(" grd"); break; } n++; } pr("\n"); nplanes = 0; natp = getnatp(player->cnum); while (nxtitem(&np, &plane)) { if (!player->owner || plane.pln_own == 0) continue; nplanes++; if (player->god) pr("%d ", plane.pln_own); pr("%d", np.cur); n = 0; while (field[n]) { switch (field[n++]) { case 1: pr(" %.4s", plchr[(int)plane.pln_type].pl_name); break; case 2: pr(" %d", xrel(natp, plane.pln_x)); break; case 3: pr(" %d", yrel(natp, plane.pln_y)); break; case 4: pr(" %c", plane.pln_wing ? plane.pln_wing : '~'); break; case 5: pr(" %d", plane.pln_effic); break; case 6: pr(" %d", plane.pln_mobil); break; case 7: pr(" %d", plane.pln_tech); break; case 8: pr(" %d", pln_att(&plane)); break; case 9: pr(" %d", pln_def(&plane)); break; case 10: pr(" %d", pln_acc(&plane)); break; case 11: pr(" %d", plane.pln_range); break; case 12: pr(" %d", pln_range_max(&plane)); break; case 13: pr(" %d", pln_load(&plane)); break; case 14: pr(" %d", plchr[(int)plane.pln_type].pl_fuel); break; case 15: pr(" %d", plane.pln_harden); break; case 16: pr(" %d", plane.pln_ship); break; case 17: pr(" %d", plane.pln_land); break; case 18: pr(pln_is_in_orbit(&plane) ? " Y" : " N"); break; case 19: pr(pln_is_in_orbit(&plane) && (plane.pln_flags & PLN_SYNCHRONOUS) ? " Y" : " N"); break; case 20: if (getnuke(nuk_on_plane(&plane), &nuke)) { pr(" %.5s", nchr[nuke.nuk_type].n_name); break; } else pr(" N/A"); break; case 21: pr(" %c", plane.pln_flags & PLN_AIRBURST ? 'A' : 'G'); break; } } pr("\n"); } if (nplanes == 0) { if (player->argp[1]) pr("%s: No plane(s)\n", player->argp[1]); else pr("%s: No plane(s)\n", ""); return RET_FAIL; } else pr("%d plane%s\n", nplanes, splur(nplanes)); return RET_OK; }
static int tend_land(struct shpstr *tenderp, char *units) { struct nstr_item lni; struct nstr_item targets; struct shpstr target; struct lndstr land; char buf[1024]; if (!snxtitem(&lni, EF_LAND, units, NULL)) return RET_SYN; while (nxtitem(&lni, &land)) { if (!player->owner) continue; if (land.lnd_ship != tenderp->shp_uid) { pr("%s is not on %s!\n", prland(&land), prship(tenderp)); continue; } if (!(lchr[(int)land.lnd_type].l_flags & L_ASSAULT)) { pr("%s does not have \"assault\" capability and can't be tended\n", prland(&land)); continue; } if (!snxtitem(&targets, EF_SHIP, player->argp[4], "Ship to be tended? ")) return RET_FAIL; if (!check_ship_ok(tenderp) || !check_land_ok(&land)) return RET_SYN; while (nxtitem(&targets, &target)) { if (!player->owner && relations_with(target.shp_own, player->cnum) < FRIENDLY) continue; if (target.shp_uid == tenderp->shp_uid) continue; if (tenderp->shp_x != target.shp_x || tenderp->shp_y != target.shp_y) continue; /* Fit unit on ship */ getship(target.shp_uid, &target); if ((!(lchr[(int)land.lnd_type].l_flags & L_LIGHT)) && (!((mchr[(int)target.shp_type].m_flags & M_SUPPLY) && (!(mchr[(int)target.shp_type].m_flags & M_SUB))))) { pr("You can only load light units onto ships,\n" "unless the ship is a non-sub supply ship\n" "%s not tended\n", prland(&land)); continue; } if ((mchr[(int)target.shp_type].m_flags & M_SUB) && (lchr[(int)land.lnd_type].l_flags & L_SPY) && !mchr[(int)target.shp_type].m_nland) { if (shp_nland(&target) > 1) { pr("%s doesn't have room for more than two spy units!\n", prship(&target)); continue; } } else if (shp_nland(&target) >= mchr[target.shp_type].m_nland) { if (mchr[(int)target.shp_type].m_nland) pr("%s doesn't have room for any more land units!\n", prship(&target)); else pr("%s doesn't carry land units!\n", prship(&target)); continue; } pr("%s transferred from %s to %s\n", prland(&land), prship(tenderp), prship(&target)); sprintf(buf, "loaded on your %s at %s", prship(&target), xyas(target.shp_x, target.shp_y, target.shp_own)); gift(target.shp_own, player->cnum, &land, buf); land.lnd_ship = target.shp_uid; land.lnd_harden = 0; putland(land.lnd_uid, &land); expose_ship(tenderp, &target); putship(target.shp_uid, &target); putship(tenderp->shp_uid, tenderp); } } return 0; }