/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* ---
*
* cargo.c: Cargo lists
- *
+ *
* Known contributors to this file:
* Markus Armbruster, 2008
*/
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include "file.h"
#include "unit.h"
return;
if (CANT_HAPPEN(*head >= nclink[type]))
*head = -1;
+ CANT_HAPPEN(clink[type][uid].next >= 0);
clink[type][uid].next = *head;
*head = uid;
}
}
*p = linkv[uid].next;
+ linkv[uid].next = -1;
}
/*
{
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);
}
struct lndstr *lp;
struct nukstr *np;
- for (i = EF_SHIP; i <= EF_NUKE; i++) {
- nclink[i] = 0;
+ memset(nclink, 0, sizeof(nclink));
+ for (i = EF_SHIP; i <= EF_NUKE; i++)
unit_onresize(i);
- }
for (i = 0; (pp = getplanep(i)); i++) {
if (!pp->pln_own)
n = ef_nelem(type);
cl = realloc(clink[type], n * sizeof(*clink[type]));
- if (!cl)
- return -1;
+ if (!cl && n)
+ exit_nomem();
for (i = nclink[type]; i < n; i++)
clink_init(&cl[i]);
clink[type] = cl;
nclink[type] = n;
- clink_check(type);
+ if (ef_flags(type) & EFF_MEM)
+ clink_check(type);
return 0;
}
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.
*/
{
return unit_cargo_first(EF_PLANE, pp->pln_uid, EF_NUKE);
}
-#endif
+
+/*
+ * Return length of a carrier's cargo list for file type CARGO_TYPE.
+ */
+int
+unit_cargo_count(int type, int uid, int cargo_type)
+{
+ int n, cargo;
+
+ n = 0;
+ for (cargo = unit_cargo_first(type, uid, cargo_type);
+ cargo >= 0;
+ cargo = unit_cargo_next(cargo_type, cargo))
+ n++;
+
+ return n;
+}
+
+/*
+ * Return number of land units loaded on SP.
+ */
+int
+shp_nland(struct shpstr *sp)
+{
+ return unit_cargo_count(EF_SHIP, sp->shp_uid, EF_LAND);
+}
+
+/*
+ * Return number of land units loaded on LP.
+ */
+int
+lnd_nland(struct lndstr *lp)
+{
+ return unit_cargo_count(EF_LAND, lp->lnd_uid, EF_LAND);
+}
+
+int
+unit_nplane(int type, int uid, int *nchopper, int *nxlight, int *nmsl)
+{
+ int n, nch, nxl, nms, cargo;
+ struct plnstr *pp;
+ struct plchrstr *pcp;
+
+ n = nxl = nch = nms = 0;
+ for (cargo = unit_cargo_first(type, uid, EF_PLANE);
+ (pp = getplanep(cargo));
+ cargo = pln_next_on_unit(cargo)) {
+ pcp = &plchr[pp->pln_type];
+ if (pcp->pl_flags & P_K)
+ nch++;
+ else if (pcp->pl_flags & P_E)
+ nxl++;
+ else if (pcp->pl_flags & P_M)
+ nms++;
+ n++;
+ }
+
+ if (nchopper)
+ *nchopper = nch;
+ if (nxlight)
+ *nxlight = nxl;
+ if (nmsl)
+ *nmsl = nms;
+ return n;
+}
+
+int
+shp_nplane(struct shpstr *sp, int *nchopper, int *nxlight, int *nmsl)
+{
+ return unit_nplane(EF_SHIP, sp->shp_uid, nchopper, nxlight, nmsl);
+}
+
+int
+lnd_nxlight(struct lndstr *lp)
+{
+ int n;
+
+ unit_nplane(EF_LAND, lp->lnd_uid, NULL, &n, NULL);
+ return n;
+}