: %d\n", nuke->nuk_plane); } static char * getin(char *buf, char **valp) { char line[1024]; char *argp[128]; char *p; *valp = NULL; p = getstarg(NULL, "%c xxxxx -- thing value : ", line); if (!p) return NULL; switch (parse(p, buf, argp, NULL, NULL, NULL)) { case 0: return ""; case 1: return NULL; default: *valp = argp[1]; return argp[0]; } } #if 0 /* not needed right now */ static void warn_deprecated(char key) { pr("Key <%c> is deprecated and will go away in a future release\n", key); } #endif int edit_sect_i(struct sctstr *sect, char *key, int arg) { int new; switch (*key) { case 'o': if (arg < 0 || arg >= MAXNOC) return RET_SYN; divine_sct_change_quiet(sect, "Owner", arg != sect->sct_own, "from %s to %s", prnatid(sect->sct_own), prnatid(arg)); if (arg == sect->sct_own) break; report_god_takes("Sector ", xyas(sect->sct_x, sect->sct_y, sect->sct_own), sect->sct_own); report_god_gives("Sector ", xyas(sect->sct_x, sect->sct_y, arg), arg); sect->sct_own = arg; break; case 'O': if (arg < 0 || arg >= MAXNOC) return RET_SYN; divine_sct_change(sect, "Old owner", arg != sect->sct_oldown, 0, "from %s to %s", prnatid(sect->sct_oldown), prnatid(arg)); sect->sct_oldown = arg; break; case 'e': new = LIMIT_TO(arg, 0, 100); noise(sect, "Efficiency", sect->sct_effic, new); sect->sct_effic = new; break; case 'm': new = LIMIT_TO(arg, -127, 127); noise(sect, "Mobility", sect->sct_mobil, new); sect->sct_mobil = new; break; case 'i': new = LIMIT_TO(arg, 0, 100); noise(sect, "Iron ore content", sect->sct_min, new); sect->sct_min = (unsigned char)new; break; case 'g': new = LIMIT_TO(arg, 0, 100); noise(sect, "Gold content", sect->sct_gmin, new); sect->sct_gmin = (unsigned char)new; break; case 'f': new = LIMIT_TO(arg, 0, 100); noise(sect, "Fertility", sect->sct_fertil, new); sect->sct_fertil = (unsigned char)new; break; case 'c': new = LIMIT_TO(arg, 0, 100); noise(sect, "Oil content", sect->sct_oil, new); sect->sct_oil = (unsigned char)new; break; case 'u': new = LIMIT_TO(arg, 0, 100); noise(sect, "Uranium content", sect->sct_uran, new); sect->sct_uran = (unsigned char)new; break; case 'w': new = LIMIT_TO(arg, 0, 100); noise(sect, "Workforce percentage", sect->sct_work, new); sect->sct_work = (unsigned char)new; break; case 'l': new = LIMIT_TO(arg, 0, 127); divine_sct_change_quiet(sect, "Loyalty", new != sect->sct_loyal, "from %d to %d", sect->sct_loyal, new); sect->sct_loyal = (unsigned char)new; break; case 'x': new = LIMIT_TO(arg, 0, CHE_MAX); divine_sct_change_quiet(sect, "Guerillas", new != sect->sct_che, "from %d to %d", sect->sct_che, new); sect->sct_che = new; break; case 'X': if (arg < 0 || arg >= MAXNOC) return RET_SYN; divine_sct_change_quiet(sect, "Che target", arg != sect->sct_che_target, "from %s to %s", prnatid(sect->sct_che_target), prnatid(arg)); sect->sct_che_target = arg; if (arg == 0) sect->sct_che = 0; break; case 'p': new = LIMIT_TO(arg, 0, PLG_EXPOSED); divine_sct_change_quiet(sect, "Plague stage", new != sect->sct_pstage, "from %d to %d", sect->sct_pstage, new); sect->sct_pstage = new; break; case 't': new = LIMIT_TO(arg, 0, 32767); divine_sct_change_quiet(sect, "Plague time", new != sect->sct_ptime, "from %d to %d", sect->sct_ptime, new); sect->sct_ptime = new; break; case 'F': new = LIMIT_TO(arg, 0, FALLOUT_MAX); noise(sect, "Fallout", sect->sct_fallout, new); sect->sct_fallout = new; break; case 'a': new = LIMIT_TO(arg, 0, 9999); noise(sect, "Available workforce", sect->sct_avail, new); sect->sct_avail = new; break; case 'M': new = LIMIT_TO(arg, 0, MINES_MAX); if (sect->sct_own == sect->sct_oldown) noise(sect, "Mines", sect->sct_mines, new); else divine_sct_change_quiet(sect, "Mines", new != sect->sct_mines, "from %d to %d", sect->sct_mines, new); sect->sct_mines = new; break; case 'R': new = LIMIT_TO(arg, 0, 100); noise(sect, "Road percentage", sect->sct_road, new); sect->sct_road = new; break; case 'r': new = LIMIT_TO(arg, 0, 100); noise(sect, "Rail percentage", sect->sct_rail, new); sect->sct_rail = new; break; case 'd': new = LIMIT_TO(arg, 0, 100); noise(sect, "Defense percentage", sect->sct_defense, new); sect->sct_defense = new; break; default: pr("huh? (%s)\n", key); return RET_SYN; } return RET_OK; } int edit_sect(struct sctstr *sect, char *key, char *p) { coord newx, newy; int new; struct sctstr newsect; switch (*key) { case 'L': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; if (newx == sect->sct_x && newy == sect->sct_y) { pr("Sector %s unchanged\n", xyas(newx, newy, player->cnum)); break; } getsect(newx, newy, &newsect); pr("Sector %s duplicated to %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), xyas(newx, newy, player->cnum)); report_god_takes("Sector ", xyas(newx, newy, newsect.sct_own), newsect.sct_own); report_god_gives("Sector ", xyas(newx, newy, sect->sct_own), sect->sct_own); if (sect->sct_x == sect->sct_dist_x && sect->sct_y == sect->sct_dist_y) { sect->sct_dist_x = newx; sect->sct_dist_y = newy; } sect->sct_x = newx; sect->sct_y = newy; sect->sct_coastal = newsect.sct_coastal; ef_set_uid(EF_SECTOR, sect, XYOFFSET(newx, newy)); break; case 'D': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; divine_sct_change_quiet(sect, "Distribution sector", newx != sect->sct_dist_x || newy != sect->sct_dist_y, "from %s to %s", xyas(sect->sct_dist_x, sect->sct_dist_y, player->cnum), xyas(newx, newy, player->cnum)); if (newx == sect->sct_dist_x && newy == sect->sct_dist_y) break; if (sect->sct_own && sect->sct_own != player->cnum) wu(0, sect->sct_own, "Distribution sector of %s changed from %s to %s" " by an act of %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), xyas(sect->sct_dist_x, sect->sct_dist_y, player->cnum), xyas(newx, newy, player->cnum), cname(player->cnum)); sect->sct_dist_x = newx; sect->sct_dist_y = newy; break; case 's': new = sct_typematch(p); if (new < 0) return RET_SYN; divine_sct_change(sect, "Designation", new != sect->sct_type, 0, "from %c to %c", dchr[sect->sct_type].d_mnem, dchr[new].d_mnem); set_coastal(sect, sect->sct_type, new); sect->sct_type = new; break; case 'S': new = sct_typematch(p); if (new < 0) return RET_SYN; divine_sct_change(sect, "New designation", new != sect->sct_newtype, 0, "from %c to %c", dchr[sect->sct_newtype].d_mnem, dchr[new].d_mnem); sect->sct_newtype = new; break; default: return edit_sect_i(sect, key, atoi(p)); } return RET_OK; } static void edit_level(struct natstr *np, int lvl, char *name, char *p) { float new = (float)atof(p); new = MAX(0.0, new); divine_nat_change(np, name, new != np->nat_level[lvl], (new > np->nat_level[lvl]) - (new < np->nat_level[lvl]), "from %.2f to %.2f", np->nat_level[lvl], new); np->nat_level[lvl] = new; } static int edit_nat(struct natstr *np, char *key, char *p) { coord newx, newy; natid nat = np->nat_cnum; int arg = atoi(p); switch (*key) { case 'n': if (!check_nat_name(p, nat)) return RET_SYN; divine_nat_change(np, "Country name", strcmp(np->nat_cnam, p), 0, "from %s to %s", np->nat_cnam, p); if (opt_GODNEWS) nreport(player->cnum, N_NAME_CHNG, 0, 1); strcpy(np->nat_cnam, p); break; case 'r': divine_nat_change(np, "Country representative", strncmp(p, np->nat_pnam, sizeof(np->nat_pnam) - 1), 0, "from %s to %.*s", np->nat_pnam, (int)sizeof(np->nat_pnam) - 1, p); strncpy(np->nat_pnam, p, sizeof(np->nat_pnam) - 1); break; case 't': arg = LIMIT_TO(arg, 0, USHRT_MAX); divine_nat_change_quiet(np, "Number of unread telegrams", arg != np->nat_tgms, "from %d to %d", np->nat_tgms, arg); np->nat_tgms = arg; break; case 'b': arg = LIMIT_TO(arg, 0, max_btus); divine_nat_change(np, "BTUs", arg != np->nat_btu, arg - np->nat_btu, "from %d to %d", np->nat_btu, arg); np->nat_btu = arg; break; case 'm': arg = LIMIT_TO(arg, 0, INT_MAX); divine_nat_change(np, "Military reserves", arg != np->nat_reserve, arg - np->nat_reserve, "from %d to %d", np->nat_reserve, arg); np->nat_reserve = arg; break; case 'c': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; if (newx == np->nat_xcap && newy == np->nat_ycap) pr("Capital unchanged\n"); else { pr("Capital moved from %s to %s\n", xyas(np->nat_xcap, np->nat_ycap, player->cnum), xyas(newx, newy, player->cnum)); if (nat != player->cnum) wu(0, nat, "Capital moved from %s to %s by an act of %s!\n", xyas(np->nat_xcap, np->nat_ycap, nat), xyas(newx, newy, nat), cname(player->cnum)); } np->nat_xcap = newx; np->nat_ycap = newy; break; case 'o': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; if (newx == np->nat_xorg && newy == np->nat_yorg) pr("Origin unchanged\n"); else { pr("Origin moved from %s to %s\n", xyas(np->nat_xorg, np->nat_yorg, player->cnum), xyas(newx, newy, player->cnum)); if (nat != player->cnum) wu(0, nat, "Origin moved from %s to %s by an act of %s!\n", xyas(np->nat_xorg, np->nat_yorg, nat), xyas(newx, newy, nat), cname(player->cnum)); } np->nat_xorg = newx; np->nat_yorg = newy; break; case 's': arg = LIMIT_TO(arg, STAT_UNUSED, STAT_GOD); divine_nat_change(np, "Status", (enum nat_status)arg != np->nat_stat, 0, "to %s", nation_status[arg].name); np->nat_stat = arg; break; case 'u': arg = LIMIT_TO(arg, 0, m_m_p_d * 60); divine_nat_change(np, "Number of seconds used", arg != np->nat_timeused, arg - np->nat_timeused, "from %d to %d", np->nat_timeused, arg); np->nat_timeused = arg; break; case 'M': divine_nat_change(np, "Money", arg != np->nat_money, arg - np->nat_money, "from %d to %d", np->nat_money, arg); np->nat_money = arg; break; case 'T': edit_level(np, NAT_TLEV, "Technology", p); break; case 'R': edit_level(np, NAT_RLEV, "Research", p); break; case 'E': edit_level(np, NAT_ELEV, "Education", p); break; case 'H': edit_level(np, NAT_HLEV, "Happiness", p); break; default: pr("huh? (%s)\n", key); break; } return RET_OK; } static int edit_unit(struct empobj *unit, char *key, char *p, int mineff, char *group_name, int on_carrier) { int arg = atoi(p); coord newx, newy; union empobj_storage newunit; char newgroup; switch (toupper(*key)) { case 'U': if (arg < 0) return RET_SYN; if (arg == unit->uid) { pr("%s unchanged\n", unit_nameof(unit)); break; } if (!ef_ensure_space(unit->ef_type, arg, 50)) { pr("Can't copy to %s #%d\n", ef_nameof(unit->ef_type), arg); return RET_FAIL; } pr("%s duplicated to (#%d)\n", unit_nameof(unit), arg); ef_set_uid(unit->ef_type, unit, arg); if (get_empobj(unit->ef_type, arg, &newunit) && newunit.gen.own) { pr("Replacing %s of %s\n", unit_nameof(&newunit.gen), prnatid(newunit.gen.own)); report_god_takes("", unit_nameof(&newunit.gen), newunit.gen.own); } report_god_gives("", unit_nameof(unit), unit->own); break; case 'O': if (arg < 0 || arg >= MAXNOC) return RET_SYN; divine_unit_change_quiet(unit, "Owner", arg != unit->own, "from %s to %s", prnatid(unit->own), prnatid(arg)); if (arg != unit->own) { report_god_takes("", unit_nameof(unit), unit->own); report_god_gives("", unit_nameof(unit), arg); } if (arg && unit->effic < mineff) { divine_unit_change_quiet(unit, "Efficiency", 1, "from %d to %d", unit->effic, mineff); unit->effic = mineff; } unit->own = arg; break; case 'L': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; if (on_carrier && (newx != unit->x || newy != unit->y)) { pr("Can't move %s while it's loaded\n", unit_nameof(unit)); return RET_FAIL; } divine_unit_change_quiet(unit, "Location", newx != unit->x || newy != unit->y, "from %s to %s", xyas(unit->x, unit->y, player->cnum), xyas(newx, newy, player->cnum)); if (newx == unit->x && newy == unit->y) break; if (unit->own && unit->own != player->cnum) wu(0, unit->own, "Location of %s changed from %s to %s by an act of %s!\n", unit_nameof(unit), xyas(unit->x, unit->y, unit->own), xyas(newx, newy, unit->own), cname(player->cnum)); unit_teleport(unit, newx, newy); break; case 'E': arg = LIMIT_TO(arg, mineff, 100); divine_unit_change(unit, "Efficiency", arg != unit->effic, arg - unit->effic, "from %d to %d", unit->effic, arg); unit->effic = arg; break; case 'M': arg = LIMIT_TO(arg, -127, 127); divine_unit_change(unit, "Mobility", arg != unit->mobil, arg - unit->mobil, "from %d to %d", unit->mobil, arg); unit->mobil = arg; break; case 'F': case 'W': case 'A': case 'S': if (p[0] == '~') newgroup = 0; else if (isalpha(p[0])) newgroup = p[0]; else { pr("%c: invalid %s\n", p[0], group_name); return RET_FAIL; } divine_unit_change(unit, "Assignment", newgroup != unit->group, 0, "from %s %c to %c", group_name, unit->group ? unit->group : '~', p[0]); unit->group = newgroup; break; default: CANT_REACH(); } return RET_OK; } static void edit_item(struct empobj *unit, short item[], struct ichrstr *ip, int arg, short lim[]) { arg = LIMIT_TO(arg, 0, lim[ip->i_uid]); divine_unit_change_quiet(unit, ip->i_name, arg != item[ip->i_uid], "from %d to %d", item[ip->i_uid], arg); report_divine_gift(unit->own, ip, arg - item[ip->i_uid], unit_nameof(unit)); item[ip->i_uid] = arg; } static void limit_item(struct empobj *unit, short item[], short lim[]) { i_type it; for (it = I_NONE + 1; it <= I_MAX; it++) { if (item[it] > lim[it]) edit_item(unit, item, &ichr[it], item[it], lim); } } static int edit_ship(struct shpstr *ship, char *key, char *p) { struct mchrstr *mcp = &mchr[ship->shp_type]; int arg = atoi(p); int ret; switch (*key) { case 'U': case 'O': case 'L': case 'E': case 'M': case 'F': ret = edit_unit((struct empobj *)ship, key, p, SHIP_MINEFF, "fleet", 0); return ret; case 't': arg = ef_elt_byname(EF_SHIP_CHR, p); if (arg < 0) { pr("%s: invalid ship type\n", p); return RET_FAIL; } divine_unit_change((struct empobj *)ship, "Type", arg != ship->shp_type, 0, "to %s", mchr[arg].m_name); ship->shp_type = arg; limit_item((struct empobj *)ship, ship->shp_item, mchr[arg].m_item); if (ship->shp_tech >= mchr[arg].m_tech) break; arg = mchr[arg].m_tech; /* fall through */ case 'T': arg = LIMIT_TO(arg, mcp->m_tech, SHRT_MAX); divine_unit_change((struct empobj *)ship, "Tech level", arg != ship->shp_tech, arg - ship->shp_tech, "from %d to %d", ship->shp_tech, arg); shp_set_tech(ship, arg); break; case 'a': arg = LIMIT_TO(arg, 0, PLG_EXPOSED); divine_unit_change_quiet((struct empobj *)ship, "Plague stage", arg != ship->shp_pstage, "from %d to %d", ship->shp_pstage, arg); ship->shp_pstage = arg; break; case 'b': arg = LIMIT_TO(arg, 0, 32767); divine_unit_change_quiet((struct empobj *)ship, "Plague time", arg != ship->shp_ptime, "from %d to %d", ship->shp_ptime, arg); ship->shp_ptime = arg; break; case 'R': divine_unit_change((struct empobj *)ship, "Retreat path", strncmp(p, ship->shp_rpath, sizeof(ship->shp_rpath) - 1), 0, "from %s to %.*s", ship->shp_rpath, (int)sizeof(ship->shp_rpath) - 1, p); strncpy(ship->shp_rpath, p, sizeof(ship->shp_rpath) - 1); break; case 'W': divine_flag_change((struct empobj *)ship, "Retreat conditions", ship->shp_rflags, arg, retreat_flags); ship->shp_rflags = arg; break; case 'c': case 'm': case 'u': case 'f': case 's': case 'g': case 'p': case 'i': case 'd': case 'o': case 'l': case 'h': case 'r': edit_item((struct empobj *)ship, ship->shp_item, item_by_name(key), arg, mcp->m_item); break; default: pr("huh? (%s)\n", key); return RET_FAIL; } return RET_OK; } static int edit_land(struct lndstr *land, char *key, char *p) { struct lchrstr *lcp = &lchr[land->lnd_type]; int arg = atoi(p); switch (*key) { case 'U': case 'O': case 'L': case 'e': case 'M': case 'a': return edit_unit((struct empobj *)land, key, p, LAND_MINEFF, "army", land->lnd_ship >= 0 || land->lnd_land >= 0); case 'T': arg = ef_elt_byname(EF_LAND_CHR, p); if (arg < 0) { pr("%s: invalid land unit type\n", p); return RET_FAIL; } divine_unit_change((struct empobj *)land, "Type", arg != land->lnd_type, 0, "to %s", lchr[arg].l_name); land->lnd_type = arg; limit_item((struct empobj *)land, land->lnd_item, lchr[arg].l_item); if (land->lnd_tech >= lchr[arg].l_tech) break; arg = lchr[arg].l_tech; /* fall through */ case 't': arg = LIMIT_TO(arg, lcp->l_tech, SHRT_MAX); divine_unit_change((struct empobj *)land, "Tech level", arg != land->lnd_tech, arg - land->lnd_tech, "from %d to %d", land->lnd_tech, arg); lnd_set_tech(land, arg); break; case 'F': arg = LIMIT_TO(arg, 0, 127); divine_unit_change((struct empobj *)land, "Fortification", arg != land->lnd_harden, arg - land->lnd_harden, "from %d to %d", land->lnd_harden, arg); land->lnd_harden = arg; break; case 'S': if (arg < -1 || arg >= ef_nelem(EF_SHIP)) return RET_SYN; if (arg == land->lnd_ship) { pr("Ship of %s unchanged\n", prland(land)); break; } divine_unload((struct empobj *)land, EF_SHIP, land->lnd_ship); if (arg >= 0) { divine_unload((struct empobj *)land, EF_LAND, land->lnd_land); land->lnd_land = -1; } divine_load((struct empobj *)land, EF_SHIP, arg); land->lnd_ship = arg; break; case 'Y': if (arg < -1 || arg >= ef_nelem(EF_LAND)) return RET_SYN; if (arg == land->lnd_land) { pr("Land unit of %s unchanged\n", prland(land)); break; } divine_unload((struct empobj *)land, EF_LAND, land->lnd_land); if (arg >= 0) { divine_unload((struct empobj *)land, EF_SHIP, land->lnd_ship); land->lnd_ship = -1; } divine_load((struct empobj *)land, EF_LAND, arg); land->lnd_land = arg; break; case 'Z': arg = LIMIT_TO(arg, 0, 100); divine_unit_change((struct empobj *)land, "Retreat percentage", arg != land->lnd_retreat, 0, "from %d to %d", land->lnd_retreat, arg); land->lnd_retreat = arg; break; case 'R': divine_unit_change((struct empobj *)land, "Retreat path", strncmp(p, land->lnd_rpath, sizeof(land->lnd_rpath) - 1), 0, "from %s to %.*s", land->lnd_rpath, (int)sizeof(land->lnd_rpath) - 1, p); strncpy(land->lnd_rpath, p, sizeof(land->lnd_rpath) - 1); break; case 'W': divine_flag_change((struct empobj *)land, "Retreat condition", land->lnd_rflags, arg, retreat_flags); land->lnd_rflags = arg; break; case 'c': case 'm': case 'u': case 'f': case 's': case 'g': case 'p': case 'i': case 'd': case 'o': case 'l': case 'h': case 'r': edit_item((struct empobj *)land, land->lnd_item, item_by_name(key), arg, lcp->l_item); break; default: pr("huh? (%s)\n", key); return RET_FAIL; } return RET_OK; } static int edit_plane(struct plnstr *plane, char *key, char *p) { struct plchrstr *pcp = &plchr[plane->pln_type]; int arg = atoi(p); switch (*key) { case 'U': case 'O': case 'l': case 'e': case 'm': case 'w': return edit_unit((struct empobj *)plane, key, p, PLANE_MINEFF, "wing", plane->pln_ship >= 0 || plane->pln_land >= 0); case 'T': arg = ef_elt_byname(EF_PLANE_CHR, p); if (arg < 0) { pr("%s: invalid plane type\n", p); return RET_FAIL; } divine_unit_change((struct empobj *)plane, "Type", arg != plane->pln_type, 0, "to %s", plchr[arg].pl_name); plane->pln_type = arg; if (plane->pln_tech >= plchr[arg].pl_tech) break; arg = plchr[arg].pl_tech; /* fall through */ case 't': arg = LIMIT_TO(arg, pcp->pl_tech, SHRT_MAX); divine_unit_change((struct empobj *)plane, "Tech level", arg != plane->pln_tech, arg - plane->pln_tech, "from %d to %d", plane->pln_tech, arg); pln_set_tech(plane, arg); break; case 'r': arg = LIMIT_TO(arg, 0, pl_range(pcp, plane->pln_tech)); divine_unit_change((struct empobj *)plane, "Range", arg != plane->pln_range, 0, "from %d to %d", plane->pln_range, arg); plane->pln_range = (unsigned char)arg; break; case 's': if (arg < -1 || arg >= ef_nelem(EF_SHIP)) return RET_SYN; if (arg == plane->pln_ship) { pr("Ship of %s unchanged\n", prplane(plane)); break; } divine_unload((struct empobj *)plane, EF_SHIP, plane->pln_ship); if (arg >= 0) { divine_unload((struct empobj *)plane, EF_LAND, plane->pln_land); plane->pln_land = -1; } divine_load((struct empobj *)plane, EF_SHIP, arg); plane->pln_ship = arg; break; case 'y': if (arg < -1 || arg >= ef_nelem(EF_LAND)) return RET_SYN; if (arg == plane->pln_land) { pr("Land unit of %s unchanged\n", prplane(plane)); break; } divine_unload((struct empobj *)plane, EF_LAND, plane->pln_land); if (arg >= 0) { divine_unload((struct empobj *)plane, EF_SHIP, plane->pln_ship); plane->pln_ship = -1; } divine_load((struct empobj *)plane, EF_LAND, arg); plane->pln_land = arg; break; case 'f': divine_flag_change((struct empobj *)plane, "Flags", plane->pln_flags, arg, plane_flags); plane->pln_flags = arg; break; default: pr("huh? (%s)\n", key); return RET_FAIL; } return RET_OK; } static int edit_nuke(struct nukstr *nuke, char *key, char *p) { struct nchrstr *ncp = &nchr[nuke->nuk_type]; int arg = atoi(p); switch (*key) { case 'U': case 'O': case 'L': case 'S': return edit_unit((struct empobj *)nuke, key, p, 100, "stockpile", nuke->nuk_plane >= 0); case 't': arg = ef_elt_byname(EF_NUKE_CHR, p); if (arg < 0) { pr("%s: invalid nuke type\n", p); return RET_FAIL; } divine_unit_change((struct empobj *)nuke, "Type", arg != nuke->nuk_type, 0, "to %s", nchr[arg].n_name); nuke->nuk_type = arg; if (nuke->nuk_tech >= nchr[arg].n_tech) break; arg = nchr[arg].n_tech; /* fall through */ case 'T': arg = LIMIT_TO(arg, ncp->n_tech, SHRT_MAX); divine_unit_change((struct empobj *)nuke, "Tech level", arg != nuke->nuk_tech, arg - nuke->nuk_tech, "from %d to %d", nuke->nuk_tech, arg); nuke->nuk_tech = arg; break; case 'p': if (arg < -1 || arg >= ef_nelem(EF_PLANE)) return RET_SYN; if (arg == nuke->nuk_plane) { pr("Plane of %s unchanged\n", prnuke(nuke)); break; } divine_unload((struct empobj *)nuke, EF_PLANE, nuke->nuk_plane); divine_load((struct empobj *)nuke, EF_PLANE, arg); nuke->nuk_plane = arg; break; default: pr("huh? (%s)\n", key); return RET_FAIL; } return RET_OK; }