]> git.pond.sub.org Git - empserver/commitdiff
Cargo lists storing lists of cargo for each carrier
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 6 Sep 2008 22:40:58 +0000 (18:40 -0400)
committerMarkus Armbruster <armbru@pond.sub.org>
Tue, 9 Sep 2008 01:30:39 +0000 (21:30 -0400)
Persistent game state encodes "who carries what" by storing the
carrier uid in the cargo.  Cargo lists augment that: they store lists
of cargo for each carrier.  They are not persistent.

New unit_cargo_init() to compute the cargo lists from game state.
Call it in ef_init_srv() and at the end of update_main().

New unit_onresize() to resize the cargo list data structure.
Installed as units' struct empfile callback onresize to make them
resize automatically with the unit files.

New unit_carrier_change() to update cargo lists when carriers change
in game state.  Convenience wrappers pln_carrier_change(),
lnd_carrier_change() and nuk_carrier_change().  Call them from
prewrite callbacks to keep cargo lists in sync with game state.

To make that work, unused units must not point to a carrier.  Add new
pln_oninit(), lnd_oninit() and nuk_oninit() take care of newly created
units.  Change lnd_prewrite() and nuk_prewrite() to take dead land
units and nukes off their carrier.  pln_prewrite() did that already.

New unit_cargo_first(), unit_cargo_next() to traverse cargo lists.
Convenience wrappers lnd_first_on_ship(), lnd_first_on_land(),
lnd_next_on_unit(), pln_first_on_ship(), pln_first_on_land(),
pln_next_on_unit() and nuk_on_plane().  The latter is disabled for now
because it clashes with an existing function.

include/land.h
include/nuke.h
include/plane.h
include/prototypes.h
include/unit.h
src/lib/common/cargo.c [new file with mode: 0644]
src/lib/subs/fileinit.c
src/lib/subs/land.c
src/lib/subs/nuke.c
src/lib/subs/plane.c
src/lib/update/main.c

index 48742630554ab8b5724ac996e23bd3c8e8905986..f443f9d9e42ed9d4f2c4b519ecf63ba7ccf0f53c 100644 (file)
@@ -159,6 +159,12 @@ extern int lnd_acc(struct lndstr *);
 extern int lnd_dam(struct lndstr *);
 extern int lnd_aaf(struct lndstr *);
 
+/* src/lib/common/cargo.c */
+extern void lnd_carrier_change(struct lndstr *, int, int, int);
+extern int lnd_first_on_ship(struct shpstr *);
+extern int lnd_first_on_land(struct lndstr *);
+extern int lnd_next_on_unit(int);
+
 extern int lnd_fire(struct lndstr *);
 extern double lnd_fire_range(struct lndstr *);
 
index 054cdb4c34c507044bc705b52f48dbb8c3823583..05245cfb4b2a1ea555ba265df72f607f3a53432d 100644 (file)
@@ -90,4 +90,10 @@ struct nchrstr {
 
 extern struct nchrstr nchr[N_MAXNUKE + 1];
 
+/* src/lib/common/cargo.c */
+extern void nuk_carrier_change(struct nukstr *, int, int, int);
+#if 0 /* clashes with the one in src/lib/subs/nuke.c */
+extern int nuk_on_plane(struct plnstr *);
+#endif
+
 #endif
index 485ebb51e69856a479128b61d850a5b7763d7705..6fb735f0fb84c18067d09d752bc334f0f3e1bcb3 100644 (file)
@@ -156,6 +156,12 @@ extern int pln_acc(struct plnstr *);
 extern int pln_range_max(struct plnstr *);
 extern int pln_load(struct plnstr *);
 
+/* src/lib/common/cargo.c */
+extern void pln_carrier_change(struct plnstr *, int, int, int);
+extern int pln_first_on_ship(struct shpstr *);
+extern int pln_first_on_land(struct lndstr *);
+extern int pln_next_on_unit(int);
+
 /* src/lib/subs/aircombat.c */
 extern void ac_combat_headers(natid, natid);
 extern void ac_airtoair(struct emp_qelem *, struct emp_qelem *);
index 7ddfeff296f2baf822096d6654cf1fe938e749ee..7cb9bd305de289eeef663d0ede3547d2c5012983 100644 (file)
@@ -450,6 +450,7 @@ extern void bitinit2(struct nstr_sect *, unsigned char *, int);
 extern int getele(char *, char *);
 /* land.c */
 extern char *prland(struct lndstr *);
+extern void lnd_oninit(void *);
 extern void lnd_postread(int, void *);
 extern void lnd_prewrite(int, void *, void *);
 /* landgun.c */
@@ -517,6 +518,7 @@ extern void init_nreport(void);
 extern void nreport(natid, int, natid, int);
 /* nuke.c */
 extern char *prnuke(struct nukstr *);
+extern void nuk_oninit(void *);
 extern void nuk_postread(int, void *);
 extern void nuk_prewrite(int, void *, void *);
 extern int nuk_on_plane(struct nukstr *, int);
@@ -528,6 +530,7 @@ extern int nxtsct(struct nstr_sect *, struct sctstr *);
 extern int onearg(char *, char *);
 /* plane.c */
 extern char *prplane(struct plnstr *);
+extern void pln_oninit(void *);
 extern void pln_postread(int, void *);
 extern void pln_prewrite(int, void *, void *);
 /* plnsub.c */
index c8805e87e330ed4337fdcb67c0f7b224b756d975..0ce36545b50f76691b5d81b2d24382d565d5ff50 100644 (file)
@@ -44,6 +44,12 @@ struct ulist {
     int supplied;              /* LAND only */
 };
 
+extern void unit_cargo_init(void);
+extern void unit_carrier_change(struct empobj *, int, int, int);
+extern int unit_cargo_first(int, int, int);
+extern int unit_cargo_next(int, int);
+extern int unit_onresize(int);
+
 extern void unit_list(struct emp_qelem *);
 extern void unit_put(struct emp_qelem *list, natid actor);
 extern char *unit_path(int, struct empobj *, char *);
diff --git a/src/lib/common/cargo.c b/src/lib/common/cargo.c
new file mode 100644 (file)
index 0000000..4e38b3b
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program 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
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  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
+ *
+ *  ---
+ *
+ *  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.
+ *
+ *  ---
+ *
+ *  cargo.c: Cargo lists
+ * 
+ *  Known contributors to this file:
+ *     Markus Armbruster, 2008
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "file.h"
+#include "unit.h"
+
+struct clink {
+    short next;
+    short 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
+ * lists of cargo for each carrier.
+ *
+ * clink[TYPE] points to an array of cargo list links.  The array has
+ * nclink[TYPE] elements.  nclink[TYPE] tracks ef_nelem(TYPE).
+ * clink[TYPE][UID] is the cargo list link for unit UID of type TYPE.
+ * TYPE must be a unit file type: EF_SHIP, EF_PLANE, EF_LAND or
+ * 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
+ * in the same carrier, -1 if none.
+ *
+ * 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.
+ *
+ * Each type of carrier can only carry certain types of cargo, but
+ * cargo lists know nothing about that.
+ */
+static struct clink *clink[EF_NUKE + 1];
+static short nclink[EF_NUKE + 1];
+
+/*
+ * Return pointer to CL's cargo list head for file type TYPE.
+ */
+static short *
+clink_headp(struct clink *cl, int type)
+{
+    static short dummy;
+
+    if (CANT_HAPPEN(type < EF_PLANE || type > EF_NUKE)) {
+       dummy = -1;
+       return &dummy;
+    }
+    return &cl->head[type - EF_PLANE];
+}
+
+/*
+ * Initialize cargo list link CL to empty.
+ */
+static void
+clink_init(struct clink *cl)
+{
+    unsigned i;
+
+    cl->next = -1;
+    for (i = 0; i < sizeof(cl->head) / sizeof(*cl->head); i++)
+       cl->head[i] = -1;
+}
+
+/*
+ * Check whether *UIDP is a valid uid for file type TYPE.
+ */
+static void
+clink_check1(short *uidp, int type)
+{
+    if (CANT_HAPPEN(*uidp >= nclink[type]))
+       *uidp = -1;
+}
+
+/*
+ * Check validity of cargo lists for file type TYPE.
+ */
+static void
+clink_check(int type)
+{
+    int carr_type, i;
+
+    /* check the heads for all carriers */
+    if (type != EF_SHIP) {
+       for (carr_type = EF_PLANE; carr_type <= EF_NUKE; carr_type++) {
+           for (i = 0; i < nclink[carr_type]; i++)
+               clink_check1(clink_headp(&clink[carr_type][i], type),
+                            type);
+       }
+    }
+    /* check the nexts */
+    for (i = 0; i < nclink[type]; i++)
+       clink_check1(&clink[type][i].next, type);
+}
+
+/*
+ * 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);
+
+    if (CANT_HAPPEN(type < 0 || type > EF_NUKE
+                   || uid < 0 || uid >= nclink[type]))
+       return;
+    if (CANT_HAPPEN(*head >= nclink[type]))
+       *head = -1;
+    clink[type][uid].next = *head;
+    *head = uid;
+}
+
+/*
+ * 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);
+    struct clink *linkv;
+    int n;
+    short *p;
+
+    if (CANT_HAPPEN(type < 0 || type > EF_NUKE))
+       return;
+    linkv = clink[type];
+    n = nclink[type];
+
+    for (p = head; *p != uid; p = &linkv[*p].next) {
+       if (CANT_HAPPEN(*p < 0 || *p >= n))
+           return;
+    }
+
+    *p = linkv[uid].next;
+}
+
+/*
+ * 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)
+       clink_rem(&clink[type][old], cargo->ef_type, cargo->uid);
+    if (new >= 0)
+       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.
+ */
+void
+pln_carrier_change(struct plnstr *pp, int type, int old, int new)
+{
+    unit_carrier_change((struct empobj *)pp, type, old, 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.
+ */
+void
+lnd_carrier_change(struct lndstr *lp, int type, int old, int new)
+{
+    unit_carrier_change((struct empobj *)lp, type, old, 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.
+ */
+void
+nuk_carrier_change(struct nukstr *np, int type, int old, int new)
+{
+    unit_carrier_change((struct empobj *)np, type, old, new);
+}
+
+/*
+ * Initialize cargo lists from game state.
+ */
+void
+unit_cargo_init(void)
+{
+    int i;
+    struct plnstr *pp;
+    struct lndstr *lp;
+    struct nukstr *np;
+
+    for (i = EF_SHIP; i <= EF_NUKE; i++) {
+       nclink[i] = 0;
+       unit_onresize(i);
+    }
+
+    for (i = 0; (pp = getplanep(i)); i++) {
+       if (!pp->pln_own)
+           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)
+           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)
+           continue;
+       nuk_carrier_change(np, EF_PLANE, -1, np->nuk_plane);
+    }
+}
+
+/*
+ * 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
+unit_onresize(int type)
+{
+    int n, i;
+    struct clink *cl;
+
+    if (CANT_HAPPEN(type < EF_SHIP || type > EF_NUKE))
+       return -1;
+
+    n = ef_nelem(type);
+    cl = realloc(clink[type], n * sizeof(*clink[type]));
+    if (!cl)
+       return -1;
+    for (i = nclink[type]; i < n; i++)
+       clink_init(&cl[i]);
+    clink[type] = cl;
+    nclink[type] = n;
+    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
+ * units.
+ */
+int
+unit_cargo_first(int type, int uid, int cargo_type)
+{
+    short *headp;
+
+    if (CANT_HAPPEN(type < EF_SHIP || type > EF_NUKE))
+       return -1;
+    if (CANT_HAPPEN(uid < 0 || uid >= nclink[type]))
+       return -1;
+    headp = clink_headp(&clink[type][uid], cargo_type);
+    if (CANT_HAPPEN(!headp))
+       return -1;
+    return *headp;
+}
+
+/*
+ * 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)
+{
+    if (CANT_HAPPEN(cargo_type < EF_SHIP || cargo_type > EF_NUKE))
+       return -1;
+    if (CANT_HAPPEN(cargo_uid < 0 || cargo_uid >= nclink[cargo_type]))
+       return -1;
+    return clink[cargo_type][cargo_uid].next;
+}
+
+/*
+ * If SP carries planes, return the uid of the first one, else -1.
+ */
+int
+pln_first_on_ship(struct shpstr *sp)
+{
+    return unit_cargo_first(EF_SHIP, sp->shp_uid, EF_PLANE);
+}
+
+/*
+ * If LP carries planes, return the uid of the first one, else -1.
+ */
+int
+pln_first_on_land(struct lndstr *lp)
+{
+    return unit_cargo_first(EF_LAND, lp->lnd_uid, EF_PLANE);
+}
+
+/*
+ * 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)
+{
+    return unit_cargo_next(EF_PLANE, uid);
+}
+
+/*
+ * If SP carries land units, return the uid of the first one, else -1.
+ */
+int
+lnd_first_on_ship(struct shpstr *sp)
+{
+    return unit_cargo_first(EF_SHIP, sp->shp_uid, EF_LAND);
+}
+
+/*
+ * If SP carries land units, return the uid of the first one, else -1.
+ */
+int
+lnd_first_on_land(struct lndstr *lp)
+{
+    return unit_cargo_first(EF_LAND, lp->lnd_uid, EF_LAND);
+}
+
+/*
+ * 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)
+{
+    return unit_cargo_next(EF_LAND, uid);
+}
+
+#if 0 /* clashes with the one in src/lib/subs/nuke.c */
+/*
+ * If PP carries a nuke, return its uid, else -1.
+ */
+int
+nuk_on_plane(struct plnstr *pp)
+{
+    return unit_cargo_first(EF_PLANE, pp->pln_uid, EF_NUKE);
+}
+#endif
index fb0e0f33fed60301d1edd88d28dd26427a1538dd..1a63a1dd0eb2cb2af07d1f502ea23b37321e00ab 100644 (file)
 #include "nat.h"
 #include "optlist.h"
 #include "prototypes.h"
+#include "unit.h"
 
 struct fileinit {
     int ef_type;
-    void (*postread) (int, void *);
-    void (*prewrite) (int, void *, void *);
+    void (*oninit)(void *);
+    void (*postread)(int, void *);
+    void (*prewrite)(int, void *, void *);
+    int (*onresize)(int);
 };
 
 static struct fileinit fileinit[] = {
-    {EF_SECTOR, sct_postread, sct_prewrite},
-    {EF_SHIP, shp_postread, shp_prewrite},
-    {EF_PLANE, pln_postread, pln_prewrite},
-    {EF_LAND, lnd_postread, lnd_prewrite},
-    {EF_NUKE, nuk_postread, nuk_prewrite}
+    {EF_SECTOR, NULL, sct_postread, sct_prewrite, NULL},
+    {EF_SHIP, NULL, shp_postread, shp_prewrite, unit_onresize},
+    {EF_PLANE, pln_oninit, pln_postread, pln_prewrite, unit_onresize},
+    {EF_LAND, lnd_oninit, lnd_postread, lnd_prewrite, unit_onresize},
+    {EF_NUKE, nuk_oninit, nuk_postread, nuk_prewrite, unit_onresize}
 };
 
 static void ef_open_srv(void);
@@ -67,6 +70,7 @@ ef_init_srv(void)
     for (i = 0; i < sizeof(fileinit) / sizeof(fileinit[0]); i++) {
        empfile[fileinit[i].ef_type].postread = fileinit[i].postread;
        empfile[fileinit[i].ef_type].prewrite = fileinit[i].prewrite;
+       empfile[fileinit[i].ef_type].onresize = fileinit[i].onresize;
     }
 
     nsc_init();
@@ -74,6 +78,7 @@ ef_init_srv(void)
     if (ef_verify() < 0)
        exit(EXIT_FAILURE);
     global_init();
+    unit_cargo_init();
 }
 
 void
index 9bc647ebf879915659936c6b06df0a7755c583d2..618a294ca9ad4834a64c8705092794b6ffe09fba 100644 (file)
@@ -120,6 +120,7 @@ lnd_prewrite(int n, void *old, void *new)
 
     if (llp->lnd_own && llp->lnd_effic < LAND_MINEFF) {
        own = 0;
+       llp->lnd_ship = llp->lnd_land = -1;
 
        for (i = 0; NULL != (lp = getlandp(i)); i++) {
            if (lp->lnd_own && lp->lnd_land == n) {
@@ -149,6 +150,13 @@ lnd_prewrite(int n, void *old, void *new)
        item_prewrite(llp->lnd_item);
     }
 
+    if (CANT_HAPPEN(llp->lnd_ship >= 0 && llp->lnd_land >= 0))
+       llp->lnd_land = -1;
+    if (oldlp->lnd_ship != llp->lnd_ship)
+       lnd_carrier_change(llp, EF_SHIP, oldlp->lnd_ship, llp->lnd_ship);
+    if (oldlp->lnd_land != llp->lnd_land)
+       lnd_carrier_change(llp, EF_LAND, oldlp->lnd_land, llp->lnd_land);
+
     /* We've avoided assigning to llp->lnd_own, in case oldsp == sp */
     if (oldlp->lnd_own != own)
        lost_and_found(EF_LAND, oldlp->lnd_own, own,
@@ -157,6 +165,14 @@ lnd_prewrite(int n, void *old, void *new)
     llp->lnd_own = own;
 }
 
+void
+lnd_oninit(void *ptr)
+{
+    struct lndstr *lp = ptr;
+
+    lp->lnd_ship = lp->lnd_land = -1;
+}
+
 char *
 prland(struct lndstr *lp)
 {
index 6f38e0e8984401a20749f44e4f26af7ce2e71766..0708ff579afeaf3df9ebf464a4629926df35c168 100644 (file)
@@ -44,8 +44,6 @@
 #include "plane.h"
 #include "player.h"
 #include "prototypes.h"
-#include "sect.h"
-#include "xy.h"
 
 void
 nuk_postread(int n, void *ptr)
@@ -80,8 +78,13 @@ nuk_prewrite(int n, void *old, void *new)
     struct nukstr *np = new;
     natid own = np->nuk_own;
 
-    if (np->nuk_effic == 0)
+    if (np->nuk_effic == 0) {
        own = 0;
+       np->nuk_plane = -1;
+    }
+
+    if (oldnp->nuk_plane != np->nuk_plane)
+       nuk_carrier_change(np, EF_PLANE, oldnp->nuk_plane, np->nuk_plane);
 
     /* We've avoided assigning to np->nuk_own, in case oldsp == sp */
     if (oldnp->nuk_own != own)
@@ -106,6 +109,14 @@ nuk_on_plane(struct nukstr *np, int pluid)
     return -1;
 }
 
+void
+nuk_oninit(void *ptr)
+{
+    struct nukstr *np = ptr;
+
+    np->nuk_plane = -1;
+}
+
 char *
 prnuke(struct nukstr *np)
 {
index 18f9401e539026da8868afea912c8a21e9c2952d..11c28104c4ad9cae52de0de005fa94d8184e91e9 100644 (file)
@@ -119,6 +119,7 @@ pln_prewrite(int n, void *old, void *new)
     if (pp->pln_effic < PLANE_MINEFF) {
        own = 0;
        pp->pln_effic = 0;
+       pp->pln_ship = pp->pln_land = -1;
        for (i = 0; NULL != (np = getnukep(i)); i++) {
            if (np->nuk_own && np->nuk_plane == n) {
                mpr(np->nuk_own, "%s lost!\n", prnuke(np));
@@ -129,6 +130,13 @@ pln_prewrite(int n, void *old, void *new)
        }
     }
 
+    if (CANT_HAPPEN(pp->pln_ship >= 0 && pp->pln_land >= 0))
+       pp->pln_land = -1;
+    if (oldpp->pln_ship != pp->pln_ship)
+       pln_carrier_change(pp, EF_SHIP, oldpp->pln_ship, pp->pln_ship);
+    if (oldpp->pln_land != pp->pln_land)
+       pln_carrier_change(pp, EF_LAND, oldpp->pln_land, pp->pln_land);
+
     /* We've avoided assigning to pp->pln_own, in case oldsp == sp */
     if (oldpp->pln_own != own)
        lost_and_found(EF_PLANE, oldpp->pln_own, own,
@@ -137,6 +145,14 @@ pln_prewrite(int n, void *old, void *new)
     pp->pln_own = own;
 }
 
+void
+pln_oninit(void *ptr)
+{
+    struct plnstr *pp = ptr;
+
+    pp->pln_ship = pp->pln_land = -1;
+}
+
 char *
 prplane(struct plnstr *pp)
 {
index 731405a4f24528fbdf6be92e538bdba4a5613c81..93fa218b10931381fff78a3bd110ca3052be9a72 100644 (file)
@@ -42,6 +42,7 @@
 #include "journal.h"
 #include "player.h"
 #include "server.h"
+#include "unit.h"
 #include "update.h"
 
 long money[MAXNOC];
@@ -169,6 +170,7 @@ update_main(void)
     ef_flush(EF_SHIP);
     ef_flush(EF_PLANE);
     ef_flush(EF_LAND);
+    unit_cargo_init();
     delete_old_announcements();
     delete_old_news();
     /* Clear all the telegram flags */