]> git.pond.sub.org Git - empserver/blobdiff - src/lib/common/cargo.c
Update copyright notice
[empserver] / src / lib / common / cargo.c
index 2b53bd2bbf7cff3714607a64af4d3011ca39016f..a0d5948ec588909884d10c8065fdfafa659b30a2 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-2020, 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/>.
  *
  *  ---
  *
  *  ---
  *
  *  cargo.c: Cargo lists
- * 
+ *
  *  Known contributors to this file:
- *     Markus Armbruster, 2008
+ *     Markus Armbruster, 2009
  */
 
 #include <config.h>
 
 #include <stdlib.h>
 #include <stdio.h>
-#include "file.h"
+#include <string.h>
 #include "unit.h"
 
 struct clink {
-    short next;
-    short head[EF_NUKE - EF_PLANE + 1];
+    int next;
+    int head[EF_NUKE - EF_PLANE + 1];
 };
 
 /*
  * Cargo lists
  *
  * Persistent game state encodes "who carries what" by storing the
- * carrier uid in the cargo.  Cargo lists augment that: they store
+ * carrier UID in the cargo.  Cargo lists augment that: they store
  * lists of cargo for each carrier.
  *
  * clink[TYPE] points to an array of cargo list links.  The array has
@@ -57,10 +56,10 @@ struct clink {
  * EF_NUKE.  Other slots of clink[] and nclink[] are unused and remain
  * zero.
  *
- * clink[TYPE][UID].next is the uid of the next unit of the same type
+ * clink[TYPE][UID].next is the UID of the next unit of the same type
  * in the same carrier, -1 if none.
  *
- * clink[TYPE][UID].head[CARGO-EF_PLANE] is the uid of the first unit
+ * clink[TYPE][UID].head[CARGO-EF_PLANE] is the UID of the first unit
  * of type CARGO carried by this unit, -1 if none.  The next unit, if
  * any, is clink[CARGO][clink[TYPE][UID].head[CARGO-EF_PLANE]].next,
  * and so forth.
@@ -69,15 +68,15 @@ struct clink {
  * cargo lists know nothing about that.
  */
 static struct clink *clink[EF_NUKE + 1];
-static short nclink[EF_NUKE + 1];
+static int nclink[EF_NUKE + 1];
 
 /*
- * Return pointer to CL's cargo list head for file type TYPE.
+ * Return pointer to @cl's cargo list head for file type @type.
  */
-static short *
+static int *
 clink_headp(struct clink *cl, int type)
 {
-    static short dummy;
+    static int dummy;
 
     if (CANT_HAPPEN(type < EF_PLANE || type > EF_NUKE)) {
        dummy = -1;
@@ -87,7 +86,7 @@ clink_headp(struct clink *cl, int type)
 }
 
 /*
- * Initialize cargo list link CL to empty.
+ * Initialize cargo list link @cl to empty.
  */
 static void
 clink_init(struct clink *cl)
@@ -100,17 +99,17 @@ clink_init(struct clink *cl)
 }
 
 /*
- * Check whether *UIDP is a valid uid for file type TYPE.
+ * Check whether *@uidp is a valid UID for file type @type.
  */
 static void
-clink_check1(short *uidp, int type)
+clink_check1(int *uidp, int type)
 {
     if (CANT_HAPPEN(*uidp >= nclink[type]))
        *uidp = -1;
 }
 
 /*
- * Check validity of cargo lists for file type TYPE.
+ * Check validity of cargo lists for file type @type.
  */
 static void
 clink_check(int type)
@@ -131,13 +130,13 @@ clink_check(int type)
 }
 
 /*
- * Add to CL's cargo list for type TYPE the uid UID.
- * UID must not be on any cargo list already.
+ * Add to @cl's cargo list for type @type the UID @uid.
+ * @uid must not be on any cargo list already.
  */
 static void
 clink_add(struct clink *cl, int type, int uid)
 {
-    short *head = clink_headp(cl, type);
+    int *head = clink_headp(cl, type);
 
     if (CANT_HAPPEN(type < 0 || type > EF_NUKE
                    || uid < 0 || uid >= nclink[type]))
@@ -150,16 +149,16 @@ clink_add(struct clink *cl, int type, int uid)
 }
 
 /*
- * Remove from CL's cargo list for type TYPE the uid UID.
- * UID must be on that cargo list.
+ * Remove from @cl's cargo list for type @type the UID @uid.
+ * @uid must be on that cargo list.
  */
 static void
 clink_rem(struct clink *cl, int type, int uid)
 {
-    short *head = clink_headp(cl, type);
+    int *head = clink_headp(cl, type);
     struct clink *linkv;
     int n;
-    short *p;
+    int *p;
 
     if (CANT_HAPPEN(type < 0 || type > EF_NUKE))
        return;
@@ -176,25 +175,25 @@ clink_rem(struct clink *cl, int type, int uid)
 }
 
 /*
- * Update cargo lists for a change of CARGO's carrier.
- * Carrier is of type TYPE, and changes from uid OLD to NEW.
- * Negative uids mean no carrier.
+ * Update cargo lists for a change of @cargo's carrier.
+ * Carrier is of type @type, and changes from UID @old to @new.
+ * Negative UIDs mean no carrier.
  */
 void
 unit_carrier_change(struct empobj *cargo, int type, int old, int new)
 {
     if (CANT_HAPPEN(type < 0 || type > EF_NUKE))
        return;
-    if (old >= 0)
+    if (old >= 0 && !CANT_HAPPEN(old >= nclink[type]))
        clink_rem(&clink[type][old], cargo->ef_type, cargo->uid);
-    if (new >= 0)
+    if (new >= 0 && !CANT_HAPPEN(new >= nclink[type]))
        clink_add(&clink[type][new], cargo->ef_type, cargo->uid);
 }
 
 /*
- * Update cargo lists for a change of PP's carrier.
- * Carrier is of type TYPE, and changes from uid OLD to NEW.
- * Negative uids mean no carrier.
+ * Update cargo lists for a change of @pp's carrier.
+ * Carrier is of type @type, and changes from UID @old to @new.
+ * Negative UIDs mean no carrier.
  */
 void
 pln_carrier_change(struct plnstr *pp, int type, int old, int new)
@@ -203,9 +202,9 @@ pln_carrier_change(struct plnstr *pp, int type, int old, int new)
 }
 
 /*
- * Update cargo lists for a change of LP's carrier.
- * Carrier is of type TYPE, and changes from uid OLD to NEW.
- * Negative uids mean no carrier.
+ * Update cargo lists for a change of @lp's carrier.
+ * Carrier is of type @type, and changes from UID @old to @new.
+ * Negative UIDs mean no carrier.
  */
 void
 lnd_carrier_change(struct lndstr *lp, int type, int old, int new)
@@ -214,9 +213,9 @@ lnd_carrier_change(struct lndstr *lp, int type, int old, int new)
 }
 
 /*
- * Update cargo lists for a change of NP's carrier.
- * Carrier is of type TYPE, and changes from uid OLD to NEW.
- * Negative uids mean no carrier.
+ * Update cargo lists for a change of @np's carrier.
+ * Carrier is of type @type, and changes from UID @old to @new.
+ * Negative UIDs mean no carrier.
  */
 void
 nuk_carrier_change(struct nukstr *np, int type, int old, int new)
@@ -240,41 +239,50 @@ unit_cargo_init(void)
        unit_onresize(i);
 
     for (i = 0; (pp = getplanep(i)); i++) {
-       if (!pp->pln_own)
+       if (!pp->pln_own) {
+           if (CANT_HAPPEN(pp->pln_ship >= 0 || pp->pln_land >= 0))
+               pp->pln_ship = pp->pln_land = -1;
            continue;
+       }
        if (CANT_HAPPEN(pp->pln_ship >= 0 && pp->pln_land >= 0))
            pp->pln_land = -1;
        pln_carrier_change(pp, EF_SHIP, -1, pp->pln_ship);
        pln_carrier_change(pp, EF_LAND, -1, pp->pln_land);
     }
     for (i = 0; (lp = getlandp(i)); i++) {
-       if (!lp->lnd_own)
+       if (!lp->lnd_own) {
+           if (CANT_HAPPEN(lp->lnd_ship >= 0 || lp->lnd_land >= 0))
+               lp->lnd_ship = lp->lnd_land = -1;
            continue;
+       }
        if (CANT_HAPPEN(lp->lnd_ship >= 0 && lp->lnd_land >= 0))
            lp->lnd_land = -1;
        lnd_carrier_change(lp, EF_SHIP, -1, lp->lnd_ship);
        lnd_carrier_change(lp, EF_LAND, -1, lp->lnd_land);
     }
     for (i = 0; (np = getnukep(i)); i++) {
-       if (!np->nuk_own)
+       if (!np->nuk_own) {
+           if (CANT_HAPPEN(np->nuk_plane >= 0))
+               np->nuk_plane = -1;
            continue;
+       }
        nuk_carrier_change(np, EF_PLANE, -1, np->nuk_plane);
     }
 }
 
 /*
- * Resize clink[TYPE] to match ef_nelem(TYPE).
+ * Resize clink[@type] to match ef_nelem(@type).
  * Return 0 on success, -1 on error.
  * This is the struct empfile onresize callback for units.
  */
-int
+void
 unit_onresize(int type)
 {
     int n, i;
     struct clink *cl;
 
     if (CANT_HAPPEN(type < EF_SHIP || type > EF_NUKE))
-       return -1;
+       return;
 
     n = ef_nelem(type);
     cl = realloc(clink[type], n * sizeof(*clink[type]));
@@ -286,19 +294,18 @@ unit_onresize(int type)
     nclink[type] = n;
     if (ef_flags(type) & EFF_MEM)
        clink_check(type);
-    return 0;
 }
 
 /*
- * Find first unit on a carrier's cargo list for file type CARGO_TYPE.
- * Search carrier UID of type TYPE.
- * Return first unit's uid, or -1 if the carrier isn't carrying such
+ * Find first unit on a carrier's cargo list for file type @cargo_type.
+ * Search carrier @uid of type @type.
+ * Return first unit's UID, or -1 if the carrier isn't carrying such
  * units.
  */
 int
 unit_cargo_first(int type, int uid, int cargo_type)
 {
-    short *headp;
+    int *headp;
 
     if (CANT_HAPPEN(type < EF_SHIP || type > EF_NUKE))
        return -1;
@@ -311,9 +318,9 @@ unit_cargo_first(int type, int uid, int cargo_type)
 }
 
 /*
- * Find the next unit on a cargo list for file type CARGO_TYPE.
- * Get the unit after CARGO_UID.
- * Return its uid, or -1 if there are no more on this list.
+ * Find the next unit on a cargo list for file type @cargo_type.
+ * Get the unit after @cargo_uid.
+ * Return its UID, or -1 if there are no more on this list.
  */
 int
 unit_cargo_next(int cargo_type, int cargo_uid)
@@ -326,7 +333,7 @@ unit_cargo_next(int cargo_type, int cargo_uid)
 }
 
 /*
- * If SP carries planes, return the uid of the first one, else -1.
+ * If @sp carries planes, return the UID of the first one, else -1.
  */
 int
 pln_first_on_ship(struct shpstr *sp)
@@ -335,7 +342,7 @@ pln_first_on_ship(struct shpstr *sp)
 }
 
 /*
- * If LP carries planes, return the uid of the first one, else -1.
+ * If @lp carries planes, return the UID of the first one, else -1.
  */
 int
 pln_first_on_land(struct lndstr *lp)
@@ -344,8 +351,8 @@ pln_first_on_land(struct lndstr *lp)
 }
 
 /*
- * Find the next plane on the same carrier as plane#UID.
- * Return its uid, or -1 if there are no more.
+ * Find the next plane on the same carrier as plane#@uid.
+ * Return its UID, or -1 if there are no more.
  */
 int
 pln_next_on_unit(int uid)
@@ -354,7 +361,7 @@ pln_next_on_unit(int uid)
 }
 
 /*
- * If SP carries land units, return the uid of the first one, else -1.
+ * If @sp carries land units, return the UID of the first one, else -1.
  */
 int
 lnd_first_on_ship(struct shpstr *sp)
@@ -363,7 +370,7 @@ lnd_first_on_ship(struct shpstr *sp)
 }
 
 /*
- * If SP carries land units, return the uid of the first one, else -1.
+ * If @lp carries land units, return the UID of the first one, else -1.
  */
 int
 lnd_first_on_land(struct lndstr *lp)
@@ -372,8 +379,8 @@ lnd_first_on_land(struct lndstr *lp)
 }
 
 /*
- * Find the next land unit on the same carrier as land#UID.
- * Return its uid, or -1 if there are no more.
+ * Find the next land unit on the same carrier as land#@uid.
+ * Return its UID, or -1 if there are no more.
  */
 int
 lnd_next_on_unit(int uid)
@@ -382,7 +389,7 @@ lnd_next_on_unit(int uid)
 }
 
 /*
- * If PP carries a nuke, return its uid, else -1.
+ * If @pp carries a nuke, return its UID, else -1.
  */
 int
 nuk_on_plane(struct plnstr *pp)
@@ -391,7 +398,8 @@ nuk_on_plane(struct plnstr *pp)
 }
 
 /*
- * Return length of a carrier's cargo list for file type CARGO_TYPE.
+ * Return length of a carrier's cargo list for file type @cargo_type.
+ * Use carrier @uid of type @type.
  */
 int
 unit_cargo_count(int type, int uid, int cargo_type)
@@ -408,7 +416,7 @@ unit_cargo_count(int type, int uid, int cargo_type)
 }
 
 /*
- * Return number of land units loaded on SP.
+ * Return number of land units loaded on @sp.
  */
 int
 shp_nland(struct shpstr *sp)
@@ -417,7 +425,7 @@ shp_nland(struct shpstr *sp)
 }
 
 /*
- * Return number of land units loaded on LP.
+ * Return number of land units loaded on @lp.
  */
 int
 lnd_nland(struct lndstr *lp)