/* * 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; }
static void divine_load_unload(struct empobj *unit, int type, int uid, char *act) { if (uid < 0) return; pr("%s %s %s #%d\n", unit_nameof(unit), act, ef_nameof(type), uid); if (unit->own && unit->own != player->cnum) wu(0, unit->own, "%s %s %s #%d by an act of %s!\n", unit_nameof(unit), act, ef_nameof(type), uid, cname(player->cnum)); /* carrier owner could differ; can't be bothered to report to him */ }
/* * Drop cargo of @unit. * Give it to @newown, unless it's zero. */ void unit_drop_cargo(struct empobj *unit, natid newown) { int type; struct nstr_item ni; union empobj_storage cargo; for (type = EF_PLANE; type <= EF_NUKE; type++) { snxtitem_cargo(&ni, type, unit->ef_type, unit->uid); while (nxtitem(&ni, &cargo)) { switch (type) { case EF_PLANE: cargo.plane.pln_ship = cargo.plane.pln_land = -1; break; case EF_LAND: cargo.land.lnd_ship = cargo.land.lnd_land = -1; break; case EF_NUKE: cargo.nuke.nuk_plane = -1; break; } mpr(cargo.gen.own, "%s transferred off %s %d to %s\n", unit_nameof(&cargo.gen), ef_nameof(unit->ef_type), unit->uid, xyas(cargo.gen.x, cargo.gen.y, cargo.gen.own)); if (newown) unit_give_away(&cargo.gen, newown, cargo.gen.own); put_empobj(type, cargo.gen.uid, &cargo.gen); } } }
/* Extended dump command */ int xdump(void) { char *p; char buf[1024]; struct xdstr xd; struct natstr *natp; int type; int meta = 0; p = getstarg(player->argp[1], "Table name, or meta? ", buf); if (p && strcmp(p, "meta") == 0) { meta = 1; p = getstarg(player->argp[2], "Table name? ", buf); } if (!p || !*p) return RET_SYN; xdinit(&xd, player->cnum, 0, 0, pr); natp = getnatp(player->cnum); type = isdigit(p[0]) ? atoi(p) : ef_byname(p); if (type < 0 || type >= EF_MAX) return RET_SYN; if (meta) return xdmeta(&xd, type); if ((EF_IS_GAME_STATE(type) || EF_IS_VIEW(type)) && !(natp->nat_stat == STAT_ACTIVE || player->god)) { pr("Access to table %s denied\n", ef_nameof(type)); return RET_FAIL; } return xditem(&xd, type, player->argp[2]); }
/* * Dump meta-data for items of type @type to @xd. * Return RET_SYN when @type doesn't have meta-data, else RET_OK. */ static int xdmeta(struct xdstr *xd, int type) { struct castr *ca = ef_cadef(type); int i; int n = 0; if (!ca) return RET_SYN; xdhdr(xd, ef_nameof(type), 1); xdcolhdr(xd, ca); for (i = 0; ca[i].ca_name; i++) { if (ca[i].ca_flags & NSC_DEITY && !xd->divine) continue; if (ca[i].ca_dump == CA_DUMP_NONE) continue; xdflds(xd, mdchr_ca, &ca[i]); xd->pr("\n"); n++; } xdftr(xd, n); return RET_OK; }
static int verify_tabref(int type, int row, struct castr *ca, int idx, long val) { int tabno = ca->ca_table; struct castr *ca_sym = ef_cadef(tabno); int i; if (ca->ca_flags & NSC_BITS) { /* symbol set */ if (CANT_HAPPEN(ca_sym != symbol_ca)) return -1; for (i = 0; i < (int)sizeof(long) * 8; i++) { if (val & (1UL << i)) { if (!symbol_by_value(1L << i, ef_ptr(tabno, 0))) { verify_fail(type, row, ca, idx, "bit %d is not in symbol table %s", i, ef_nameof(tabno)); return -1; } } } } else if (ca_sym == symbol_ca) { /* symbol */ if (!symbol_by_value(val, ef_ptr(tabno, 0))) { verify_fail(type, row, ca, idx, "value %ld is not in symbol table %s", val, ef_nameof(tabno)); return -1; } } else { /* table index */ if (val >= ef_nelem(tabno) || val < -1) { verify_fail(type, row, ca, idx, "value %ld indexes table %s out of bounds 0..%d", val, ef_nameof(tabno), ef_nelem(tabno)); return -1; } /* laziness: assumes TABNO is EFF_MEM */ if (val >= 0 && !empobj_in_use(tabno, ef_ptr(tabno, val))) { verify_fail(type, row, ca, idx, "value %ld refers to missing element of table %s", val, ef_nameof(tabno)); return -1; } } return 0; }
static void verify_fail(int type, int row, struct castr *ca, int idx, char *fmt, ...) { int base = empfile[type].base < 0 ? type : empfile[type].base; va_list ap; fprintf(stderr, "%s %s uid %d", EF_IS_GAME_STATE(base) ? "File" : "Config", ef_nameof(type), row); if (ca) { fprintf(stderr, " field %s", ca->ca_name); if (CA_IS_ARRAY(ca)) fprintf(stderr, "(%d)", idx); } fprintf(stderr, ": "); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); putc('\n', stderr); }
int scra(void) { struct nstr_item ni; union empobj_storage item; int type, n; struct sctstr sect; struct mchrstr *mp; struct plchrstr *pp; struct lchrstr *lp; char *p; i_type i; char prompt[128]; char buf[1024]; float eff; short *mvec; int amt; if (!(p = getstarg(player->argp[1], "Ship, land, or plane? ", buf))) return RET_SYN; switch (*p) { case 's': type = EF_SHIP; break; case 'p': type = EF_PLANE; break; case 'l': type = EF_LAND; break; default: pr("Ships, land units, or planes only! (s, l, p)\n"); return RET_SYN; } if (!snxtitem(&ni, type, player->argp[2], NULL)) return RET_SYN; n = 0; while (nxtitem(&ni, &item)) { if (!player->owner) continue; n++; } snprintf(prompt, sizeof(prompt), "Really scrap %d %s%s [n]? ", n, ef_nameof(type), splur(n)); if (!confirm(prompt)) return RET_FAIL; snxtitem_rewind(&ni); while (nxtitem(&ni, &item)) { if (!player->owner) continue; if (opt_MARKET) { if (ontradingblock(type, &item.ship)) { pr("You cannot scrap an item on the trading block!\n"); continue; } } getsect(item.gen.x, item.gen.y, §); if (type == EF_SHIP) { if (!player->owner && relations_with(sect.sct_own, player->cnum) < FRIENDLY) { pr("%s is not in a friendly harbor!\n", prship(&item.ship)); continue; } if (sect.sct_type != SCT_HARBR || sect.sct_effic < 60) { pr("%s is not in a 60%% efficient harbor!\n", prship(&item.ship)); continue; } if (mchr[item.ship.shp_type].m_flags & M_TRADE) { pr("WARNING: You only collect money from trade ships if you \"scuttle\" them!\n"); sprintf(prompt, "Are you really sure that you want to scrap %s (n)? ", prship(&item.ship)); if (!confirm(prompt)) { pr("%s not scrapped\n", prship(&item.ship)); continue; } } } else { if (!player->owner && relations_with(sect.sct_own, player->cnum) != ALLIED) { pr("%s is not in an allied sector!\n", unit_nameof(&item.gen)); continue; } if (type == EF_PLANE && (sect.sct_type != SCT_AIRPT || sect.sct_effic < 60)) { pr("%s is not in a 60%% efficient airfield!\n", prplane(&item.plane)); continue; } } pr("%s scrapped in %s\n", unit_nameof(&item.gen), xyas(item.gen.x, item.gen.y, player->cnum)); unit_drop_cargo(&item.gen, sect.sct_own); if (type == EF_SHIP) { eff = item.ship.shp_effic / 100.0; mp = &mchr[(int)item.ship.shp_type]; for (i = I_NONE + 1; i <= I_MAX; i++) { if (load_comm_ok(§, item.ship.shp_own, i, -item.ship.shp_item[i])) sect.sct_item[i] += item.ship.shp_item[i]; } mvec = mp->m_mat; if (item.ship.shp_pstage == PLG_INFECT && sect.sct_pstage == PLG_HEALTHY) sect.sct_pstage = PLG_EXPOSED; } else if (type == EF_LAND) { eff = item.land.lnd_effic / 100.0; lp = &lchr[(int)item.land.lnd_type]; for (i = I_NONE + 1; i <= I_MAX; i++) { if (load_comm_ok(§, item.land.lnd_own, i, -item.land.lnd_item[i])) sect.sct_item[i] += item.land.lnd_item[i]; } mvec = lp->l_mat; if (item.land.lnd_pstage == PLG_INFECT && sect.sct_pstage == PLG_HEALTHY) sect.sct_pstage = PLG_EXPOSED; } else { eff = item.land.lnd_effic / 100.0; pp = &plchr[(int)item.plane.pln_type]; mvec = pp->pl_mat; } item.gen.effic = 0; put_empobj(type, item.gen.uid, &item.gen); for (i = I_NONE + 1; i <= I_MAX; i++) { if (i == I_CIVIL || i == I_MILIT || i == I_UW) amt = sect.sct_item[i] + mvec[i] * eff; else amt = sect.sct_item[i] + mvec[i] * 2 / 3 * eff; if (amt > ITEM_MAX) amt = ITEM_MAX; sect.sct_item[i] = amt; } putsect(§); } return RET_OK; }