]> git.pond.sub.org Git - empserver/blob - src/lib/commands/edit.c
(at_minimum, blocksig, emp_bitinit, filelogerror, iceil, ifloor,
[empserver] / src / lib / commands / edit.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  edit.c: Edit things (sectors, ships, planes, units, nukes, countries)
29  * 
30  *  Known contributors to this file:
31  *     David Muir Sharnoff
32  *     Chad Zabel, 1994
33  *     Steve McClure, 1998-2000
34  *     Ron Koenderink, 2003
35  */
36
37 #include <stdio.h>
38 #include <ctype.h>
39 #ifdef Rel4
40 #include <string.h>
41 #endif /* Rel4 */
42 #include "misc.h"
43 #include "player.h"
44 #include "var.h"
45 #include "xy.h"
46 #include "sect.h"
47 #include "nat.h"
48 #include "news.h"
49 #include "nsc.h"
50 #include "item.h"
51 #include "file.h"
52 #include "plane.h"
53 #include "ship.h"
54 #include "land.h"
55 #include "optlist.h"
56 #include "commands.h"
57
58 #define END -1
59
60 static void benefit(natid who, int good);
61 static int docountry(s_char op, int arg, s_char *p, float farg, natid nat,
62                      struct natstr *np);
63 static int doland(s_char op, int arg, s_char *p, struct sctstr *sect);
64 static int doplane(s_char op, int arg, s_char *p, struct plnstr *plane);
65 static int doship(s_char op, int arg, s_char *p, struct shpstr *ship);
66 static int dounit(s_char op, int arg, s_char *p, struct lndstr *land);
67 static int getin(s_char **, s_char **, int *, s_char *);
68 static void noise(struct sctstr *sptr, int public_amt, s_char *name,
69                   int old, int new);
70 static void pr_land(struct lndstr *land);
71 static void pr_plane(struct plnstr *plane);
72 static void pr_ship(struct shpstr *ship);
73 static void prnat(natid n);
74 static void prsect(struct sctstr *sect);
75
76
77 int
78 edit(void)
79 {
80     struct sctstr sect;
81     struct plnstr plane;
82     struct shpstr ship;
83     struct lndstr land;
84     s_char *what;
85     s_char *ptr;
86     s_char *thing;
87     int num;
88     int arg;
89     int err;
90     int arg_index = 3;
91     coord x, y;
92     float farg;
93     natid nat;
94     struct natstr *np;
95     s_char buf[1024];
96     s_char ewhat;               /* saves information from the command line
97                                    for use later on.                         */
98
99     if ((what = getstarg(player->argp[1],
100                          "Edit What (country, land, ship, plane, nuke, unit)? ",
101                          buf)) == 0)
102         return RET_SYN;
103     ewhat = what[0];
104     switch (ewhat) {
105     case 'l':
106         if (!(ptr = getstarg(player->argp[2], "Sector : ", buf)))
107             return RET_FAIL;
108         if (!sarg_xy(ptr, &x, &y))
109             return RET_FAIL;
110         if (!getsect(x, y, &sect))
111             return RET_FAIL;
112         break;
113     case 'c':
114         if ((num = natarg(player->argp[2], "Country number? ")) < 0)
115             return RET_SYN;
116         nat = (natid)num;
117         np = getnatp(nat);
118         break;
119     case 'p':
120         if ((num = onearg(player->argp[2], "Plane number? ")) < 0)
121             return RET_SYN;
122         if (!getplane(num, &plane))
123             return RET_SYN;
124         break;
125     case 's':
126         if ((num = onearg(player->argp[2], "Ship number? ")) < 0)
127             return RET_SYN;
128         if (!getship(num, &ship))
129             return RET_SYN;
130         break;
131     case 'u':
132         if ((num = onearg(player->argp[2], "Unit number? ")) < 0)
133             return RET_SYN;
134         if (!getland(num, &land))
135             return RET_SYN;
136         break;
137     case 'n':
138         pr("Not implemented yet.\n");
139         break;
140     default:
141         pr("huh?\n");
142         return RET_SYN;
143     }
144     if (player->argp[3] == 0) {
145         switch (ewhat) {
146         case 'l':
147             prsect(&sect);
148             break;
149         case 'c':
150             prnat(nat);
151             break;
152         case 'p':
153             pr_plane(&plane);
154             break;
155         case 's':
156             pr_ship(&ship);
157             break;
158         case 'u':
159             pr_land(&land);
160             break;
161         }
162     }
163     ptr = &buf[0];
164     *ptr = 0;
165     for (;;) {
166         if (player->argp[arg_index] != 0) {
167             if (player->argp[arg_index+1] != 0) {
168                 thing = player->argp[arg_index++];
169                 ptr = player->argp[arg_index++];
170                 arg = atoi(ptr);
171             } else
172                 return RET_SYN;
173         } else if (arg_index == 3) {
174             if ((err = getin(&thing, &ptr, &arg, buf)) != RET_OK) {
175                 if (err == END) {
176                     switch (ewhat) {
177                     case 'c':
178                         prnat(nat);
179                         break;
180                     case 'l':
181                         prsect(&sect);
182                         break;
183                     case 's':
184                         pr_ship(&ship);
185                         break;
186                     case 'u':
187                         pr_land(&land);
188                         break;
189                     case 'p':
190                         pr_plane(&plane);
191                         break;
192                     }
193                     break;
194                 } else
195                     return err;
196             }
197         } else
198             break;
199         switch (ewhat) {
200         case 'c':
201             farg = atof(ptr);
202             if ((err = docountry(thing[0], arg, ptr, farg, nat, np))
203                 != RET_OK)
204                 return err;
205             break;
206         case 'l':
207             if ((err = doland(thing[0], arg, ptr, &sect)) != RET_OK)
208                 return err;
209             if (!putsect(&sect))
210                 return RET_FAIL;
211             break;
212         case 's':
213             if ((err = doship(thing[0], arg, ptr, &ship)) != RET_OK)
214                 return err;
215             if (!putship(ship.shp_uid, &ship))
216                 return RET_FAIL;
217             break;
218         case 'u':
219             if ((err = dounit(thing[0], arg, ptr, &land))
220                 != RET_OK)
221                 return err;
222             if (!putland(land.lnd_uid, &land))
223                 return RET_FAIL;
224             break;
225         case 'p':
226             if ((err = doplane(thing[0], arg, ptr, &plane))
227                 != RET_OK)
228                 return err;
229             if (!putplane(plane.pln_uid, &plane))
230                 return RET_FAIL;
231             break;
232         }
233         if (err != RET_OK)
234             break;
235         else
236             ptr = 0;
237     }
238     return RET_OK;
239 }
240
241 static void
242 benefit(natid who, int good)
243 {
244     if (!opt_GODNEWS)
245         return;
246
247     if (good) {
248         if (who)
249             nreport(player->cnum, N_AIDS, who, 1);
250     } else {
251         if (who)
252             nreport(player->cnum, N_HURTS, who, 1);
253     }
254 }
255
256 static void
257 noise(struct sctstr *sptr, int public_amt, s_char *name, int old, int new)
258 {
259     s_char p[100];
260
261     pr("%s of %s changed from %d to %d\n",
262        name, xyas(sptr->sct_x, sptr->sct_y, player->cnum), old, new);
263     if (public_amt)
264         (void)sprintf(p, "changed from %d to %d", old, new);
265     else
266         (void)sprintf(p, "%s", (old < new ? "increased" : "decreased"));
267     if (sptr->sct_own)
268         wu(player->cnum, sptr->sct_own,
269            "%s in %s was %s by an act of %s\n",
270            name, xyas(sptr->sct_x, sptr->sct_y, sptr->sct_own),
271            p, cname(player->cnum));
272     benefit(sptr->sct_own, (old < new));
273 }
274
275 static void
276 prsect(struct sctstr *sect)
277 {
278     pr("Location <L>: %s\t", xyas(sect->sct_x, sect->sct_y, player->cnum));
279     pr("Distribution sector <D>: %s\n",
280        xyas(sect->sct_dist_x, sect->sct_dist_y, player->cnum));
281     pr("Designation <s>: %c\t New designation <S>: %c\n",
282        dchr[sect->sct_type].d_mnem, dchr[sect->sct_newtype].d_mnem);
283     pr("own  oo eff mob min gld frt oil urn wrk lty  che plg ptime fall avail\n");
284     pr("  o   O   e   m   i   g   f   c   u   w   l    x   p     t    F     a\n");
285     pr("%3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %4d %3d %5d %4d %5d\n",
286        sect->sct_own, sect->sct_oldown, sect->sct_effic, sect->sct_mobil,
287        sect->sct_min, sect->sct_gmin, sect->sct_fertil, sect->sct_oil,
288        sect->sct_uran, sect->sct_work, sect->sct_loyal,
289        getvar(V_CHE, (s_char *)sect, EF_SECTOR),
290        getvar(V_PSTAGE, (s_char *)sect, EF_SECTOR),
291        getvar(V_PTIME, (s_char *)sect, EF_SECTOR),
292        getvar(V_FALLOUT, (s_char *)sect, EF_SECTOR), sect->sct_avail);
293
294     pr("Mines <M>: %d\t", getvar(V_MINE, (s_char *)sect, EF_SECTOR));
295     pr("Coastal <C>: %d\n", sect->sct_coastal);
296     pr("Road %% <R>: %d\t", sect->sct_road);
297     pr("Rail %% <r>: %d\t", sect->sct_rail);
298     pr("Defense %% <d>: %d\n", sect->sct_defense);
299 }
300
301
302 static void
303 prnat(natid n)
304 {
305     struct natstr *np;
306     int i;
307
308     if ((np = getnatp(n)) == 0)
309         return;
310     pr("Country #: %2d\n", n);
311     pr("Name <n>: %-20s\t", np->nat_cnam);
312     pr("Connected: %d\n", np->nat_connected);
313     pr("Representative <r>: %-20s\n", np->nat_pnam);
314     pr("BTUs <b>: %3d\t\t\t", np->nat_btu);
315     pr("Reserves <m>: %5d\n", np->nat_reserve);
316     pr("Capital <c>: %s\t\t",
317        xyas(np->nat_xcap, np->nat_ycap, player->cnum));
318     pr("Origin <o>: %3s\n",
319        xyas(np->nat_xorg, np->nat_yorg, player->cnum));
320     pr("Status <s>: 0x%x\t\t\t", np->nat_stat);
321     pr("Min Used <u>: %3d\n", np->nat_minused);
322     pr("Technology <T>: %.2f\t\t", np->nat_level[NAT_TLEV]);
323     pr("Research <R>: %.2f\n", np->nat_level[NAT_RLEV]);
324     pr("Education <E>: %.2f\t\t", np->nat_level[NAT_ELEV]);
325     pr("Happiness <H>: %.2f\n", np->nat_level[NAT_HLEV]);
326     pr("Money <M>: $%6d\n", np->nat_money);
327     pr("Telegrams <t>: %6d\n", np->nat_tgms);
328     if (opt_DEMANDUPDATE)
329         pr("Updates missed <U>: %d\n", np->nat_missed);
330     if (opt_HIDDEN) {
331         pr("Countries contacted: ");
332         for (i = 0; i < MAXNOC; i++) {
333             if (getcontact(np, i))
334                 pr("%d(%d) ", i, getcontact(np, i));
335         }
336         pr("\n");
337     }
338 }
339
340 static void
341 pr_plane(struct plnstr *plane)
342 {
343     pr("UID <U>: %d\t\t", (int)plane->pln_uid);
344     pr("Owner <O>: %d\t\t", (int)plane->pln_own);
345     pr("Location <l>: %s\n",
346        xyas(plane->pln_x, plane->pln_y, player->cnum));
347     pr("Efficiency <e>: %d\t", (int)plane->pln_effic);
348     pr("Mobility <m>: %d\n", (int)plane->pln_mobil);
349     pr("Tech <t>: %d\t\t", plane->pln_tech);
350     pr("Wing <w>: %c\n", plane->pln_wing);
351     pr("Attack <a>: %d\t\t", plane->pln_att);
352     pr("Defense <d>: %d\n", plane->pln_def);
353     pr("Range <r>: %d\t\t", plane->pln_range);
354     pr("Flags <f>: %d\n", plane->pln_flags);
355     pr("Ship <s>: %d\t\t", plane->pln_ship);
356     pr("Land Unit <y>: %d\t", plane->pln_land);
357     pr("Nuke Type <n>: %d\n", plane->pln_nuketype);
358 }
359
360 static void
361 pr_land(struct lndstr *land)
362 {
363     int vec[I_MAX + 1];
364     struct lchrstr *lcp;
365
366     lcp = &lchr[(int)land->lnd_type];
367     pr("UID <U>: %d\n", (int)land->lnd_uid);
368     pr("Owner <O>: %d\n", (int)land->lnd_own);
369     pr("Location <L>: %s\n", xyas(land->lnd_x, land->lnd_y, player->cnum));
370     pr("Efficiency <e>: %d\t", (int)land->lnd_effic);
371     pr("Mobility <M>: %d\n", (int)land->lnd_mobil);
372     pr("Tech <t>: %d\t\t", land->lnd_tech);
373     pr("Army <a>: %c\n", land->lnd_army);
374     pr("Attack: %f\t", lcp->l_att);
375     pr("Defense: %f\n", lcp->l_def);
376     pr("Fortification <F>: %d\t", land->lnd_harden);
377     pr("Fuel <B>: %d\n", land->lnd_fuel);
378     count_land_planes(land);
379     pr("Xlight planes <X>: %d\n", land->lnd_nxlight);
380     pr("Land unit <Y>: %d\n", land->lnd_land);
381     pr("Ship <S>: %d\t\t", land->lnd_ship);
382     pr("Radius <P>: %d\n", land->lnd_rad_max);
383     pr("Retreat percentage <Z>: %d\n", (int)land->lnd_retreat);
384     pr("Retreat path <R>: '%s'\t\tRetreat Flags <W>: %d\n",
385        land->lnd_rpath, (int)land->lnd_rflags);
386     getvec(VT_ITEM, vec, (s_char *)land, EF_LAND);
387     pr("civ mil  uw food shl gun  pet  irn  dst  oil  lcm  hcm rad\n");
388     pr("  c   m   u    f   s   g    p    i    d    o    l    h   r\n");
389     pr("%3d", vec[I_CIVIL]);
390     pr("%4d", vec[I_MILIT]);
391     pr("%4d", vec[I_UW]);
392     pr("%5d", vec[I_FOOD]);
393     pr("%4d", vec[I_SHELL]);
394     pr("%4d", vec[I_GUN]);
395     pr("%5d", vec[I_PETROL]);
396     pr("%5d", vec[I_IRON]);
397     pr("%5d", vec[I_DUST]);
398     pr("%5d", vec[I_OIL]);
399     pr("%5d", vec[I_LCM]);
400     pr("%5d", vec[I_HCM]);
401     pr("%4d", vec[I_RAD]);
402     pr("\n");
403 }
404
405 static void
406 pr_ship(struct shpstr *ship)
407 {
408     int vec[I_MAX + 1];
409     struct natstr *natp;
410
411     if ((natp = getnatp(ship->shp_own)) == 0)
412         return;
413     pr("%s (#%d) %s\n", natp->nat_cnam, (int)ship->shp_own, prship(ship));
414     pr("UID <U>: %d\n", (int)ship->shp_uid);
415     pr("Owner <O>: %d\t\t\t", (int)ship->shp_own);
416     pr("Location <L>: %s\n", xyas(ship->shp_x, ship->shp_y, player->cnum));
417     pr("Tech <T>: %d\t\t\t", ship->shp_tech);
418     pr("Efficiency <E>: %d\n", (int)ship->shp_effic);
419     pr("Mobility <M>: %d\t\t\t", (int)ship->shp_mobil);
420     pr("Fleet <F>: %c\n", ship->shp_fleet);
421     count_planes(ship);
422     pr("Helos <H>: %d\n", (int)ship->shp_nchoppers);
423     pr("Xlight planes <X>: %d\n", (int)ship->shp_nxlight);
424     pr("Planes <P>: %d\n", (int)ship->shp_nplane);
425     count_units(ship);
426     pr("Units <Y>: %d\n", (int)ship->shp_nland);
427     /* could depend on opt_FUEL - but a deity might want to set this
428        up before enabling the option */
429     pr("Fuel <B>: %d\n", (int)ship->shp_fuel);
430     pr("Retreat path <R>: '%s'\t\tRetreat Flags <W>: %d\n",
431        ship->shp_rpath, (int)ship->shp_rflags);
432     getvec(VT_ITEM, vec, (s_char *)ship, EF_SHIP);
433     pr("Plague Stage <a>: %d\n",
434        getvar(V_PSTAGE, (s_char *)ship, EF_SHIP));
435     pr("Plague Time <b>: %d\n", getvar(V_PTIME, (s_char *)ship, EF_SHIP));
436     pr("civ mil  uw food shl gun  pet  irn  dst  oil  lcm  hcm rad\n");
437     pr("  c   m   u    f   s   g    p    i    d    o    l    h   r\n");
438     pr("%3d", vec[I_CIVIL]);
439     pr("%4d", vec[I_MILIT]);
440     pr("%4d", vec[I_UW]);
441     pr("%5d", vec[I_FOOD]);
442     pr("%4d", vec[I_SHELL]);
443     pr("%4d", vec[I_GUN]);
444     pr("%5d", vec[I_PETROL]);
445     pr("%5d", vec[I_IRON]);
446     pr("%5d", vec[I_DUST]);
447     pr("%5d", vec[I_OIL]);
448     pr("%5d", vec[I_LCM]);
449     pr("%5d", vec[I_HCM]);
450     pr("%4d", vec[I_RAD]);
451     pr("\n");
452 }
453
454 static int
455 errcheck(int num, int min, int max)
456 {
457     if (num < min)
458         return (min);
459     else if (num > max)
460         return (max);
461     return (num);
462 }
463
464 static int
465 getin(s_char **what, s_char **p, int *arg, s_char *buf)
466 {
467     if (!(*what = getstarg(*p, "%c xxxxx -- thing value : ", buf))) {
468         return RET_SYN;
469     }
470     if (**what == '\0')
471         return END;
472     while (**what && isspace(**what))
473         (*what)++;
474     if (**what == '\0')
475         return RET_SYN;
476     for (*p = *what; **p && !isspace(**p); (*p)++)      /* skip non spaces */
477         continue;
478     while (**p && isspace(**p))
479         (*p)++;
480     if (**p == '\0')
481         return RET_SYN;
482     *arg = atoi(*p);
483     return RET_OK;
484 }
485
486
487 static int
488 doland(s_char op, int arg, s_char *p, struct sctstr *sect)
489 {
490     natid newown, oldown;
491     coord newx, newy;
492     int new, old;
493     int des;
494     switch (op) {
495     case 'C':
496         if (arg < 0)
497             return RET_SYN;
498         sect->sct_coastal = (arg ? 1 : 0);
499         pr("Coastal flag of %s changed to %d\n",
500            xyas(sect->sct_x, sect->sct_y, player->cnum),
501            sect->sct_coastal);
502         break;
503     case 'o':
504         if (arg < 0)
505             return RET_SYN;
506         newown = (natid)errcheck(arg, 0, MAXNOC - 1);
507         pr("Owner of %s changed from %s (#%d) to %s (#%d).\n",
508            xyas(sect->sct_x, sect->sct_y, player->cnum),
509            cname(sect->sct_own), sect->sct_own, cname(newown), newown);
510         if (sect->sct_own) {
511             makelost(EF_SECTOR, sect->sct_own, 0, sect->sct_x,
512                      sect->sct_y);
513             wu(player->cnum, sect->sct_own,
514                "Sector %s lost to deity intervention\n", xyas(sect->sct_x,
515                                                               sect->sct_y,
516                                                               sect->
517                                                               sct_own));
518         }
519         benefit(sect->sct_own, 0);
520         sect->sct_own = newown;
521         if (newown) {
522             makenotlost(EF_SECTOR, newown, 0, sect->sct_x, sect->sct_y);
523             wu(player->cnum, newown,
524                "Sector %s gained from deity intervention\n",
525                xyas(sect->sct_x, sect->sct_y, sect->sct_own));
526         }
527         benefit(newown, 1);
528         break;
529     case 'O':
530         if (arg < 0)
531             return RET_SYN;
532         oldown = (natid)errcheck(arg, 0, MAXNOC - 1);
533         pr("Old player->owner of %s changed from %s (#%d) to %s (#%d).\n",
534            xyas(sect->sct_x, sect->sct_y, player->cnum),
535            cname(sect->sct_oldown),
536            sect->sct_oldown, cname(oldown), oldown);
537         sect->sct_oldown = oldown;
538         break;
539     case 'e':
540         new = errcheck(arg, 0, 100);
541         noise(sect, 1, "Efficiency", (int)sect->sct_effic, new);
542         sect->sct_effic = (u_char)new;
543         break;
544     case 'm':
545         new = errcheck(arg, -127, 255);
546         noise(sect, 1, "Mobility", (int)sect->sct_mobil, new);
547         sect->sct_mobil = new;
548         break;
549     case 'i':
550         new = errcheck(arg, 0, 127);
551         noise(sect, 1, "Iron ore content", (int)sect->sct_min, new);
552         sect->sct_min = (u_char)new;
553         break;
554     case 'g':
555         new = errcheck(arg, 0, 127);
556         noise(sect, 1, "Gold content", (int)sect->sct_gmin, new);
557         sect->sct_gmin = (u_char)new;
558         break;
559     case 'f':
560         new = errcheck(arg, 0, 127);
561         noise(sect, 1, "Fertility", (int)sect->sct_fertil, new);
562         sect->sct_fertil = (u_char)new;
563         break;
564     case 'c':
565         new = errcheck(arg, 0, 127);
566         noise(sect, 1, "Oil content", (int)sect->sct_oil, new);
567         sect->sct_oil = (u_char)new;
568         break;
569     case 'u':
570         new = errcheck(arg, 0, 127);
571         noise(sect, 1, "Uranium content", (int)sect->sct_uran, new);
572         sect->sct_uran = (u_char)new;
573         break;
574     case 'w':
575         new = errcheck(arg, 0, 100);
576         noise(sect, 1, "Workforce percentage", (int)sect->sct_work, new);
577         sect->sct_work = (u_char)new;
578         break;
579     case 'l':
580         new = errcheck(arg, 0, 127);
581         pr("Loyalty of %s changed from %d to %d%%\n",
582            xyas(sect->sct_x, sect->sct_y, player->cnum),
583            sect->sct_loyal, new);
584         sect->sct_loyal = (u_char)new;
585         break;
586     case 'x':
587         old = getvar(V_CHE, (s_char *)sect, EF_SECTOR);
588         new = errcheck(arg, 0, 65536);
589         pr("Guerillas in %s changed from %d to %d%\n",
590            xyas(sect->sct_x, sect->sct_y, player->cnum), old, new);
591         putvar(V_CHE, new, (s_char *)sect, EF_SECTOR);
592         break;
593     case 'p':
594         old = getvar(V_PSTAGE, (s_char *)sect, EF_SECTOR);
595         new = errcheck(arg, 0, PLG_EXPOSED);
596         pr("Plague stage of %s changed from %d to %d%\n",
597            xyas(sect->sct_x, sect->sct_y, player->cnum), old, new);
598         putvar(V_PSTAGE, new, (s_char *)sect, EF_SECTOR);
599         break;
600     case 't':
601         old = getvar(V_PTIME, (s_char *)sect, EF_SECTOR);
602         new = errcheck(arg, 0, 255);
603         pr("Plague time of %s changed from %d to %d%\n",
604            xyas(sect->sct_x, sect->sct_y, player->cnum), old, new);
605         putvar(V_PTIME, new, (s_char *)sect, EF_SECTOR);
606         break;
607     case 'F':
608         old = getvar(V_FALLOUT, (s_char *)sect, EF_SECTOR);
609         new = errcheck(arg, 0, 9999);
610         pr("Fallout for sector %s changed from %d to %d\n",
611            xyas(sect->sct_x, sect->sct_y, player->cnum), old, new);
612         putvar(V_FALLOUT, new, (s_char *)sect, EF_SECTOR);
613         break;
614     case 'a':
615         new = errcheck(arg, 0, 9999);
616         noise(sect, 1, "Available workforce", (int)sect->sct_avail, new);
617         sect->sct_avail = new;
618         break;
619     case 'M':
620         putvar(V_MINE, arg, (s_char *)sect, EF_SECTOR);
621         pr("Mines changed to %d\n", arg);
622         break;
623     case 'L':
624         if (!sarg_xy(p, &newx, &newy))
625             return RET_SYN;
626         sect->sct_x = newx;
627         sect->sct_y = newy;
628         break;
629     case 'D':
630         if (!sarg_xy(p, &newx, &newy))
631             return RET_SYN;
632         pr("Distribtion Location for sector %s changed from %s to %s\n",
633            xyas(sect->sct_x, sect->sct_y, player->cnum),
634            xyas(sect->sct_dist_x, sect->sct_dist_y, player->cnum),
635            xyas(newx, newy, player->cnum));
636         sect->sct_dist_x = newx;
637         sect->sct_dist_y = newy;
638         break;
639     case 's':
640         des = typematch(p, EF_SECTOR);
641         if (des < 0)
642             return RET_SYN;
643         pr("Designation for sector %s changed from %c to %c\n",
644            xyas(sect->sct_x, sect->sct_y, player->cnum),
645            dchr[sect->sct_type].d_mnem, dchr[des].d_mnem);
646         sect->sct_type = des;
647         break;
648     case 'S':
649         des = typematch(p, EF_SECTOR);
650         if (des < 0)
651             return RET_SYN;
652         pr("New Designation for sector %s changed from %c to %c\n",
653            xyas(sect->sct_x, sect->sct_y, player->cnum),
654            dchr[sect->sct_newtype].d_mnem, dchr[des].d_mnem);
655         sect->sct_newtype = des;
656         break;
657     case 'R':
658         if (arg > 100)
659             arg = 100;
660         if (arg < 0)
661             arg = 0;
662         noise(sect, 1, "Road percentage", (int)sect->sct_road, arg);
663         sect->sct_road = arg;
664         break;
665     case 'r':
666         if (arg > 100)
667             arg = 100;
668         if (arg < 0)
669             arg = 0;
670         noise(sect, 1, "Rail percentage", (int)sect->sct_rail, arg);
671         sect->sct_rail = arg;
672         break;
673     case 'd':
674         if (arg > 100)
675             arg = 100;
676         if (arg < 0)
677             arg = 0;
678         noise(sect, 1, "Defense percentage", (int)sect->sct_defense, arg);
679         sect->sct_defense = arg;
680         break;
681     default:
682         pr("huh? (%c)\n", op);
683         return RET_SYN;
684     }
685     return RET_OK;
686 }
687
688
689 static int
690 docountry(s_char op, int arg, s_char *p, float farg, natid nat,
691           struct natstr *np)
692 {
693     extern int m_m_p_d;
694     coord newx, newy;
695     switch (op) {
696     case 'n':
697         pr("Country name changed from %s to %s\n", np->nat_cnam, p);
698         strncpy(np->nat_cnam, p, sizeof(np->nat_cnam) - 1);
699         break;
700     case 'r':
701         pr("Country representative changed from %s to %s\n",
702            np->nat_pnam, p);
703         strncpy(np->nat_pnam, p, sizeof(np->nat_pnam) - 1);
704         break;
705     case 't':
706         np->nat_tgms = arg;
707         break;
708     case 'b':
709         arg = errcheck(arg, 0, 1024);
710         pr("BTU's changed from %d to %d\n", np->nat_btu, arg);
711         np->nat_btu = arg;
712         break;
713     case 'm':
714         benefit(nat, np->nat_reserve < arg);
715         pr("Military Reserves changed from %d to %d\n",
716            np->nat_reserve, arg);
717         if (np->nat_stat == STAT_NORM)
718             wu(player->cnum, nat,
719                "Military Reserves changed from %d to %d by divine intervention.\n",
720                np->nat_reserve, arg);
721         np->nat_reserve = arg;
722         break;
723     case 'c':
724         if (!sarg_xy(p, &newx, &newy))
725             return RET_SYN;
726         pr("Capital coordinates changed from %s to %s\n",
727            xyas(np->nat_xcap, np->nat_ycap, player->cnum),
728            xyas(newx, newy, player->cnum));
729         np->nat_xcap = newx;
730         np->nat_ycap = newy;
731         break;
732     case 'o':
733         if (!sarg_xy(p, &newx, &newy))
734             return RET_SYN;
735         pr("Origin coordinates changed from %s to %s\n",
736            xyas(np->nat_xorg, np->nat_yorg, player->cnum),
737            xyas(newx, newy, player->cnum));
738         np->nat_xorg = newx;
739         np->nat_yorg = newy;
740         break;
741     case 's':
742         np->nat_stat = (s_char)errcheck(arg, 0, STAT_NEW);
743         break;
744     case 'u':
745         arg = errcheck(arg, 0, m_m_p_d);
746         pr("Number of minutes used changed from %d to %d.\n",
747            np->nat_minused, arg);
748         np->nat_minused = arg;
749         break;
750     case 'M':
751         pr("Money changed from %d to %d\n", np->nat_money, arg);
752         wu(player->cnum, nat,
753            "Money changed from %d to %d by divine intervention.\n",
754            np->nat_money, arg);
755         np->nat_money = arg;
756         break;
757     case 'T':
758         pr("Tech changed from %.2f to %.2f.\n",
759            np->nat_level[NAT_TLEV], farg);
760         np->nat_level[NAT_TLEV] = farg;
761         break;
762     case 'R':
763         pr("Research changed from %.2f to %.2f.\n",
764            np->nat_level[NAT_RLEV], farg);
765         np->nat_level[NAT_RLEV] = farg;
766         break;
767     case 'E':
768         pr("Education changed from %.2f to %.2f.\n",
769            np->nat_level[NAT_ELEV], farg);
770         np->nat_level[NAT_ELEV] = farg;
771         break;
772     case 'H':
773         pr("Happiness changed from %.2f to %.2f.\n",
774            np->nat_level[NAT_HLEV], farg);
775         np->nat_level[NAT_HLEV] = farg;
776         break;
777     case 'U':
778         np->nat_missed = arg;
779         break;
780     default:
781         pr("huh? (%c)\n", op);
782         break;
783     }
784     putnat(np);
785     return RET_OK;
786 }
787
788
789 static int
790 doship(s_char op, int arg, s_char *p, struct shpstr *ship)
791 {
792     coord newx, newy;
793
794     newx = newy = 0;
795     switch (op) {
796     case 'a':
797         putvar(V_PSTAGE, arg, (s_char *)ship, EF_SHIP);
798         break;
799     case 'b':
800         putvar(V_PTIME, arg, (s_char *)ship, EF_SHIP);
801         break;
802     case 'R':
803         bcopy(p, ship->shp_rpath, 10);
804         break;
805     case 'W':
806         ship->shp_rflags = arg;
807         break;
808     case 'H':
809         ship->shp_nchoppers = arg;
810         break;
811     case 'X':
812         ship->shp_nxlight = arg;
813         break;
814     case 'U':
815         ship->shp_uid = arg;
816         break;
817     case 'O':
818         if (ship->shp_own)
819             wu(player->cnum, ship->shp_own,
820                "%s taken from you by deity intervention!\n", prship(ship));
821         if (arg && arg < MAXNOC) {
822             wu(player->cnum, (natid)arg,
823                "%s given to you by deity intervention!\n", prship(ship));
824             makelost(EF_SHIP, ship->shp_own, ship->shp_uid, ship->shp_x,
825                      ship->shp_y);
826             ship->shp_own = (natid)arg;
827             makenotlost(EF_SHIP, ship->shp_own, ship->shp_uid, ship->shp_x,
828                         ship->shp_y);
829         } else if (!arg) {
830             ship->shp_effic = 0;
831             makelost(EF_SHIP, ship->shp_own, ship->shp_uid, ship->shp_x,
832                      ship->shp_y);
833             ship->shp_own = (natid)0;
834         }
835         break;
836     case 'L':
837         if (!sarg_xy(p, &newx, &newy))
838             return RET_SYN;
839         ship->shp_x = newx;
840         ship->shp_y = newy;
841         break;
842     case 'T':
843         ship->shp_tech = arg;
844         break;
845     case 'E':
846         ship->shp_effic = errcheck(arg, 0, 100);
847         if (arg < 10) {
848             ship->shp_effic = 0;
849             makelost(EF_SHIP, ship->shp_own, ship->shp_uid, ship->shp_x,
850                      ship->shp_y);
851             ship->shp_own = (natid)0;
852         }
853         break;
854     case 'M':
855         ship->shp_mobil = arg;
856         break;
857     case 'B':
858         ship->shp_fuel = errcheck(arg, 0, 255);
859         break;
860     case 'F':
861         if (p[0] == '~')
862             ship->shp_fleet = ' ';
863         else if (isalpha(p[0]))
864             ship->shp_fleet = p[0];
865         else {
866             pr("%c: invalid fleet\n", p[0]);
867             return RET_FAIL;
868         }
869         break;
870     case 'Y':
871         ship->shp_nland = errcheck(arg, 0, 100);
872         break;
873     case 'P':
874         ship->shp_nplane = errcheck(arg, 0, 100);
875         break;
876     case 'c':
877         if (!putvar(V_CIVIL, arg, (s_char *)ship, EF_SHIP)) {
878             pr("No room on ship!\n");
879             return RET_FAIL;
880         }
881         break;
882     case 'm':
883         if (!putvar(V_MILIT, arg, (s_char *)ship, EF_SHIP)) {
884             pr("No room on ship!\n");
885             return RET_FAIL;
886         }
887         break;
888     case 'u':
889         if (!putvar(V_UW, arg, (s_char *)ship, EF_SHIP)) {
890             pr("No room on ship!\n");
891             return RET_FAIL;
892         }
893         break;
894     case 'f':
895         if (!putvar(V_FOOD, arg, (s_char *)ship, EF_SHIP)) {
896             pr("No room on ship!\n");
897             return RET_FAIL;
898         }
899         break;
900     case 's':
901         if (!putvar(V_SHELL, arg, (s_char *)ship, EF_SHIP)) {
902             pr("No room on ship!\n");
903             return RET_FAIL;
904         }
905         break;
906     case 'g':
907         if (!putvar(V_GUN, arg, (s_char *)ship, EF_SHIP)) {
908             pr("No room on ship!\n");
909             return RET_FAIL;
910         }
911         break;
912     case 'p':
913         if (!putvar(V_PETROL, arg, (s_char *)ship, EF_SHIP)) {
914             pr("No room on ship!\n");
915             return RET_FAIL;
916         }
917         break;
918     case 'i':
919         if (!putvar(V_IRON, arg, (s_char *)ship, EF_SHIP)) {
920             pr("No room on ship!\n");
921             return RET_FAIL;
922         }
923         break;
924     case 'd':
925         if (!putvar(V_DUST, arg, (s_char *)ship, EF_SHIP)) {
926             pr("No room on ship!\n");
927             return RET_FAIL;
928         }
929         break;
930     case 'o':
931         if (!putvar(V_OIL, arg, (s_char *)ship, EF_SHIP)) {
932             pr("No room on ship!\n");
933             return RET_FAIL;
934         }
935         break;
936     case 'l':
937         if (!putvar(V_LCM, arg, (s_char *)ship, EF_SHIP)) {
938             pr("No room on ship!\n");
939             return RET_FAIL;
940         }
941         break;
942     case 'h':
943         if (!putvar(V_HCM, arg, (s_char *)ship, EF_SHIP)) {
944             pr("No room on ship!\n");
945             return RET_FAIL;
946         }
947         break;
948     case 'r':
949         if (!putvar(V_RAD, arg, (s_char *)ship, EF_SHIP)) {
950             pr("No room on ship!\n");
951             return RET_FAIL;
952         }
953         break;
954     default:
955         pr("huh? (%c)\n", op);
956         return RET_FAIL;
957     }
958     return RET_OK;
959 }
960
961 static int
962 dounit(s_char op, int arg, s_char *p, struct lndstr *land)
963 {
964     coord newx, newy;
965
966     newx = newy = 0;
967     switch (op) {
968     case 'Y':
969         land->lnd_land = arg;
970         break;
971     case 'U':
972         land->lnd_uid = arg;
973         break;
974     case 'O':
975         if (land->lnd_own)
976             wu(player->cnum, land->lnd_own,
977                "%s taken from you by deity intervention!\n", prland(land));
978
979         if (arg && arg < MAXNOC) {
980             wu(player->cnum, (natid)arg,
981                "%s given to you by deity intervention!\n", prland(land));
982             makelost(EF_LAND, land->lnd_own, land->lnd_uid, land->lnd_x,
983                      land->lnd_y);
984             land->lnd_own = (natid)arg;
985             makenotlost(EF_LAND, land->lnd_own, land->lnd_uid, land->lnd_x,
986                         land->lnd_y);
987         } else if (!arg) {
988             makelost(EF_LAND, land->lnd_own, land->lnd_uid, land->lnd_x,
989                      land->lnd_y);
990             land->lnd_effic = 0;
991             land->lnd_own = (natid)0;
992         }
993         break;
994     case 'L':
995         if (!sarg_xy(p, &newx, &newy))
996             return RET_SYN;
997         land->lnd_x = newx;
998         land->lnd_y = newy;
999         break;
1000     case 'e':
1001         land->lnd_effic = errcheck(arg, 0, 100);
1002         if (arg < 10) {
1003             makelost(EF_LAND, land->lnd_own, land->lnd_uid, land->lnd_x,
1004                      land->lnd_y);
1005             land->lnd_effic = 0;
1006             land->lnd_own = (natid)0;
1007         }
1008         break;
1009     case 'M':
1010         land->lnd_mobil = arg;
1011         break;
1012     case 't':
1013         land->lnd_tech = arg;
1014         break;
1015     case 'a':
1016         if (p[0] == '~')
1017             land->lnd_army = ' ';
1018         else if (isalpha(p[0]))
1019             land->lnd_army = p[0];
1020         else {
1021             pr("%c: invalid army\n", p[0]);
1022             return RET_FAIL;
1023         }
1024         break;
1025     case 'F':
1026         land->lnd_harden = errcheck(arg, 0, 255);
1027         break;
1028     case 'B':
1029         land->lnd_fuel = errcheck(arg, 0, 255);
1030         break;
1031     case 'X':
1032         land->lnd_nxlight = arg;
1033         break;
1034     case 'S':
1035         land->lnd_ship = arg;
1036         break;
1037     case 'P':
1038         land->lnd_rad_max = arg;
1039         break;
1040     case 'Z':
1041         land->lnd_retreat = arg;
1042         break;
1043     case 'R':
1044         bcopy(p, land->lnd_rpath, 10);
1045         break;
1046     case 'W':
1047         land->lnd_rflags = arg;
1048         break;
1049     case 'c':
1050         if (!putvar(V_CIVIL, arg, (s_char *)land, EF_LAND)) {
1051             pr("No room on land unit!\n");
1052             return RET_FAIL;
1053         }
1054         break;
1055     case 'm':
1056         if (!putvar(V_MILIT, arg, (s_char *)land, EF_LAND)) {
1057             pr("No room on land!\n");
1058             return RET_FAIL;
1059         }
1060         break;
1061     case 'u':
1062         if (!putvar(V_UW, arg, (s_char *)land, EF_LAND)) {
1063             pr("No room on land!\n");
1064             return RET_FAIL;
1065         }
1066         break;
1067     case 'f':
1068         if (!putvar(V_FOOD, arg, (s_char *)land, EF_LAND)) {
1069             pr("No room on land!\n");
1070             return RET_FAIL;
1071         }
1072         break;
1073     case 's':
1074         if (!putvar(V_SHELL, arg, (s_char *)land, EF_LAND)) {
1075             pr("No room on land!\n");
1076             return RET_FAIL;
1077         }
1078         break;
1079     case 'g':
1080         if (!putvar(V_GUN, arg, (s_char *)land, EF_LAND)) {
1081             pr("No room on land!\n");
1082             return RET_FAIL;
1083         }
1084         break;
1085     case 'p':
1086         if (!putvar(V_PETROL, arg, (s_char *)land, EF_LAND)) {
1087             pr("No room on land!\n");
1088             return RET_FAIL;
1089         }
1090         break;
1091     case 'i':
1092         if (!putvar(V_IRON, arg, (s_char *)land, EF_LAND)) {
1093             pr("No room on land!\n");
1094             return RET_FAIL;
1095         }
1096         break;
1097     case 'd':
1098         if (!putvar(V_DUST, arg, (s_char *)land, EF_LAND)) {
1099             pr("No room on land!\n");
1100             return RET_FAIL;
1101         }
1102         break;
1103     case 'o':
1104         if (!putvar(V_OIL, arg, (s_char *)land, EF_LAND)) {
1105             pr("No room on land!\n");
1106             return RET_FAIL;
1107         }
1108         break;
1109     case 'l':
1110         if (!putvar(V_LCM, arg, (s_char *)land, EF_LAND)) {
1111             pr("No room on land!\n");
1112             return RET_FAIL;
1113         }
1114         break;
1115     case 'h':
1116         if (!putvar(V_HCM, arg, (s_char *)land, EF_LAND)) {
1117             pr("No room on land!\n");
1118             return RET_FAIL;
1119         }
1120         break;
1121     case 'r':
1122         if (!putvar(V_RAD, arg, (s_char *)land, EF_LAND)) {
1123             pr("No room on land!\n");
1124             return RET_FAIL;
1125         }
1126         break;
1127     default:
1128         pr("huh? (%c)\n", op);
1129         return RET_FAIL;
1130     }
1131     return RET_OK;
1132 }
1133
1134
1135 int
1136 doplane(s_char op, int arg, s_char *p, struct plnstr *plane)
1137 {
1138     coord newx, newy;
1139
1140     switch (op) {
1141     case 'n':
1142         plane->pln_nuketype = arg;
1143         break;
1144     case 'U':
1145         plane->pln_uid = arg;
1146         break;
1147     case 'l':
1148         if (!sarg_xy(p, &newx, &newy))
1149             return RET_SYN;
1150         plane->pln_x = newx;
1151         plane->pln_y = newy;
1152         break;
1153     case 'O':
1154         if (plane->pln_own)
1155             wu(player->cnum, plane->pln_own,
1156                "%s taken from you by deity intervention!\n",
1157                prplane(plane));
1158         if (arg && arg < MAXNOC) {
1159             makelost(EF_PLANE, plane->pln_own, plane->pln_uid,
1160                      plane->pln_x, plane->pln_y);
1161             plane->pln_own = (natid)arg;
1162             makenotlost(EF_PLANE, plane->pln_own, plane->pln_uid,
1163                         plane->pln_x, plane->pln_y);
1164             wu(player->cnum, plane->pln_own,
1165                "%s given to you by deity intervention!\n", prplane(plane));
1166         } else if (!arg) {
1167             plane->pln_effic = 0;
1168             makelost(EF_PLANE, plane->pln_own, plane->pln_uid,
1169                      plane->pln_x, plane->pln_y);
1170             plane->pln_own = (natid)0;
1171         }
1172         break;
1173     case 'e':
1174         plane->pln_effic = errcheck(arg, 0, 100);
1175         if (arg < 10) {
1176             plane->pln_effic = 0;
1177             makelost(EF_PLANE, plane->pln_own, plane->pln_uid,
1178                      plane->pln_x, plane->pln_y);
1179             plane->pln_own = (natid)0;
1180         }
1181         break;
1182     case 'm':
1183         plane->pln_mobil = errcheck(arg, -127, 255);
1184         break;
1185     case 't':
1186         plane->pln_tech = arg;
1187         break;
1188     case 'w':
1189         if (p[0] == '~')
1190             plane->pln_wing = ' ';
1191         else if (isalpha(p[0]))
1192             plane->pln_wing = p[0];
1193         else {
1194             pr("%c: invalid wing\n", p[0]);
1195             return RET_FAIL;
1196         }
1197         break;
1198     case 'a':
1199         plane->pln_att = (s_char)errcheck(arg, 0, 127);
1200         break;
1201     case 'd':
1202         plane->pln_def = (s_char)arg;
1203         break;
1204     case 'r':
1205         plane->pln_range = (u_char)arg;
1206         break;
1207     case 's':
1208         plane->pln_ship = arg;
1209         break;
1210     case 'y':
1211         plane->pln_land = arg;
1212         break;
1213     case 'f':
1214         plane->pln_flags = arg;
1215         break;
1216     default:
1217         pr("huh? (%c)\n", op);
1218         return RET_FAIL;
1219     }
1220     return RET_OK;
1221 }