]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/retr.c
Update copyright notice
[empserver] / src / lib / commands / retr.c
index 58016d46388b3c98b55882099bce021ed2a8c51f..39c14d65194f4c1abe4bd254805d248827129518 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2015, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
  *  ---
  *
  *  retr.c: Set retreat conditionals for ships and land units
- * 
+ *
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 2000
+ *     Markus Armbruster, 2008-2014
  */
 
 #include <config.h>
 #include "retreat.h"
 #include "ship.h"
 
-static int retreat(short);
+/*
+ * Retreat flag characters
+ * 'X' means flag is not available
+ * Must agree with RET_ defines.
+ */
+static char shp_rflagsc[] = "Xitshbdu";
+static char lnd_rflagsc[] = "XiXXhbXX";
+
+static int retreat(int);
 
 int
 retr(void)
@@ -57,103 +65,72 @@ lretr(void)
 }
 
 static int
-retreat(short type)
+retreat(int type)
 {
     char *pq, *fl;
     int nunits;
     struct nstr_item ni;
     union empobj_storage unit;
-    int rflags;
+    int rflags, ch, j;
     unsigned i;
-    char *what;
+    char *rflagsc, *p, *name, *rpath, *what;
+    int *rflagsp;
     char buf1[1024];
     char buf2[1024];
 
     if (CANT_HAPPEN(type != EF_LAND && type != EF_SHIP))
        type = EF_SHIP;
+    rflagsc = type == EF_SHIP ? shp_rflagsc : lnd_rflagsc;
 
-    if (!snxtitem(&ni, type, player->argp[1]))
+    if (!snxtitem(&ni, type, player->argp[1], NULL))
        return RET_SYN;
     nunits = 0;
-    if (player->argp[2] != NULL)
+    if (player->argp[2] != NULL) {
        pq = getstarg(player->argp[2], "Retreat path? ", buf1);
-    else
+       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;
+           }
+       }
+    } else
        pq = NULL;
 
     rflags = 0;
     if (pq != NULL) {
+    again:
        fl = getstarg(player->argp[3],
-                     type == EF_SHIP
-                     ? "Retreat conditions [i|t|s|h|b|d|u|c]? "
-                     : "Retreat conditions [i|h|b|c]? ",
+                     "Retreat conditions ('?' to list available ones)? ",
                      buf2);
        if (!fl)
            return RET_SYN;
 
        for (i = 0; fl[i]; i++) {
-           switch (fl[i]) {
-           case 'I':
-           case 'i':
-               rflags |= RET_INJURED;
-               break;
-           case 'T':
-           case 't':
-               if (type == EF_LAND)
-                   goto badflag;
-               rflags |= RET_TORPED;
-               break;
-           case 'S':
-           case 's':
-               if (type == EF_LAND)
-                   goto badflag;
-               rflags |= RET_SONARED;
-               break;
-           case 'H':
-           case 'h':
-               rflags |= RET_HELPLESS;
-               break;
-           case 'B':
-           case 'b':
-               rflags |= RET_BOMBED;
-               break;
-           case 'D':
-           case 'd':
-               if (type == EF_LAND)
-                   goto badflag;
-               rflags |= RET_DCHRGED;
-               break;
-           case 'U':
-           case 'u':
-               if (type == EF_LAND)
-                   goto badflag;
-               rflags |= RET_BOARDED;
+           ch = tolower(fl[i]);
+           if (ch == 'c') {
+               *pq = 0;
                break;
-           case 'C':
-           case 'c':
-               pq = "";
-               break;
-           default:
-           badflag:
-               pr("bad condition\n");
-               /* fall through */
-           case '?':
-               pr("i\tretreat when injured\n");
-               if (type == EF_SHIP) {
-                   pr("t\tretreat when torped\n");
-                   pr("s\tretreat when sonared\n");
-               }
-               pr("h\tretreat when helpless\n");
-               pr("b\tretreat when bombed\n");
-               if (type == EF_SHIP) {
-                   pr("d\tretreat when depth-charged\n");
-                   pr("u\tretreat when boarded\n");
+           }
+           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);
+           if (!p) {
+               pr("Bad retreat condition '%c'\n", fl[i]);
+               return RET_SYN;
+           }
+           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)
@@ -164,67 +141,48 @@ retreat(short type)
        if (!player->owner || unit.gen.own == 0)
            continue;
        if (type == EF_SHIP) {
-           if (pq != NULL) {
-               strncpy(unit.ship.shp_rpath, pq, sizeof(unit.ship.shp_rpath) - 1);
-               unit.ship.shp_rflags = rflags;
-               putship(unit.ship.shp_uid, &unit.ship);
-           }
            if (nunits++ == 0) {
                if (player->god)
                    pr("own ");
-               pr("shp#     ship type       x,y   fl path       as flt? flags\n");
+               pr("shp#     ship type       x,y   fl path       as flt?  flags\n");
            }
-           if (player->god)
-               pr("%3d ", unit.ship.shp_own);
-           pr("%4d ", ni.cur);
-           pr("%-16.16s ", mchr[unit.ship.shp_type].m_name);
-           prxy("%4d,%-4d ", unit.ship.shp_x, unit.ship.shp_y, player->cnum);
-           pr("%1.1s", &unit.ship.shp_fleet);
-           pr(" %-11s", unit.ship.shp_rpath);
-           rflags = unit.ship.shp_rflags;
-           if (rflags & RET_GROUP)
-               pr("Yes     ");
-           else
-               pr("        ");
+           name = mchr[unit.ship.shp_type].m_name;
+           rpath = unit.ship.shp_rpath;
+           rflagsp = &unit.ship.shp_rflags;
        } else {
-           if (pq != NULL) {
-               strncpy(unit.land.lnd_rpath, pq, sizeof(unit.land.lnd_rpath) - 1);
-               unit.land.lnd_rflags = rflags;
-               putland(unit.land.lnd_uid, &unit.land);
-           }
-
            if (nunits++ == 0) {
                if (player->god)
                    pr("own ");
                pr("lnd#     unit type       x,y   ar path       as army? flags\n");
            }
-           if (player->god)
-               pr("%3d ", unit.land.lnd_own);
-           pr("%4d ", ni.cur);
-           pr("%-16.16s ", lchr[unit.land.lnd_type].l_name);
-           prxy("%4d,%-4d ", unit.land.lnd_x, unit.land.lnd_y, player->cnum);
-           pr("%1.1s", &unit.land.lnd_army);
-           pr(" %-11s", unit.land.lnd_rpath);
-           rflags = unit.land.lnd_rflags;
-           if (rflags & RET_GROUP)
-               pr("Yes      ");
-           else
-               pr("         ");
+           name = lchr[unit.land.lnd_type].l_name;
+           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("%-16.16s ", name);
+       prxy("%4d,%-4d ", unit.gen.x, unit.gen.y);
+       pr("%1.1s", &unit.gen.group);
+       pr(" %-11s", rpath);
+       rflags = *rflagsp;
+       if (rflags & RET_GROUP)
+           pr("Yes      ");
+       else
+           pr("         ");
+       for (j = 1; rflagsc[j]; j++) {
+           if ((1 << j) & rflags) {
+               if (CANT_HAPPEN(rflagsc[j] == 'X'))
+                   continue;
+               pr("%c", rflagsc[j]);
+           }
        }
-       if (rflags & RET_INJURED)
-           pr("I");
-       if (rflags & RET_TORPED)
-           pr("T");
-       if (rflags & RET_SONARED)
-           pr("S");
-       if (rflags & RET_HELPLESS)
-           pr("H");
-       if (rflags & RET_BOMBED)
-           pr("B");
-       if (rflags & RET_DCHRGED)
-           pr("D");
-       if (rflags & RET_BOARDED)
-           pr("U");
        pr("\n");
     }
     what = type == EF_SHIP ? "ship" : "unit";