Get rid of ship and land unit load counters

Load counters are redundant; they can be computed from the carrier
uids.  Keeping them up-to-date as the carriers change is a pain, and
we never got that quite complete.

Computing load counters straight from the carrier uids every time we
need them would be rather inefficient, but computing them from cargo
lists is not.  So do that.

Remove the load counters: struct shpstr members shp_nplane,
shp_nchoppers, shp_nxlight, shp_nland, and struct lndstr members
lnd_nxlight and lnd_nland.

Don't compute/update load counters in build_ship(), build_land(),
land(), ldump(), load_plane_ship(), load_land_ship(),
load_plane_land(), load_land_land(), lstat(), sdump(), shi(), sstat(),
tend_land(), check_trade(), put_combat(), pln_oneway_to_carrier_ok),
pln_newlanding(), fit_plane_on_ship(), fit_plane_on_land(),
unit_list().

Nothing left in fit_plane_off_ship(), fit_plane_off_land(), so remove
them.

load_land_ship(), load_land_land(), check_trade(), pln_newlanding(),
put_plane_on_ship(), take_plane_off_ship(), put_plane_on_land(),
take_plane_off_land() no longer change the carrier, so don't put it.

Remove functions to recompute the load counters from carrier uids:
count_units(), lnd_count_units(), count_planes(), count_land_planes(),
pln_fixup() and lnd_fixup(), along with the latter two's private
copies of fit_plane_on_ship() and fit_plane_on_land().

New cargo list functions to compute load counts: unit_cargo_count()
and unit_nplane(), with convenience wrappers shp_nplane(),
shp_nland(), lnd_nxlight(), lnd_nland().

Use them to make ship selectors nplane, nchoppers, nxlight, nland
virtual.  They now reflect what is loaded, not how the load uses the
available slots.  This makes a difference when x-light planes or
choppers use plane slots.

Use them to make land unit selectors nxlight and nland virtual.

Use them to get load counts in land(), ldump(), load_plane_ship(),
load_land_ship(), load_plane_land(), load_land_land(), sdump(), shi(),
tend_land(), fit_plane_on_land(), trade_desc(), unit_list().

Rewrite fit_plane_on_ship() and could_be_on_ship() to use
shp_nplane().  could_be_on_ship() now takes load count arguments, as
computed by shp_nplane(), so it can be used for checking against an
existing load as well.
This commit is contained in:
Markus Armbruster 2008-09-07 11:10:53 -04:00
parent 8b1470e3a8
commit 3e370da58c
22 changed files with 215 additions and 449 deletions

View file

@ -359,10 +359,6 @@ build_ship(struct sctstr *sp, struct mchrstr *mp, short *vec, int tlev)
} else {
ship.shp_mobil = 0;
}
ship.shp_nplane = 0;
ship.shp_nland = 0;
ship.shp_nxlight = 0;
ship.shp_nchoppers = 0;
ship.shp_fleet = 0;
memset(ship.shp_item, 0, sizeof(ship.shp_item));
ship.shp_pstage = PLG_HEALTHY;
@ -484,10 +480,8 @@ build_land(struct sctstr *sp, struct lchrstr *lp, short *vec, int tlev)
land.lnd_flags = 0;
land.lnd_ship = -1;
land.lnd_land = -1;
land.lnd_nland = 0;
land.lnd_harden = 0;
land.lnd_retreat = morale_base;
land.lnd_nxlight = 0;
land.lnd_rflags = 0;
memset(land.lnd_rpath, 0, sizeof(land.lnd_rpath));
land.lnd_rad_max = 0;

View file

@ -53,9 +53,6 @@ land(void)
continue;
if (!player->owner && !player->god)
continue;
count_land_planes(&land);
lnd_count_units(&land);
if (nunits++ == 0) {
if (player->god)
pr("own ");
@ -78,8 +75,8 @@ land(void)
pr("%4d ", land.lnd_tech);
pr("%3d%%", land.lnd_retreat);
pr("%3d", land.lnd_rad_max);
pr("%3d", land.lnd_nxlight);
pr("%3d", land.lnd_nland);
pr("%3d", lnd_nxlight(&land));
pr("%3d", lnd_nland(&land));
if (land.lnd_ship >= 0)
pr(" %4dS", land.lnd_ship);
else if (land.lnd_land >= 0)

View file

@ -299,9 +299,6 @@ ldump(void)
continue;
if (!player->owner && !player->god)
continue;
count_land_planes(&land);
lnd_count_units(&land);
nunits++;
if (player->god)
pr("%d ", land.lnd_own);
@ -349,10 +346,10 @@ ldump(void)
pr(" %d", land.lnd_rad_max);
break;
case 14:
pr(" %d", land.lnd_nxlight);
pr(" %d", lnd_nxlight(&land));
break;
case 15:
pr(" %d", land.lnd_nland);
pr(" %d", lnd_nland(&land));
break;
case 16:
pr(" %d", land.lnd_land);

View file

@ -356,11 +356,9 @@ load_plane_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
pr("%s cannot carry planes\n", prship(sp));
return 0;
}
count_planes(sp);
if (load_unload == LOAD &&
sp->shp_nchoppers >= mcp->m_nchoppers &&
sp->shp_nxlight >= mcp->m_nxlight &&
sp->shp_nplane >= mcp->m_nplanes) {
shp_nplane(sp, NULL, NULL, NULL)
>= mcp->m_nchoppers + mcp->m_nxlight + mcp->m_nplanes) {
if (noisy)
pr("%s doesn't have room for any more planes\n", prship(sp));
return 0;
@ -419,7 +417,7 @@ load_plane_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
continue;
/* ship to (plane or missle) sanity */
if (!could_be_on_ship(&pln, sp)) {
if (!could_be_on_ship(&pln, sp, 0, 0, 0, 0)) {
if (plchr[(int)pln.pln_type].pl_flags & P_L) {
strcpy(buf, "planes");
} else if (plchr[(int)pln.pln_type].pl_flags & P_K) {
@ -477,12 +475,11 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
char buf[1024];
int load_spy = 0;
count_units(sp);
if (load_unload == LOAD) {
if (opt_LANDSPIES) {
if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
(mchr[(int)sp->shp_type].m_nland == 0)) {
if (sp->shp_nland >= 2) {
if (shp_nland(sp) >= 2) {
pr("Non-land unit carrying subs can only carry up to two spy units.\n");
return 0;
}
@ -490,8 +487,7 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
load_spy = 1;
}
}
if ((!load_spy) &&
(sp->shp_nland >= mchr[(int)sp->shp_type].m_nland)) {
if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) {
if (noisy) {
if (mchr[(int)sp->shp_type].m_nland)
pr("%s doesn't have room for any more land units!\n",
@ -533,8 +529,7 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
prland(&land), land.lnd_land);
continue;
}
lnd_count_units(&land);
if (land.lnd_nland > 0) {
if (lnd_nland(&land)) {
if (noisy)
pr("%s cannot be loaded since it is carrying units\n",
prland(&land));
@ -574,12 +569,11 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
}
/* Fit unit on ship */
if (load_unload == LOAD) {
count_units(sp);
/* We have to check again, since it may have changed */
if (opt_LANDSPIES) {
if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
(mchr[(int)sp->shp_type].m_nland == 0)) {
if (sp->shp_nland >= 2) {
if (shp_nland(sp) >= 2) {
pr("Non-land unit carrying subs can only carry up to two spy units.\n");
return 0;
}
@ -587,8 +581,7 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
load_spy = 1;
}
}
if (!load_spy &&
(sp->shp_nland >= mchr[(int)sp->shp_type].m_nland)) {
if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) {
if (noisy) {
if (mchr[(int)sp->shp_type].m_nland)
pr("%s doesn't have room for any more land units!\n",
@ -605,11 +598,9 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
land.lnd_harden = 0;
land.lnd_mission = 0;
resupply_all(&land);
sp->shp_nland++;
putland(land.lnd_uid, &land);
if (!has_supply(&land))
pr("WARNING: %s is out of supply!\n", prland(&land));
putship(sp->shp_uid, sp);
snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
while (nxtitem(&pni, &plane)) {
if (plane.pln_flags & PLN_LAUNCHED)
@ -630,9 +621,7 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
if (!(lchr[(int)land.lnd_type].l_flags & L_SPY))
gift(sectp->sct_own, player->cnum, &land, buf);
land.lnd_ship = -1;
sp->shp_nland--;
putland(land.lnd_uid, &land);
putship(sp->shp_uid, sp);
/* Spies are unloaded quietly, others aren't, and
in the off chance they can carry a plane (missile?)
@ -759,8 +748,7 @@ load_plane_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
pr("%s cannot carry extra-light planes.\n", prland(lp));
return 0;
}
count_land_planes(lp);
if (load_unload == LOAD && lp->lnd_nxlight >= lcp->l_nxlight) {
if (load_unload == LOAD && lnd_nxlight(lp) >= lcp->l_nxlight) {
if (noisy)
pr("%s doesn't have room for any more extra-light planes\n",
prland(lp));
@ -946,12 +934,10 @@ load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
char prompt[512];
char buf[1024];
lnd_count_units(lp);
if (load_unload == LOAD
&& lp->lnd_nland >= lchr[lp->lnd_type].l_nland) {
&& lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) {
if (noisy) {
if (lp->lnd_nland)
if (lchr[lp->lnd_type].l_nland)
pr("%s doesn't have room for any more land units!\n",
prland(lp));
else
@ -991,8 +977,7 @@ load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
prland(&land), land.lnd_land);
continue;
}
lnd_count_units(&land);
if (land.lnd_nland > 0) {
if (lnd_nland(&land)) {
if (noisy)
pr("%s cannot be loaded since it is carrying units\n",
prland(&land));
@ -1022,10 +1007,9 @@ load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
/* Fit unit on ship */
if (load_unload == LOAD) {
lnd_count_units(lp);
if (lp->lnd_nland >= lchr[lp->lnd_type].l_nland) {
if (lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) {
if (noisy) {
if (lp->lnd_nland)
if (lchr[lp->lnd_type].l_nland)
pr("%s doesn't have room for any more land units!\n",
prland(lp));
else
@ -1040,11 +1024,9 @@ load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
land.lnd_harden = 0;
land.lnd_mission = 0;
resupply_all(&land);
lp->lnd_nland++;
putland(land.lnd_uid, &land);
if (!has_supply(&land))
pr("WARNING: %s is out of supply!\n", prland(&land));
putland(lp->lnd_uid, lp);
snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
while (nxtitem(&pni, &plane)) {
if (plane.pln_flags & PLN_LAUNCHED)
@ -1062,9 +1044,7 @@ load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
gift(sectp->sct_own, player->cnum, &land, buf);
land.lnd_land = -1;
lp->lnd_nland--;
putland(land.lnd_uid, &land);
putland(lp->lnd_uid, lp);
snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
while (nxtitem(&pni, &plane)) {
if (plane.pln_flags & PLN_LAUNCHED)

View file

@ -52,8 +52,6 @@ lsta(void)
if (!player->owner || land.lnd_own == 0)
continue;
lcp = lchr + land.lnd_type;
count_land_planes(&land);
if (nunits++ == 0) {
pr(" %16.16s s v s r r a f a a\n", "");
pr(" %16.16s p i p a n c i m a\n", "");

View file

@ -47,7 +47,7 @@ sdump(void)
struct shpstr ship;
int field[128];
struct natstr *np;
int n, i;
int n, i, npln, nch, nxl;
time_t now;
if (!snxtitem(&ni, EF_SHIP, player->argp[1], NULL))
@ -263,9 +263,8 @@ sdump(void)
while (nxtitem(&ni, &ship)) {
if (!player->owner || ship.shp_own == 0)
continue;
count_planes(&ship);
count_units(&ship);
nships++;
npln = shp_nplane(&ship, &nch, &nxl, NULL);
if (player->god)
pr("%d ", ship.shp_own);
pr("%d", ni.cur);
@ -300,16 +299,16 @@ sdump(void)
pr(" %d", ship.shp_item[I_FOOD]);
break;
case 10:
pr(" %d", ship.shp_nplane);
pr(" %d", npln - nch - nxl);
break;
case 11:
pr(" %d", ship.shp_nchoppers);
pr(" %d", nch);
break;
case 12:
pr(" %d", ship.shp_nxlight);
pr(" %d", nxl);
break;
case 13:
pr(" %d", ship.shp_nland);
pr(" %d", shp_nland(&ship));
break;
case 14:
pr(" %d", ship.shp_mobil);

View file

@ -41,7 +41,7 @@
int
shi(void)
{
int nships, noff;
int nships, noff, npln, nch, nxl;
struct nstr_item ni;
struct shpstr ship;
@ -52,8 +52,6 @@ shi(void)
while (nxtitem(&ni, &ship)) {
if (!player->owner || ship.shp_own == 0)
continue;
count_planes(&ship);
count_units(&ship);
if (nships++ == 0) {
if (player->god)
pr("own ");
@ -76,10 +74,9 @@ shi(void)
pr("%4d", ship.shp_item[I_UW]);
pr("%4d", ship.shp_item[I_FOOD]);
pr("%3d", ship.shp_nplane);
pr("%3d", ship.shp_nchoppers);
pr("%3d", ship.shp_nxlight);
pr("%3d", ship.shp_nland);
npln = shp_nplane(&ship, &nch, &nxl, NULL);
pr("%3d%3d%3d", npln - nch - nxl, nch, nxl);
pr("%3d", shp_nland(&ship));
pr("%4d", ship.shp_mobil);
pr("%5d\n", ship.shp_tech);
if (ship.shp_name[0] != 0) {

View file

@ -51,9 +51,6 @@ sstat(void)
while (nxtitem(&ni, &ship)) {
if (!player->owner || ship.shp_own == 0)
continue;
count_planes(&ship);
count_units(&ship);
if (nships++ == 0) {
pr("shp# %22.22s x,y eff tech def spd vis rng fir\n",
"ship-type");

View file

@ -242,7 +242,6 @@ tend_land(struct shpstr *tenderp, char *units)
continue;
/* Fit unit on ship */
count_units(&target);
getship(target.shp_uid, &target);
if ((!(lchr[(int)land.lnd_type].l_flags & L_LIGHT)) &&
@ -257,12 +256,12 @@ tend_land(struct shpstr *tenderp, char *units)
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) {
if (shp_nland(&target) > 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) {
} else if (shp_nland(&target) >= mchr[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));
@ -279,11 +278,9 @@ tend_land(struct shpstr *tenderp, char *units)
land.lnd_ship = target.shp_uid;
land.lnd_harden = 0;
land.lnd_mission = 0;
target.shp_nland++;
putland(land.lnd_uid, &land);
expose_ship(tenderp, &target);
putship(target.shp_uid, &target);
count_units(tenderp);
putship(tenderp->shp_uid, tenderp);
snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
while (nxtitem(&pni, &plane)) {

View file

@ -379,12 +379,6 @@ check_trade(void)
case EF_LAND:
tg.land.lnd_x = trade.trd_x;
tg.land.lnd_y = trade.trd_y;
if (tg.land.lnd_ship >= 0) {
struct shpstr ship;
getship(tg.land.lnd_ship, &ship);
ship.shp_nland--;
putship(ship.shp_uid, &ship);
}
tg.land.lnd_own = trade.trd_maxbidder;
tg.land.lnd_army = 0;
/* no cheap version of fly */

View file

@ -387,3 +387,83 @@ nuk_on_plane(struct plnstr *pp)
{
return unit_cargo_first(EF_PLANE, pp->pln_uid, EF_NUKE);
}
/*
* 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;
}

View file

@ -44,10 +44,15 @@
#include "optlist.h"
#include "nsc.h"
#include "product.h"
#include "unit.h"
static void *nsc_ver(struct valstr *, struct natstr *, void *);
static void *nsc_ver_maxnoc(struct valstr *, struct natstr *, void *);
static void *nsc_sct_terr(struct valstr *, struct natstr *, void *);
static void *nsc_cargo_nplane(struct valstr *, struct natstr *, void *);
static void *nsc_cargo_nchopper(struct valstr *, struct natstr *, void *);
static void *nsc_cargo_nxlight(struct valstr *, struct natstr *, void *);
static void *nsc_cargo_nland(struct valstr *, struct natstr *, void *);
static void *nsc_pln_att(struct valstr *, struct natstr *, void *);
static void *nsc_pln_def(struct valstr *, struct natstr *, void *);
static void *nsc_pln_nuketype(struct valstr *, struct natstr *, void *);
@ -221,8 +226,6 @@ struct castr ship_ca[] = {
#define CURSTR struct shpstr
NSC_GENITEM(EF_SHIP, EF_SHIP_CHR),
{"fleet", fldoff(shp_fleet), NSC_STRINGY, 1, NULL, EF_BAD, 0},
{"nplane", fldoff(shp_nplane), NSC_UCHAR, 0, NULL, EF_BAD, NSC_EXTRA},
{"nland", fldoff(shp_nland), NSC_UCHAR, 0, NULL, EF_BAD, NSC_EXTRA},
{"xstart", fldoff(shp_destx[0]), NSC_XCOORD, 0, NULL, EF_BAD, 0},
{"xend", fldoff(shp_destx[1]), NSC_XCOORD, 0, NULL, EF_BAD, 0},
{"ystart", fldoff(shp_desty[0]), NSC_YCOORD, 0, NULL, EF_BAD, 0},
@ -244,10 +247,6 @@ struct castr ship_ca[] = {
{"follow", fldoff(shp_follow), NSC_SHORT, 0, NULL, EF_BAD, 0},
{"name", fldoff(shp_name), NSC_STRINGY, MAXSHPNAMLEN, NULL,
EF_BAD, 0},
{"nchoppers", fldoff(shp_nchoppers), NSC_UCHAR, 0, NULL,
EF_BAD, NSC_EXTRA},
{"nxlight", fldoff(shp_nxlight), NSC_UCHAR, 0, NULL,
EF_BAD, NSC_EXTRA},
/* should let builder access xbuilt, ybuilt, but can't express that: */
{"xbuilt", fldoff(shp_orig_x), NSC_XCOORD, 0, NULL,
EF_BAD, NSC_DEITY},
@ -258,6 +257,10 @@ struct castr ship_ca[] = {
{"rflags", fldoff(shp_rflags), NSC_INT, 0, NULL,
EF_RETREAT_FLAGS, NSC_BITS},
{"rpath", fldoff(shp_rpath), NSC_STRINGY, RET_LEN, NULL, EF_BAD, 0},
{"nplane", 0, NSC_LONG, 0, nsc_cargo_nplane, EF_BAD, NSC_EXTRA},
{"nchoppers", 0, NSC_LONG, 0, nsc_cargo_nchopper, EF_BAD, NSC_EXTRA},
{"nxlight", 0, NSC_LONG, 0, nsc_cargo_nxlight, EF_BAD, NSC_EXTRA},
{"nland", 0, NSC_LONG, 0, nsc_cargo_nland, EF_BAD, NSC_EXTRA},
{NULL, 0, NSC_NOTYPE, 0, NULL, EF_BAD, 0}
#undef CURSTR
};
@ -335,8 +338,6 @@ struct castr land_ca[] = {
{"ship", fldoff(lnd_ship), NSC_SHORT, 0, NULL, EF_BAD, 0},
{"harden", fldoff(lnd_harden), NSC_CHAR, 0, NULL, EF_BAD, 0},
{"retreat", fldoff(lnd_retreat), NSC_SHORT, 0, NULL, EF_BAD, 0},
{"nxlight", fldoff(lnd_nxlight), NSC_UCHAR, 0, NULL,
EF_BAD, NSC_EXTRA},
{"rflags", fldoff(lnd_rflags), NSC_INT, 0, NULL,
EF_RETREAT_FLAGS, NSC_BITS},
{"rpath", fldoff(lnd_rpath), NSC_STRINGY, RET_LEN, NULL, EF_BAD, 0},
@ -346,7 +347,6 @@ struct castr land_ca[] = {
EF_PLAGUE_STAGES, NSC_DEITY},
{"ptime", fldoff(lnd_ptime), NSC_SHORT, 0, NULL, EF_BAD, NSC_DEITY},
{"land", fldoff(lnd_land), NSC_SHORT, 0, NULL, EF_BAD, 0},
{"nland", fldoff(lnd_nland), NSC_UCHAR, 0, NULL, EF_BAD, NSC_EXTRA},
{"access", fldoff(lnd_access), NSC_SHORT, 0, NULL, EF_BAD, 0},
{"att", 0, NSC_DOUBLE, 0, nsc_lnd_att, EF_BAD, NSC_EXTRA},
{"def", 0, NSC_DOUBLE, 0, nsc_lnd_def, EF_BAD, NSC_EXTRA},
@ -357,6 +357,8 @@ struct castr land_ca[] = {
{"acc", 0, NSC_LONG, 0, nsc_lnd_acc, EF_BAD, NSC_EXTRA},
{"dam", 0, NSC_LONG, 0, nsc_lnd_dam, EF_BAD, NSC_EXTRA},
{"aaf", 0, NSC_LONG, 0, nsc_lnd_aaf, EF_BAD, NSC_EXTRA},
{"nland", 0, NSC_LONG, 0, nsc_cargo_nland, EF_BAD, NSC_EXTRA},
{"nxlight", 0, NSC_LONG, 0, nsc_cargo_nxlight, EF_BAD, NSC_EXTRA},
#undef CURSTR
#define CURSTR struct lchrstr
{"spy", fldoff(l_spy), NSC_INT, 0, nsc_lchr, EF_BAD, NSC_EXTRA},
@ -769,6 +771,48 @@ nsc_sct_terr(struct valstr *val, struct natstr *np, void *ptr)
return ptr;
}
static void *
nsc_cargo_nplane(struct valstr *val, struct natstr *np, void *ptr)
{
struct empobj *obj = ptr;
int n, nch, nxl;
n = unit_nplane(obj->ef_type, obj->uid, &nch, &nxl, NULL);
val->val_as.lng = n - nch - nxl;
return NULL;
}
static void *
nsc_cargo_nchopper(struct valstr *val, struct natstr *np, void *ptr)
{
struct empobj *obj = ptr;
int n;
unit_nplane(obj->ef_type, obj->uid, &n, NULL, NULL);
val->val_as.lng = n;
return NULL;
}
static void *
nsc_cargo_nxlight(struct valstr *val, struct natstr *np, void *ptr)
{
struct empobj *obj = ptr;
int n;
unit_nplane(obj->ef_type, obj->uid, NULL, &n, NULL);
val->val_as.lng = n;
return NULL;
}
static void *
nsc_cargo_nland(struct valstr *val, struct natstr *np, void *ptr)
{
struct empobj *obj = ptr;
val->val_as.lng = unit_cargo_count(obj->ef_type, obj->uid, EF_LAND);
return NULL;
}
static void *
nsc_pln_def(struct valstr *val, struct natstr *np, void *ptr)
{

View file

@ -386,7 +386,6 @@ put_combat(struct combat *com)
}
if (!(com->lnd_lcp->l_flags & L_SPY))
land.lnd_item[I_MILIT] = com->mil;
lnd_count_units(&land);
if (com->own == player->cnum) {
land.lnd_mission = 0;
land.lnd_rflags = 0;
@ -409,7 +408,6 @@ put_combat(struct combat *com)
ship.shp_pstage = PLG_EXPOSED;
}
ship.shp_item[I_MILIT] = com->mil;
count_units(&ship);
if (com->own == player->cnum) {
ship.shp_mission = 0;
ship.shp_rflags = 0;

View file

@ -386,54 +386,6 @@ intelligence_report(int destination, struct lndstr *lp, int spy,
}
}
void
count_units(struct shpstr *sp)
{
struct nstr_item ni;
struct lndstr land;
int nland = 0;
if (sp->shp_effic < SHIP_MINEFF)
return;
snxtitem_xy(&ni, EF_LAND, sp->shp_x, sp->shp_y);
while (nxtitem(&ni, &land)) {
if (land.lnd_own == 0)
continue;
if (land.lnd_ship == sp->shp_uid)
nland++;
}
if (sp->shp_nland != nland) {
sp->shp_nland = nland;
putship(sp->shp_uid, sp);
}
}
void
lnd_count_units(struct lndstr *lp)
{
struct nstr_item ni;
struct lndstr land;
int nland = 0;
if (lp->lnd_effic < LAND_MINEFF)
return;
snxtitem_xy(&ni, EF_LAND, lp->lnd_x, lp->lnd_y);
while (nxtitem(&ni, &land)) {
if (land.lnd_own == 0)
continue;
if (land.lnd_land == lp->lnd_uid)
nland++;
}
if (lp->lnd_nland != nland) {
lp->lnd_nland = nland;
putland(lp->lnd_uid, lp);
}
}
void
lnd_sel(struct nstr_item *ni, struct emp_qelem *list)
{

View file

@ -202,8 +202,6 @@ pln_oneway_to_carrier_ok(struct emp_qelem *bomb_list,
if (cno < 0 || !getship(cno, &ship))
return 0;
count_planes(&ship);
/* for both lists */
for (list = bomb_list;
list;
@ -232,8 +230,7 @@ pln_newlanding(struct emp_qelem *list, coord tx, coord ty, int cno)
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
plp = (struct plist *)qp;
if (cno >= 0) {
count_planes(&ship);
if (!could_be_on_ship(&plp->plane, &ship))
if (!could_be_on_ship(&plp->plane, &ship, 0, 0, 0, 0))
pr("\t%s cannot land on ship #%d! %s aborts!\n",
prplane(&plp->plane), cno, prplane(&plp->plane));
else if (!put_plane_on_ship(&plp->plane, &ship))
@ -259,8 +256,6 @@ pln_newlanding(struct emp_qelem *list, coord tx, coord ty, int cno)
plp->plane.pln_ship = cno;
}
}
if (cno >= 0)
putship(ship.shp_uid, &ship);
}
void
@ -812,81 +807,50 @@ pln_put1(struct plist *plp)
free(plp);
}
/*
* Can PP be loaded on a ship of SP's type?
* Assume that it already carries N planes, of which NCH are choppers,
* NXL xlight, NMSL light missiles, and the rest are light fixed-wing
* planes.
*/
int
could_be_on_ship(struct plnstr *pp, struct shpstr *sp,
int n, int nch, int nxl, int nmsl)
{
struct plchrstr *pcp = &plchr[pp->pln_type];
struct mchrstr *mcp = &mchr[sp->shp_type];
if (pcp->pl_flags & P_K)
nch++;
else if (pcp->pl_flags & P_E)
nxl++;
else if (!(pcp->pl_flags & P_L))
return 0;
else if (pcp->pl_flags & P_M)
nmsl++;
n++;
n -= MIN(nch, mcp->m_nchoppers);
n -= MIN(nxl, mcp->m_nxlight);
if (nmsl && !(mcp->m_flags & (M_MSL | M_FLY)))
return 0; /* missile slots wanted */
if (nmsl < n && !(mcp->m_flags & M_FLY))
return 0; /* fixed-wing slots wanted */
return n <= mcp->m_nplanes;
}
/*
* Fit a plane of PP's type on ship SP.
* Adjust SP's plane counters.
* Updating the plane accordingly is the caller's job.
* Return whether it fits.
*/
static int
fit_plane_on_ship(struct plnstr *pp, struct shpstr *sp)
{
struct plchrstr *pcp = plchr + pp->pln_type;
struct mchrstr *mcp = mchr + sp->shp_type;
int wanted;
int n, nch, nxl, nmsl;
if (pcp->pl_flags & P_K) {
/* chopper, try chopper slot first */
if (sp->shp_nchoppers < mcp->m_nchoppers)
return ++sp->shp_nchoppers;
/* else try plane slot */
wanted = M_FLY;
} else if (pcp->pl_flags & P_E) {
/* x-light, try x-light slot first */
if (sp->shp_nxlight < mcp->m_nxlight)
return ++sp->shp_nxlight;
/* else try plane slot */
wanted = M_MSL | M_FLY;
} else if (!(pcp->pl_flags & P_L)) {
/* not light, no go */
wanted = 0;
} else if (pcp->pl_flags & P_M) {
/* missile, use plane slot */
wanted = M_MSL | M_FLY;
} else {
/* fixed-wing plane, use plane slot */
wanted = M_FLY;
}
if ((mcp->m_flags & wanted) == 0)
return 0; /* ship not capable */
if (sp->shp_nplane < mcp->m_nplanes)
return ++sp->shp_nplane;
return 0;
}
/*
* Fit a plane of PP's type off ship SP.
* Adjust SP's plane counters, badly. You need to run count_planes()
* before the next fit_plane_on_ship().
* Updating the plane accordingly is the caller's job.
*/
static void
fit_plane_off_ship(struct plnstr *pp, struct shpstr *sp)
{
/*
* Frees chopper and nxlight slots first, which is why we need to
* run count_planes() before fit_plane_on_ship().
*/
struct plchrstr *pcp = plchr + pp->pln_type;
if (pcp->pl_flags & P_K) {
if (sp->shp_nchoppers) {
sp->shp_nchoppers--;
return;
}
} else if (pcp->pl_flags & P_E) {
if (sp->shp_nxlight) {
sp->shp_nxlight--;
return;
}
}
if (CANT_HAPPEN(sp->shp_nplane == 0))
sp->shp_nplane = 1;
sp->shp_nplane--;
n = shp_nplane(sp, &nch, &nxl, &nmsl);
return could_be_on_ship(pp, sp, n, nch, nxl, nmsl);
}
int
@ -902,7 +866,6 @@ put_plane_on_ship(struct plnstr *plane, struct shpstr *ship)
plane->pln_y = ship->shp_y;
plane->pln_ship = ship->shp_uid;
putplane(plane->pln_uid, plane);
putship(ship->shp_uid, ship);
return 1;
}
@ -912,15 +875,12 @@ take_plane_off_ship(struct plnstr *plane, struct shpstr *ship)
if (CANT_HAPPEN(plane->pln_ship != ship->shp_uid))
return;
fit_plane_off_ship(plane, ship);
plane->pln_ship = -1;
putship(ship->shp_uid, ship);
putplane(plane->pln_uid, plane);
}
/*
* Fit a plane of PP's type on land unit LP.
* Adjust LP's plane counters.
* Updating the plane accordingly is the caller's job.
* Return whether it fits.
*/
@ -930,23 +890,7 @@ fit_plane_on_land(struct plnstr *pp, struct lndstr *lp)
struct plchrstr *pcp = plchr + pp->pln_type;
struct lchrstr *lcp = lchr + lp->lnd_type;
if ((pcp->pl_flags & P_E) && lp->lnd_nxlight < lcp->l_nxlight)
return ++lp->lnd_nxlight;
return 0;
}
/*
* Fit a plane of PP's type off land unit LP.
* Adjust LP's plane counters.
* Updating the plane accordingly is the caller's job.
*/
static void
fit_plane_off_land(struct plnstr *pp, struct lndstr *lp)
{
if (CANT_HAPPEN(lp->lnd_nxlight == 0))
lp->lnd_nxlight = 1;
lp->lnd_nxlight--;
return (pcp->pl_flags & P_E) && lnd_nxlight(lp) < lcp->l_nxlight;
}
int
@ -962,7 +906,6 @@ put_plane_on_land(struct plnstr *plane, struct lndstr *land)
plane->pln_y = land->lnd_y;
plane->pln_land = land->lnd_uid;
putplane(plane->pln_uid, plane);
putland(land->lnd_uid, land);
return 1;
}
@ -972,25 +915,10 @@ take_plane_off_land(struct plnstr *plane, struct lndstr *land)
if (CANT_HAPPEN(plane->pln_land != land->lnd_uid))
return;
fit_plane_off_land(plane, land);
plane->pln_land = -1;
putland(land->lnd_uid, land);
putplane(plane->pln_uid, plane);
}
/*
* Could a plane of PP's type be on on ship SP?
*/
int
could_be_on_ship(struct plnstr *pp, struct shpstr *sp)
{
struct shpstr ship;
ship = *sp;
ship.shp_nplane = ship.shp_nchoppers = ship.shp_nxlight = 0;
return fit_plane_on_ship(pp, &ship);
}
void
plane_sweep(struct emp_qelem *plane_list, coord x, coord y)
{
@ -1035,65 +963,6 @@ plane_sweep(struct emp_qelem *plane_list, coord x, coord y)
putsect(&sect);
}
void
count_planes(struct shpstr *sp)
{
struct nstr_item ni;
struct plnstr plane;
int nplane, nchoppers, nxlight;
if (sp->shp_effic < SHIP_MINEFF)
return;
nplane = sp->shp_nplane;
sp->shp_nplane = 0;
nchoppers = sp->shp_nchoppers;
sp->shp_nchoppers = 0;
nxlight = sp->shp_nxlight;
sp->shp_nxlight = 0;
snxtitem_xy(&ni, EF_PLANE, sp->shp_x, sp->shp_y);
while (nxtitem(&ni, &plane)) {
if (plane.pln_own == 0)
continue;
if (plane.pln_ship == sp->shp_uid) {
if (!fit_plane_on_ship(&plane, sp))
CANT_REACH();
}
}
if (nplane != sp->shp_nplane ||
nxlight != sp->shp_nxlight || nchoppers != sp->shp_nchoppers) {
putship(sp->shp_uid, sp);
}
}
void
count_land_planes(struct lndstr *lp)
{
struct nstr_item ni;
struct plnstr plane;
int nplane;
if (lp->lnd_effic < LAND_MINEFF)
return;
nplane = lp->lnd_nxlight;
lp->lnd_nxlight = 0;
snxtitem_all(&ni, EF_PLANE);
while (nxtitem(&ni, &plane)) {
if (plane.pln_own == 0)
continue;
if (plane.pln_land == lp->lnd_uid)
if (!fit_plane_on_land(&plane, lp))
CANT_REACH();
}
if (lp->lnd_nxlight != nplane)
putland(lp->lnd_uid, lp);
}
int
pln_hitchance(struct plnstr *pp, int hardtarget, int type)
{

View file

@ -148,7 +148,7 @@ trade_desc(struct trdstr *tp, union empobj_storage *tgp)
land.lnd_tech,
land.lnd_effic,
lchr[(int)land.lnd_type].l_name, land.lnd_uid);
if (land.lnd_nxlight) {
if (lnd_nxlight(&land)) {
snxtitem_all(&ni, EF_PLANE);
while (nxtitem(&ni, &plane)) {
if (plane.pln_land == land.lnd_uid) {

View file

@ -46,7 +46,7 @@ unit_list(struct emp_qelem *unit_list)
struct emp_qelem *qp;
struct emp_qelem *next;
struct ulist *ulp;
int type;
int type, npln, nch, nxl;
struct empobj *unit;
struct lndstr *lnd;
struct shpstr *shp;
@ -80,18 +80,14 @@ unit_list(struct emp_qelem *unit_list)
if (type == EF_LAND) {
pr("%4d", lnd->lnd_item[I_SHELL]);
pr("%4d", lnd->lnd_item[I_GUN]);
count_land_planes(lnd);
pr("%3d", lnd->lnd_nxlight);
pr("%3d", lnd_nxlight(lnd));
} else {
pr("%4d", shp->shp_item[I_MILIT]);
pr("%4d", shp->shp_item[I_SHELL]);
pr("%4d", shp->shp_item[I_GUN]);
count_planes(shp);
pr("%3d", shp->shp_nplane);
pr("%3d", shp->shp_nchoppers);
pr("%3d", shp->shp_nxlight);
count_units(shp);
pr("%3d", shp->shp_nland);
npln = shp_nplane(shp, &nch, &nxl, NULL);
pr("%3d%3d%3d", npln - nch - nxl, nch, nxl);
pr("%3d", shp_nland(shp));
}
pr("%4d", unit->mobil);
pr("%4d", unit->tech);