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