]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/tend.c
COPYING duplicates information from README. Remove. Move GPL from
[empserver] / src / lib / commands / tend.c
index 88bd5cdd34353f13048635375bd762e1b7c3ff0c..4771d1e7570c881ac9fa5fb3854e639263a86e94 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                           Ken Stevens, Steve McClure
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -19,9 +19,9 @@
  *
  *  ---
  *
- *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- *  related information and legal notices. It is expected that any future
- *  projects/authors will amend these files as needed.
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
  *
  *  ---
  *
  *     Steve McClure, 2000
  */
 
-#ifdef Rel4
+#include <config.h>
+
 #include <string.h>
-#endif /* Rel4 */
 #include "misc.h"
 #include "player.h"
-#include "var.h"
+#include "plague.h"
 #include "xy.h"
 #include "file.h"
 #include "ship.h"
@@ -47,7 +47,6 @@
 #include "nat.h"
 #include "land.h"
 #include "plane.h"
-#include "nuke.h"
 #include "genitem.h"
 #include "commands.h"
 
@@ -82,18 +81,18 @@ tend(void)
 
     if (!strncmp(p, "land", 4))
        type = EF_LAND;
-    else if (NULL != (ip = whatitem(p, (s_char *)0)))
+    else if (NULL != (ip = item_by_name(p)))
        type = EF_SECTOR;
     else {
-       pr("Bad commodity.\n");
+       pr("Can't tend '%s'\n", p);
        return RET_SYN;
     }
 
-    if (!snxtitem
-       (&tenders, EF_SHIP, getstarg(player->argp[2], "Tender(s)? ", buf)))
+    if (!snxtitem(&tenders, EF_SHIP,
+                 getstarg(player->argp[2], "Tender(s)? ", buf)))
        return RET_SYN;
 
-    while (nxtitem(&tenders, (s_char *)&tender)) {
+    while (nxtitem(&tenders, &tender)) {
        if (!player->owner)
            continue;
        if (type == EF_LAND) {
@@ -117,14 +116,13 @@ tend(void)
            pr("Amount must be non-zero!\n");
            return RET_SYN;
        }
-       ontender = getvar(ip->i_vtype, (s_char *)&tender, EF_SHIP);
+       ontender = tender.shp_item[ip->i_vtype];
        if (ontender == 0 && amt > 0) {
            pr("No %s on %s\n", ip->i_name, prship(&tender));
            return RET_FAIL;
        }
        vbase = &mchr[(int)tender.shp_type];
-       maxtender = vl_find(ip->i_vtype, vbase->m_vtype,
-                           vbase->m_vamt, (int)vbase->m_nv);
+       maxtender = vbase->m_item[ip->i_vtype];
        if (maxtender == 0) {
            pr("A %s cannot hold any %s\n",
               mchr[(int)tender.shp_type].m_name, ip->i_name);
@@ -137,7 +135,7 @@ tend(void)
        if (!check_ship_ok(&tender))
            return RET_SYN;
        total = 0;
-       while (tend_nxtitem(&targets, (s_char *)&target)) {
+       while (nxtitem(&targets, &target)) {
            if (!player->owner &&
                (getrel(getnatp(target.shp_own), player->cnum) < FRIENDLY))
                continue;
@@ -146,35 +144,32 @@ tend(void)
            if (tender.shp_x != target.shp_x ||
                tender.shp_y != target.shp_y)
                continue;
-           ontarget = getvar(ip->i_vtype, (s_char *)&target, EF_SHIP);
+           ontarget = target.shp_item[ip->i_vtype];
            if (ontarget == 0 && amt < 0) {
                pr("No %s on %s\n", ip->i_name, prship(&target));
                continue;
            }
            vbase = &mchr[(int)target.shp_type];
-           maxtarget = vl_find(ip->i_vtype, vbase->m_vtype,
-                               vbase->m_vamt, (int)vbase->m_nv);
+           maxtarget = vbase->m_item[ip->i_vtype];
            if (amt < 0) {
                if (!player->owner)
                    amt = 0;
 
                /* take from target and give to tender */
-               transfer = min(ontarget, -amt);
-               transfer = min(maxtender - ontender, transfer);
+               transfer = MIN(ontarget, -amt);
+               transfer = MIN(maxtender - ontender, transfer);
                if (transfer == 0)
                    continue;
-               putvar(ip->i_vtype, ontarget - transfer,
-                      (s_char *)&target, EF_SHIP);
+               target.shp_item[ip->i_vtype] = ontarget - transfer;
                ontender += transfer;
                total += transfer;
            } else {
                /* give to target from tender */
-               transfer = min(ontender, amt);
-               transfer = min(transfer, maxtarget - ontarget);
+               transfer = MIN(ontender, amt);
+               transfer = MIN(transfer, maxtarget - ontarget);
                if (transfer == 0)
                    continue;
-               putvar(ip->i_vtype, ontarget + transfer,
-                      (s_char *)&target, EF_SHIP);
+               target.shp_item[ip->i_vtype] = ontarget + transfer;
                ontender -= transfer;
                total += transfer;
            }
@@ -188,7 +183,11 @@ tend(void)
        pr("%d total %s transferred %s %s\n",
           total, ip->i_name, (amt > 0) ? "off of" : "to",
           prship(&tender));
-       putvar(ip->i_vtype, ontender, (s_char *)&tender, EF_SHIP);
+       if (target.shp_own != player->cnum) {
+           wu(0, target.shp_own, "%s tended %d %s to %s\n",
+              cname(player->cnum), total, ip->i_name, prship(&target));
+       }
+       tender.shp_item[ip->i_vtype] = ontender;
        tender.shp_mission = 0;
        putship(tender.shp_uid, &tender);
     }
@@ -198,87 +197,10 @@ tend(void)
 static void
 expose_ship(struct shpstr *s1, struct shpstr *s2)
 {
-    if (getvar(V_PSTAGE, (s_char *)s1, EF_SHIP) == PLG_INFECT &&
-       getvar(V_PSTAGE, (s_char *)s2, EF_SHIP) == PLG_HEALTHY)
-       putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)s2, EF_SHIP);
-    if (getvar(V_PSTAGE, (s_char *)s2, EF_SHIP) == PLG_INFECT &&
-       getvar(V_PSTAGE, (s_char *)s1, EF_SHIP) == PLG_HEALTHY)
-       putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)s1, EF_SHIP);
-}
-
-/*
- * tend_nxtitem.c
- *
- * get next item from list. Stolen from nxtitem to make 1 itsy-bitsy change
- *
- * Dave Pare, 1989
- */
-
-int
-tend_nxtitem(struct nstr_item *np, caddr_t ptr)
-{
-    struct genitem *gp;
-    int selected;
-
-    if (np->sel == NS_UNDEF)
-       return 0;
-    gp = (struct genitem *)ptr;
-    do {
-       if (np->sel == NS_LIST) {
-           np->index++;
-           if (np->index >= np->size)
-               return 0;
-           np->cur = np->list[np->index];
-       } else {
-           np->cur++;
-       }
-       if (!np->read(np->type, np->cur, ptr)) {
-           /* if read fails, fatal */
-           return 0;
-       }
-       selected = 1;
-       switch (np->sel) {
-       case NS_LIST:
-           /* The change is to take the player->owner check out here */
-           break;
-       case NS_ALL:
-           /* XXX maybe combine NS_LIST and NS_ALL later */
-           break;
-       case NS_DIST:
-           if (!xyinrange(gp->x, gp->y, &np->range)) {
-               selected = 0;
-               break;
-           }
-           np->curdist = mapdist((int)gp->x, (int)gp->y,
-                                 (int)np->cx, (int)np->cy);
-           if (np->curdist > np->dist)
-               selected = 0;
-           break;
-       case NS_AREA:
-           if (!xyinrange(gp->x, gp->y, &np->range))
-               selected = 0;
-           if (gp->x == np->range.hx || gp->y == np->range.hy)
-               selected = 0;
-           break;
-       case NS_XY:
-           if (gp->x != np->cx || gp->y != np->cy)
-               selected = 0;
-           break;
-       case NS_GROUP:
-           if (np->group != gp->group)
-               selected = 0;
-           break;
-       default:
-           logerror("nxtitem: bad selector %d\n", np->sel);
-           return 0;
-       }
-       if (selected && np->ncond) {
-           /* nstr_exec is expensive, so we do it last */
-           if (!nstr_exec(np->cond, np->ncond, ptr, np->type))
-               selected = 0;
-       }
-    } while (!selected);
-    return 1;
+    if (s1->shp_pstage == PLG_INFECT && s2->shp_pstage == PLG_HEALTHY)
+       s2->shp_pstage = PLG_EXPOSED;
+    if (s2->shp_pstage == PLG_INFECT && s1->shp_pstage == PLG_HEALTHY)
+       s1->shp_pstage = PLG_EXPOSED;
 }
 
 static int
@@ -295,7 +217,7 @@ tend_land(struct shpstr *tenderp, s_char *units)
     if (!snxtitem(&lni, EF_LAND, units))
        return RET_SYN;
 
-    while (nxtitem(&lni, (s_char *)&land)) {
+    while (nxtitem(&lni, &land)) {
        if (!player->owner)
            continue;
        if (land.lnd_ship != tenderp->shp_uid) {
@@ -312,7 +234,7 @@ tend_land(struct shpstr *tenderp, s_char *units)
            break;
        if (!check_land_ok(&land))
            return RET_SYN;
-       while (tend_nxtitem(&targets, (s_char *)&target)) {
+       while (nxtitem(&targets, &target)) {
            if (!player->owner &&
                (getrel(getnatp(target.shp_own), player->cnum) < FRIENDLY))
                continue;
@@ -326,7 +248,15 @@ tend_land(struct shpstr *tenderp, s_char *units)
            count_units(&target);
            getship(target.shp_uid, &target);
 
-           if (target.shp_nland >= mchr[(int)target.shp_type].m_nland) {
+           if ((mchr[(int)target.shp_type].m_flags & M_SUB) &&
+               (lchr[(int)land.lnd_type].l_flags & L_SPY) &&
+               !mchr[(int)target.shp_type].m_nland) {
+               if (target.shp_nland > 1) {
+                   pr("%s doesn't have room for more than two spy units!\n",
+                      prship(&target));
+                   continue;
+               }
+           } else if (target.shp_nland >= mchr[(int)target.shp_type].m_nland) {
                if (mchr[(int)target.shp_type].m_nland)
                    pr("%s doesn't have room for any more land units!\n",
                       prship(&target));
@@ -356,7 +286,7 @@ tend_land(struct shpstr *tenderp, s_char *units)
            count_units(tenderp);
            putship(tenderp->shp_uid, tenderp);
            snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
-           while (nxtitem(&pni, (s_char *)&plane)) {
+           while (nxtitem(&pni, &plane)) {
                if (plane.pln_flags & PLN_LAUNCHED)
                    continue;
                if (plane.pln_land != land.lnd_uid)