]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/edit.c
edit: Generalize edit to multiple objects
[empserver] / src / lib / commands / edit.c
index 1de7ea46d47d52146538f576f1ea96f9246df6c0..dacf508fc211820966ad67a61f4d004cfaf0629e 100644 (file)
@@ -63,157 +63,125 @@ static int edit_plane(struct plnstr *, char *, char *);
 int
 edit(void)
 {
-    struct sctstr sect;
-    struct plnstr plane;
-    struct shpstr ship;
-    struct lndstr land;
+    union empobj_storage item;
     char *what;
+    struct nstr_item ni;
     char *key, *ptr;
-    int num;
-    int err;
-    int arg_index = 3;
-    coord x, y;
     struct natstr *np;
+    int type, arg_index, ret;
     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) {
+    switch (what[0]) {
     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, &sect))
-           return RET_FAIL;
-       break;
-    case 'c':
-       np = natargp(player->argp[2], "Country? ");
-       if (!np)
-           return RET_SYN;
+       type = EF_SECTOR;
        break;
     case 'p':
-       if ((num = onearg(player->argp[2], "Plane number? ")) < 0)
-           return RET_SYN;
-       if (!getplane(num, &plane))
-           return RET_SYN;
+       type = EF_PLANE;
        break;
     case 's':
-       if ((num = onearg(player->argp[2], "Ship number? ")) < 0)
-           return RET_SYN;
-       if (!getship(num, &ship))
-           return RET_SYN;
+       type = EF_SHIP;
        break;
     case 'u':
-       if ((num = onearg(player->argp[2], "Unit number? ")) < 0)
-           return RET_SYN;
-       if (!getland(num, &land))
-           return RET_SYN;
+       type = EF_LAND;
        break;
     case 'n':
        pr("Not implemented yet.\n");
+       return RET_FAIL;
+    case 'c':
+       type = EF_NATION;
        break;
     default:
        pr("huh?\n");
        return RET_SYN;
     }
-    if (!player->argp[3]) {
-       switch (ewhat) {
-       case 'l':
-           print_sect(&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;
+
+    if (!snxtitem(&ni, type, player->argp[2], NULL))
+       return RET_SYN;
+    while (nxtitem(&ni, &item)) {
+       if (!player->argp[3]) {
+           switch (type) {
+           case EF_SECTOR:
+               print_sect(&item.sect);
+               break;
+           case EF_SHIP:
+               print_ship(&item.ship);
+               break;
+           case EF_PLANE:
+               print_plane(&item.plane);
+               break;
+           case EF_LAND:
+               print_land(&item.land);
+               break;
+           case EF_NATION:
+               print_nat(&item.nat);
+               break;
+           default:
+               CANT_REACH();
+           }
        }
-    }
-    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(&sect);
-                   break;
-               case 's':
-                   print_ship(&ship);
-                   break;
-               case 'u':
-                   print_land(&land);
-                   break;
-               case 'p':
-                   print_plane(&plane);
+
+       arg_index = 3;
+       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)
                    break;
-               }
-               return RET_OK;
-           }
-       } else
-           return RET_OK;
+           } else
+               break;
 
-       switch (ewhat) {
-       case 'c':
-           if ((err = edit_nat(np, key, ptr)) != RET_OK)
-               return err;
-           break;
-       case 'l':
-           if (!check_sect_ok(&sect))
-               return RET_FAIL;
-           if ((err = edit_sect(&sect, key, ptr)) != RET_OK)
-               return err;
-           if (!putsect(&sect))
-               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 (!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 (!putland(land.lnd_uid, &land))
+           if (!check_obj_ok(&item.gen))
                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 (!putplane(plane.pln_uid, &plane))
+           switch (type) {
+           case EF_NATION:
+               /*
+                * edit_nat() may update the edited country by sending
+                * it bulletins.  Writing back item.nat would trigger
+                * a seqno mismatch oops.  Workaround: edit in-place.
+                */
+               np = getnatp(item.nat.nat_cnum);
+               ret = edit_nat(np, key, ptr);
+               if (ret != RET_OK)
+                   return ret;
+               if (!putnat(np))
+                   return RET_FAIL;
+               item.nat = *np;
+               continue;
+           case EF_SECTOR:
+               ret = edit_sect(&item.sect, key, ptr);
+               break;
+           case EF_SHIP:
+               ret = edit_ship(&item.ship, key, ptr);
+               break;
+           case EF_LAND:
+               ret = edit_land(&item.land, key, ptr);
+               break;
+           case EF_PLANE:
+               ret = edit_plane(&item.plane, key, ptr);
+               break;
+           default:
+               CANT_REACH();
+           }
+           if (ret != RET_OK)
+               return ret;
+           if (!put_empobj(type, item.gen.uid, &item.gen))
                return RET_FAIL;
-           break;
        }
     }
+
+    return RET_OK;
 }
 
 static void
@@ -656,6 +624,9 @@ edit_nat(struct natstr *np, char *key, char *p)
        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':
@@ -709,7 +680,11 @@ edit_nat(struct natstr *np, char *key, char *p)
        np->nat_yorg = newy;
        break;
     case 's':
-       np->nat_stat = LIMIT_TO(arg, STAT_UNUSED, STAT_GOD);
+       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);
@@ -740,7 +715,6 @@ edit_nat(struct natstr *np, char *key, char *p)
        pr("huh? (%s)\n", key);
        break;
     }
-    putnat(np);
     return RET_OK;
 }