/* * Empire - A multi-player, client/server Internet based war game. * Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak, * Ken Stevens, Steve McClure, Markus Armbruster * * Empire is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * --- * * See files README, COPYING and CREDITS in the root of the source * tree for related information and legal notices. It is expected * that future projects/authors will amend these files as needed. * * --- * * edit.c: Edit things (sectors, ships, planes, units, nukes, countries) * * Known contributors to this file: * David Muir Sharnoff * Chad Zabel, 1994 * Steve McClure, 1998-2000 * Ron Koenderink, 2003-2009 * Markus Armbruster, 2003-2013 */ #include #include #include #include "actofgod.h" #include "commands.h" #include "item.h" #include "land.h" #include "news.h" #include "optlist.h" #include "plague.h" #include "plane.h" #include "ship.h" static void print_sect(struct sctstr *); static void print_nat(struct natstr *); static void print_plane(struct plnstr *); static void print_land(struct lndstr *); static void print_ship(struct shpstr *); static char *getin(char *, char **); static int edit_nat(struct natstr *, char *, char *); static int edit_ship(struct shpstr *, char *, char *); static int edit_land(struct lndstr *, char *, char *); static int edit_plane(struct plnstr *, char *, char *); int edit(void) { struct sctstr sect; struct plnstr plane; struct shpstr ship; struct lndstr land; char *what; char *key, *ptr; int num; int err; int arg_index = 3; coord x, y; struct natstr *np; char buf[1024]; char ewhat; what = getstarg(player->argp[1], "Edit what (country, land, ship, plane, nuke, unit)? ", buf); if (!what) return RET_SYN; ewhat = what[0]; switch (ewhat) { case 'l': if (!(ptr = getstarg(player->argp[2], "Sector : ", buf))) return RET_FAIL; if (!sarg_xy(ptr, &x, &y)) return RET_FAIL; if (!getsect(x, y, §)) return RET_FAIL; break; case 'c': np = natargp(player->argp[2], "Country? "); if (!np) return RET_SYN; break; case 'p': if ((num = onearg(player->argp[2], "Plane number? ")) < 0) return RET_SYN; if (!getplane(num, &plane)) return RET_SYN; break; case 's': if ((num = onearg(player->argp[2], "Ship number? ")) < 0) return RET_SYN; if (!getship(num, &ship)) return RET_SYN; break; case 'u': if ((num = onearg(player->argp[2], "Unit number? ")) < 0) return RET_SYN; if (!getland(num, &land)) return RET_SYN; break; case 'n': pr("Not implemented yet.\n"); break; default: pr("huh?\n"); return RET_SYN; } if (!player->argp[3]) { switch (ewhat) { case 'l': print_sect(§); break; case 'c': print_nat(np); break; case 'p': print_plane(&plane); break; case 's': print_ship(&ship); break; case 'u': print_land(&land); break; } } for (;;) { if (player->argp[arg_index]) { if (player->argp[arg_index+1]) { key = player->argp[arg_index++]; ptr = player->argp[arg_index++]; } else return RET_SYN; } else if (arg_index == 3) { key = getin(buf, &ptr); if (!key) return RET_SYN; if (!*key) { switch (ewhat) { case 'c': print_nat(np); break; case 'l': print_sect(§); break; case 's': print_ship(&ship); break; case 'u': print_land(&land); break; case 'p': print_plane(&plane); break; } return RET_OK; } } else return RET_OK; switch (ewhat) { case 'c': if ((err = edit_nat(np, key, ptr)) != RET_OK) return err; break; case 'l': if (!check_sect_ok(§)) return RET_FAIL; if ((err = edit_sect(§, key, ptr)) != RET_OK) return err; if (!putsect(§)) return RET_FAIL; break; case 's': if (!check_ship_ok(&ship)) return RET_FAIL; if ((err = edit_ship(&ship, key, ptr)) != RET_OK) return err; if (!ef_ensure_space(EF_SHIP, ship.shp_uid, 50)) return RET_FAIL; if (!putship(ship.shp_uid, &ship)) return RET_FAIL; break; case 'u': if (!check_land_ok(&land)) return RET_FAIL; if ((err = edit_land(&land, key, ptr)) != RET_OK) return err; if (!ef_ensure_space(EF_LAND, land.lnd_uid, 50)) return RET_FAIL; if (!putland(land.lnd_uid, &land)) return RET_FAIL; break; case 'p': if (!check_plane_ok(&plane)) return RET_FAIL; if ((err = edit_plane(&plane, key, ptr)) != RET_OK) return err; if (!ef_ensure_space(EF_PLANE, plane.pln_uid, 50)) return RET_FAIL; if (!putplane(plane.pln_uid, &plane)) return RET_FAIL; break; } } } static void benefit(natid who, int goodness) { if (opt_GODNEWS && getnatp(who)->nat_stat != STAT_GOD && goodness) nreport(player->cnum, goodness > 0 ? N_AIDS : N_HURTS, who, 1); } static void noise(struct sctstr *sptr, char *name, int old, int new) { pr("%s of %s changed from %d to %d\n", name, xyas(sptr->sct_x, sptr->sct_y, player->cnum), old, new); if (sptr->sct_own && sptr->sct_own != player->cnum && new != old) wu(0, sptr->sct_own, "%s of %s changed from %d to %d by an act of %s\n", name, xyas(sptr->sct_x, sptr->sct_y, sptr->sct_own), old, new, cname(player->cnum)); benefit(sptr->sct_own, new - old); } static void print_sect(struct sctstr *sect) { pr("Location : %s\t", xyas(sect->sct_x, sect->sct_y, player->cnum)); pr("Distribution sector : %s\n", xyas(sect->sct_dist_x, sect->sct_dist_y, player->cnum)); pr("Designation : %c\tNew designation : %c\n", dchr[sect->sct_type].d_mnem, dchr[sect->sct_newtype].d_mnem); pr("own oo eff mob min gld frt oil urn wrk lty che ctg plg ptime fall avail\n"); pr(" o O e m i g f c u w l x X p t F a\n"); pr("%3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %5d %4d %5d\n", sect->sct_own, sect->sct_oldown, sect->sct_effic, sect->sct_mobil, sect->sct_min, sect->sct_gmin, sect->sct_fertil, sect->sct_oil, sect->sct_uran, sect->sct_work, sect->sct_loyal, sect->sct_che, sect->sct_che_target, sect->sct_pstage, sect->sct_ptime, sect->sct_fallout, sect->sct_avail); pr("Mines : %d\n", sect->sct_mines); pr("Road %% : %d\t", sect->sct_road); pr("Rail %% : %d\t", sect->sct_rail); pr("Defense %% : %d\n", sect->sct_defense); } static void print_nat(struct natstr *np) { int i; pr("Country #: %2d\n", np->nat_cnum); pr("Name : %-20s\t", np->nat_cnam); pr("Representative : %-20s\n", np->nat_pnam); pr("BTUs : %3d\t\t\t", np->nat_btu); pr("Reserves : %5d\n", np->nat_reserve); pr("Capital : %s\t\t", xyas(np->nat_xcap, np->nat_ycap, player->cnum)); pr("Origin : %3s\n", xyas(np->nat_xorg, np->nat_yorg, player->cnum)); pr("Status : 0x%x\t\t\t", np->nat_stat); pr("Seconds Used : %3d\n", np->nat_timeused); pr("Technology : %.2f\t\t", np->nat_level[NAT_TLEV]); pr("Research : %.2f\n", np->nat_level[NAT_RLEV]); pr("Education : %.2f\t\t", np->nat_level[NAT_ELEV]); pr("Happiness : %.2f\n", np->nat_level[NAT_HLEV]); pr("Money : $%6d\n", np->nat_money); pr("Telegrams : %6d\n", np->nat_tgms); if (opt_HIDDEN) { pr("Countries contacted: "); for (i = 0; i < MAXNOC; i++) { if (getcontact(np, i)) pr("%d(%d) ", i, getcontact(np, i)); } pr("\n"); } } static void print_plane(struct plnstr *plane) { pr("%s %s\n", prnatid(plane->pln_own), prplane(plane)); pr("UID : %d\t\t", plane->pln_uid); pr("Owner : %d\t\t", plane->pln_own); pr("Location : %s\n", xyas(plane->pln_x, plane->pln_y, player->cnum)); pr("Efficiency : %d\t", plane->pln_effic); pr("Mobility : %d\n", plane->pln_mobil); pr("Tech : %d\t\t", plane->pln_tech); pr("Wing : %.1s\n", &plane->pln_wing); pr("Range : %d\t\t", plane->pln_range); pr("Flags : %d\n", plane->pln_flags); pr("Ship : %d\t\t", plane->pln_ship); pr("Land Unit : %d\t", plane->pln_land); } static void print_land(struct lndstr *land) { pr("%s %s\n", prnatid(land->lnd_own), prland(land)); pr("UID : %d\n", land->lnd_uid); pr("Owner : %d\n", land->lnd_own); pr("Location : %s\n", xyas(land->lnd_x, land->lnd_y, player->cnum)); pr("Efficiency : %d\t", land->lnd_effic); pr("Mobility : %d\n", land->lnd_mobil); pr("Tech : %d\t\t", land->lnd_tech); pr("Army : %.1s\n", &land->lnd_army); pr("Fortification : %d\t", land->lnd_harden); pr("Land unit : %d\n", land->lnd_land); pr("Ship : %d\t\t", land->lnd_ship); pr("Retreat percentage : %d\n", land->lnd_retreat); pr("Retreat path : '%s'\t\tRetreat Flags : %d\n", land->lnd_rpath, land->lnd_rflags); pr("civ mil uw food shl gun pet irn dst oil lcm hcm rad\n"); pr(" c m u f s g p i d o l h r\n"); pr("%3d", land->lnd_item[I_CIVIL]); pr("%4d", land->lnd_item[I_MILIT]); pr("%4d", land->lnd_item[I_UW]); pr("%5d", land->lnd_item[I_FOOD]); pr("%4d", land->lnd_item[I_SHELL]); pr("%4d", land->lnd_item[I_GUN]); pr("%5d", land->lnd_item[I_PETROL]); pr("%5d", land->lnd_item[I_IRON]); pr("%5d", land->lnd_item[I_DUST]); pr("%5d", land->lnd_item[I_OIL]); pr("%5d", land->lnd_item[I_LCM]); pr("%5d", land->lnd_item[I_HCM]); pr("%4d", land->lnd_item[I_RAD]); pr("\n"); } static void print_ship(struct shpstr *ship) { pr("%s %s\n", prnatid(ship->shp_own), prship(ship)); pr("UID : %d\n", ship->shp_uid); pr("Owner : %d\t\t\t", ship->shp_own); pr("Location : %s\n", xyas(ship->shp_x, ship->shp_y, player->cnum)); pr("Tech : %d\t\t\t", ship->shp_tech); pr("Efficiency : %d\n", ship->shp_effic); pr("Mobility : %d\t\t", ship->shp_mobil); pr("Fleet : %.1s\n", &ship->shp_fleet); pr("Retreat path : '%s'\t\tRetreat Flags : %d\n", ship->shp_rpath, ship->shp_rflags); pr("Plague Stage : %d\t\t", ship->shp_pstage); pr("Plague Time : %d\n", ship->shp_ptime); pr("civ mil uw food shl gun pet irn dst oil lcm hcm rad\n"); pr(" c m u f s g p i d o l h r\n"); pr("%3d", ship->shp_item[I_CIVIL]); pr("%4d", ship->shp_item[I_MILIT]); pr("%4d", ship->shp_item[I_UW]); pr("%5d", ship->shp_item[I_FOOD]); pr("%4d", ship->shp_item[I_SHELL]); pr("%4d", ship->shp_item[I_GUN]); pr("%5d", ship->shp_item[I_PETROL]); pr("%5d", ship->shp_item[I_IRON]); pr("%5d", ship->shp_item[I_DUST]); pr("%5d", ship->shp_item[I_OIL]); pr("%5d", ship->shp_item[I_LCM]); pr("%5d", ship->shp_item[I_HCM]); pr("%4d", ship->shp_item[I_RAD]); pr("\n"); } 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; pr("Owner of %s changed from %s to %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), 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; pr("Old owner of %s changed from %s to %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), prnatid(sect->sct_oldown), prnatid(arg)); if (arg == sect->sct_oldown) break; if (sect->sct_own && sect->sct_own != player->cnum) wu(0, sect->sct_own, "Old owner of %s changed from %s to %s by an act of %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), prnatid(sect->sct_oldown), prnatid(arg), cname(player->cnum)); 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); pr("Loyalty of %s changed from %d to %d\n", xyas(sect->sct_x, sect->sct_y, player->cnum), sect->sct_loyal, new); sect->sct_loyal = (unsigned char)new; break; case 'x': new = LIMIT_TO(arg, 0, CHE_MAX); pr("Guerillas of %s changed from %d to %d\n", xyas(sect->sct_x, sect->sct_y, player->cnum), sect->sct_che, new); sect->sct_che = new; break; case 'X': if (arg < 0 || arg >= MAXNOC) return RET_SYN; pr("Che target of %s changed from %s to %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), 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); pr("Plague stage of %s changed from %d to %d\n", xyas(sect->sct_x, sect->sct_y, player->cnum), sect->sct_pstage, new); sect->sct_pstage = new; break; case 't': new = LIMIT_TO(arg, 0, 32767); pr("Plague time of %s changed from %d to %d\n", xyas(sect->sct_x, sect->sct_y, player->cnum), 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 pr("Mines of %s changed from %d to %d\n", xyas(sect->sct_x, sect->sct_y, player->cnum), 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; 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); sect->sct_x = newx; sect->sct_y = newy; ef_set_uid(EF_SECTOR, sect, XYOFFSET(newx, newy)); break; case 'D': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; pr("Distribution sector of %s changed from %s to %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)); 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; pr("Designation of %s changed from %c to %c\n", xyas(sect->sct_x, sect->sct_y, player->cnum), dchr[sect->sct_type].d_mnem, dchr[new].d_mnem); if (new == sect->sct_type) break; if (sect->sct_own && sect->sct_own != player->cnum) wu(0, sect->sct_own, "Designation of %s changed from %c to %c" " by an act of %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), dchr[sect->sct_type].d_mnem, dchr[new].d_mnem, cname(player->cnum)); set_coastal(sect, sect->sct_type, new); sect->sct_type = new; break; case 'S': new = sct_typematch(p); if (new < 0) return RET_SYN; pr("New designation of %s changed from %c to %c\n", xyas(sect->sct_x, sect->sct_y, player->cnum), dchr[sect->sct_newtype].d_mnem, dchr[new].d_mnem); if (new == sect->sct_newtype) break; if (sect->sct_own && sect->sct_own != player->cnum) wu(0, sect->sct_own, "New designation of %s changed from %c to %c" " by an act of %s\n", xyas(sect->sct_x, sect->sct_y, player->cnum), dchr[sect->sct_newtype].d_mnem, dchr[new].d_mnem, cname(player->cnum)); sect->sct_newtype = new; break; default: return edit_sect_i(sect, key, atoi(p)); } return RET_OK; } static int edit_nat(struct natstr *np, char *key, char *p) { coord newx, newy; natid nat = np->nat_cnum; int arg = atoi(p); float farg = (float)atof(p); switch (*key) { case 'n': if (!check_nat_name(p, nat)) return RET_SYN; pr("Country name changed from %s to %s\n", np->nat_cnam, p); strcpy(np->nat_cnam, p); break; case 'r': pr("Country representative changed from %s to %s\n", np->nat_pnam, p); strncpy(np->nat_pnam, p, sizeof(np->nat_pnam) - 1); break; case 't': arg = LIMIT_TO(arg, 0, USHRT_MAX); np->nat_tgms = arg; break; case 'b': arg = LIMIT_TO(arg, 0, max_btus); pr("BTU's changed from %d to %d\n", np->nat_btu, arg); np->nat_btu = arg; break; case 'm': arg = LIMIT_TO(arg, 0, INT_MAX); benefit(nat, arg - np->nat_reserve); pr("Military reserves changed from %d to %d\n", np->nat_reserve, arg); if (arg == np->nat_reserve) break; if (nat != player->cnum) wu(0, nat, "Military reserves changed from %d to %d by an act of %s\n", np->nat_reserve, arg, cname(player->cnum)); np->nat_reserve = arg; break; case 'c': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; pr("Capital coordinates changed from %s to %s\n", xyas(np->nat_xcap, np->nat_ycap, player->cnum), xyas(newx, newy, player->cnum)); np->nat_xcap = newx; np->nat_ycap = newy; break; case 'o': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; pr("Origin coordinates changed from %s to %s\n", xyas(np->nat_xorg, np->nat_yorg, player->cnum), xyas(newx, newy, player->cnum)); np->nat_xorg = newx; np->nat_yorg = newy; break; case 's': np->nat_stat = LIMIT_TO(arg, STAT_UNUSED, STAT_GOD); break; case 'u': arg = LIMIT_TO(arg, 0, m_m_p_d * 60); pr("Number of seconds used changed from %d to %d.\n", np->nat_timeused, arg); np->nat_timeused = arg; break; case 'M': pr("Money changed from %d to %d\n", np->nat_money, arg); if (arg == np->nat_money) break; if (nat != player->cnum) wu(0, nat, "Money changed from %d to %d by an act of %s\n", np->nat_money, arg, cname(player->cnum)); np->nat_money = arg; break; case 'T': farg = MAX(0.0, farg); pr("Tech changed from %.2f to %.2f.\n", np->nat_level[NAT_TLEV], farg); np->nat_level[NAT_TLEV] = farg; break; case 'R': farg = MAX(0.0, farg); pr("Research changed from %.2f to %.2f.\n", np->nat_level[NAT_RLEV], farg); np->nat_level[NAT_RLEV] = farg; break; case 'E': farg = MAX(0.0, farg); pr("Education changed from %.2f to %.2f.\n", np->nat_level[NAT_ELEV], farg); np->nat_level[NAT_ELEV] = farg; break; case 'H': farg = MAX(0.0, farg); pr("Happiness changed from %.2f to %.2f.\n", np->nat_level[NAT_HLEV], farg); np->nat_level[NAT_HLEV] = farg; break; default: pr("huh? (%s)\n", key); break; } putnat(np); return RET_OK; } static int edit_ship(struct shpstr *ship, char *key, char *p) { struct mchrstr *mcp = &mchr[ship->shp_type]; int arg = atoi(p); coord newx, newy; struct ichrstr *ip; newx = newy = 0; switch (*key) { case 'a': arg = LIMIT_TO(arg, 0, PLG_EXPOSED); ship->shp_pstage = arg; break; case 'b': arg = LIMIT_TO(arg, 0, 32767); ship->shp_ptime = arg; break; case 'R': strncpy(ship->shp_rpath, p, sizeof(ship->shp_rpath) - 1); break; case 'W': ship->shp_rflags = arg; break; case 'U': ef_set_uid(EF_SHIP, ship, arg); break; case 'O': if (arg < 0 || arg >= MAXNOC) return RET_SYN; if (arg == ship->shp_own) break; if (ship->shp_own && ship->shp_own != player->cnum) wu(0, ship->shp_own, "%s taken from you by an act of %s!\n", prship(ship), cname(player->cnum)); if (arg && arg != player->cnum) wu(0, arg, "%s given to you by an act of %s!\n", prship(ship), cname(player->cnum)); ship->shp_own = arg; break; case 'L': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; ship->shp_x = newx; ship->shp_y = newy; break; case 'T': arg = LIMIT_TO(arg, mcp->m_tech, SHRT_MAX); shp_set_tech(ship, arg); break; case 'E': ship->shp_effic = LIMIT_TO(arg, SHIP_MINEFF, 100); break; case 'M': arg = LIMIT_TO(arg, -127, 127); ship->shp_mobil = arg; break; case 'F': if (p[0] == '~') ship->shp_fleet = 0; else if (isalpha(p[0])) ship->shp_fleet = p[0]; else { pr("%c: invalid fleet\n", p[0]); return RET_FAIL; } 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': ip = item_by_name(key); arg = LIMIT_TO(arg, 0, mchr[ship->shp_type].m_item[ip->i_uid]); ship->shp_item[ip->i_uid] = arg; 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); coord newx, newy; struct ichrstr *ip; newx = newy = 0; switch (*key) { case 'Y': if (arg < -1 || arg >= ef_nelem(EF_LAND)) return RET_SYN; if (arg >= 0 && arg != land->lnd_land) land->lnd_ship = -1; land->lnd_land = arg; break; case 'U': ef_set_uid(EF_LAND, land, arg); break; case 'O': if (arg < 0 || arg >= MAXNOC) return RET_SYN; if (arg == land->lnd_own) break; if (land->lnd_own && land->lnd_own != player->cnum) wu(0, land->lnd_own, "%s taken from you by an act of %s!\n", prland(land), cname(player->cnum)); if (arg && arg != player->cnum) wu(0, arg, "%s given to you by an act of %s!\n", prland(land), cname(player->cnum)); land->lnd_own = arg; break; case 'L': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; land->lnd_x = newx; land->lnd_y = newy; break; case 'e': land->lnd_effic = LIMIT_TO(arg, LAND_MINEFF, 100); break; case 'M': arg = LIMIT_TO(arg, -127, 127); land->lnd_mobil = arg; break; case 't': arg = LIMIT_TO(arg, lcp->l_tech, SHRT_MAX); lnd_set_tech(land, arg); break; case 'a': if (p[0] == '~') land->lnd_army = 0; else if (isalpha(p[0])) land->lnd_army = p[0]; else { pr("%c: invalid army\n", p[0]); return RET_FAIL; } break; case 'F': land->lnd_harden = LIMIT_TO(arg, 0, 127); break; case 'S': if (arg < -1 || arg >= ef_nelem(EF_SHIP)) return RET_SYN; if (arg >= 0 && arg != land->lnd_ship) land->lnd_land = -1; land->lnd_ship = arg; break; case 'Z': arg = LIMIT_TO(arg, 0, 100); land->lnd_retreat = arg; break; case 'R': strncpy(land->lnd_rpath, p, sizeof(land->lnd_rpath) - 1); break; case 'W': 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': ip = item_by_name(key); arg = LIMIT_TO(arg, 0, lchr[land->lnd_type].l_item[ip->i_uid]); land->lnd_item[ip->i_uid] = arg; 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); coord newx, newy; switch (*key) { case 'U': ef_set_uid(EF_PLANE, plane, arg); break; case 'l': if (!sarg_xy(p, &newx, &newy)) return RET_SYN; plane->pln_x = newx; plane->pln_y = newy; break; case 'O': if (arg < 0 || arg >= MAXNOC) return RET_SYN; if (arg == plane->pln_own) break; if (plane->pln_own && plane->pln_own != player->cnum) wu(0, plane->pln_own, "%s taken from you by an act of %s!\n", prplane(plane), cname(player->cnum)); if (arg && arg != player->cnum) wu(0, arg, "%s given to you by an act of %s!\n", prplane(plane), cname(player->cnum)); plane->pln_own = arg; break; case 'e': plane->pln_effic = LIMIT_TO(arg, PLANE_MINEFF, 100); break; case 'm': plane->pln_mobil = LIMIT_TO(arg, -127, 127); break; case 't': arg = LIMIT_TO(arg, pcp->pl_tech, SHRT_MAX); pln_set_tech(plane, arg); break; case 'w': if (p[0] == '~') plane->pln_wing = 0; else if (isalpha(p[0])) plane->pln_wing = p[0]; else { pr("%c: invalid wing\n", p[0]); return RET_FAIL; } break; case 'r': arg = LIMIT_TO(arg, 0, pl_range(pcp, plane->pln_tech)); plane->pln_range = (unsigned char)arg; break; case 's': if (arg < -1 || arg >= ef_nelem(EF_SHIP)) return RET_SYN; if (arg >= 0 && arg != plane->pln_ship) plane->pln_land = -1; plane->pln_ship = arg; break; case 'y': if (arg < -1 || arg >= ef_nelem(EF_LAND)) return RET_SYN; if (arg >= 0 && arg != plane->pln_land) plane->pln_ship = -1; plane->pln_land = arg; break; case 'f': plane->pln_flags = arg; break; default: pr("huh? (%s)\n", key); return RET_FAIL; } return RET_OK; }