]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/retr.c
Update copyright notice
[empserver] / src / lib / commands / retr.c
index fef389506da06350116fa2aea0f235f53615ee66..abfbd5c7bff217a222bcb734b443d2155030fac4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2012, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2018, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                Ken Stevens, Steve McClure, Markus Armbruster
  *
  *  Empire is free software: you can redistribute it and/or modify
@@ -29,7 +29,7 @@
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 2000
- *     Markus Armbruster, 2008-2010
+ *     Markus Armbruster, 2008-2015
  */
 
 #include <config.h>
@@ -38,6 +38,7 @@
 #include "commands.h"
 #include "empobj.h"
 #include "land.h"
+#include "path.h"
 #include "retreat.h"
 #include "ship.h"
 
@@ -50,6 +51,7 @@ static char shp_rflagsc[] = "Xitshbdu";
 static char lnd_rflagsc[] = "XiXXhbXX";
 
 static int retreat(int);
+static int retreat_show(int, struct nstr_item *);
 
 int
 retr(void)
@@ -70,10 +72,8 @@ retreat(int type)
     int nunits;
     struct nstr_item ni;
     union empobj_storage unit;
-    int rflags, ch, j;
-    unsigned i;
-    char *rflagsc, *p, *name, *rpath, *what;
-    int *rflagsp;
+    int i, rflags, ch, j;
+    char *rflagsc, *p;
     char buf1[1024];
     char buf2[1024];
 
@@ -83,14 +83,38 @@ retreat(int type)
 
     if (!snxtitem(&ni, type, player->argp[1], NULL))
        return RET_SYN;
-    nunits = 0;
-    if (player->argp[2] != NULL)
-       pq = getstarg(player->argp[2], "Retreat path? ", buf1);
-    else
-       pq = NULL;
+
+    if (player->argp[1] && !player->argp[2]) {
+       pr("Omitting the second argument is deprecated and will cease to work in a\n"
+          "future release.  Please use '%s q' to query retreat orders.\n\n",
+          player->combuf);
+       pq = "q";
+    } else {
+       /*
+        * TODO getpath() or similar would be nice once the deprecated
+        * syntax is gone.
+        */
+       pq = getstarg(player->argp[2], "Retreat path, or q to query? ",
+                     buf1);
+       if (!pq || !*pq)
+           return RET_SYN;
+    }
+
+    if (*pq == 'q')
+       return retreat_show(type, &ni);
+
+    for (i = 0; i < RET_LEN - 1 && pq[i]; i++) {
+       if (chkdir(pq[i], DIR_STOP, DIR_LAST) < 0) {
+           pr("'%c' is not a valid direction...\n", pq[i]);
+           direrr(NULL, NULL, NULL);
+           return RET_SYN;
+       }
+    }
+    for (i--; i >= 0 && pq[i] == dirch[DIR_STOP]; i--)
+       pq[i] = 0;
 
     rflags = 0;
-    if (pq != NULL) {
+    if (*pq) {
     again:
        fl = getstarg(player->argp[3],
                      "Retreat conditions ('?' to list available ones)? ",
@@ -101,17 +125,17 @@ retreat(int type)
        for (i = 0; fl[i]; i++) {
            ch = tolower(fl[i]);
            if (ch == 'c') {
+               /* Deprecated, but keeping it around doesn't hurt */
                *pq = 0;
                break;
            }
-           if (ch == '?') {
+           if (ch == '?' && !player->argp[3]) {
                for (j = 1; rflagsc[j]; j++) {
                    if (rflagsc[j] != 'X')
                        pr("%c\tretreat when %s\n",
                           rflagsc[j],
                           symbol_by_value(1 << j, retreat_flags));
                }
-               pr("c\tcancel retreat order\n");
                goto again;
            }
            p = strchr(rflagsc, ch);
@@ -121,17 +145,51 @@ retreat(int type)
            }
            rflags |= 1 << (p - rflagsc);
        }
-       if (*pq && !rflags) {
-           pr("Must give retreat conditions!\n");
-           return RET_FAIL;
-       }
+       if (*pq && !rflags)
+           return RET_SYN;
        if (ni.sel == NS_GROUP && ni.group)
            rflags |= RET_GROUP;
        if (!*pq)
            rflags = 0;
     }
 
+    nunits = 0;
     while (nxtitem(&ni, &unit)) {
+       if (!player->owner || unit.gen.own == 0)
+           continue;
+       if (type == EF_SHIP) {
+           strncpy(unit.ship.shp_rpath, pq, RET_LEN - 1);
+           unit.ship.shp_rflags = rflags;
+       } else {
+           strncpy(unit.land.lnd_rpath, pq, RET_LEN - 1);
+           unit.land.lnd_rflags = rflags;
+       }
+       put_empobj(type, unit.gen.uid, &unit);
+       nunits++;
+    }
+    if (rflags) {
+       symbol_set_fmt(buf2, sizeof(buf2), rflags & ~RET_GROUP,
+                      retreat_flags, ", ", 0);
+       pr("%d %s%s ordered to retreat%s along path %s when %s\n",
+          nunits, ef_nameof_pretty(type), splur(nunits),
+          rflags & RET_GROUP ? " as group" : "", pq, buf2);
+    } else
+       pr("%d %s%s ordered not to retreat\n",
+          nunits, ef_nameof_pretty(type), splur(nunits));
+    return RET_OK;
+}
+
+static int
+retreat_show(int type, struct nstr_item *np)
+{
+    char *rflagsc = type == EF_SHIP ? shp_rflagsc : lnd_rflagsc;
+    union empobj_storage unit;
+    int nunits;
+    char *name, *rpath, *what;
+    int *rflagsp, rflags, i;
+
+    nunits = 0;
+    while (nxtitem(np, &unit)) {
        if (!player->owner || unit.gen.own == 0)
            continue;
        if (type == EF_SHIP) {
@@ -153,14 +211,9 @@ retreat(int type)
            rpath = unit.land.lnd_rpath;
            rflagsp = &unit.land.lnd_rflags;
        }
-       if (pq) {
-           strncpy(rpath, pq, RET_LEN - 1);
-           *rflagsp = rflags;
-           put_empobj(type, unit.gen.uid, &unit);
-       }
        if (player->god)
            pr("%3d ", unit.gen.own);
-       pr("%4d ", ni.cur);
+       pr("%4d ", np->cur);
        pr("%-16.16s ", name);
        prxy("%4d,%-4d ", unit.gen.x, unit.gen.y);
        pr("%1.1s", &unit.gen.group);
@@ -170,11 +223,11 @@ retreat(int type)
            pr("Yes      ");
        else
            pr("         ");
-       for (j = 1; rflagsc[j]; j++) {
-           if ((1 << j) & rflags) {
-               if (CANT_HAPPEN(rflagsc[j] == 'X'))
+       for (i = 1; rflagsc[i]; i++) {
+           if ((1 << i) & rflags) {
+               if (CANT_HAPPEN(rflagsc[i] == 'X'))
                    continue;
-               pr("%c", rflagsc[j]);
+               pr("%c", rflagsc[i]);
            }
        }
        pr("\n");