(pln_oneway_to_carrier_ok): New.

(fly, reco): Use it to prevent flying to a carrier that doesn't have
space for the planes.  Previously, planes that did this were
teleported home, which could be abused.

(fly): Fail if pln_sel() comes up empty, just like the other commands
to fly planes.
This commit is contained in:
Markus Armbruster 2004-08-13 20:22:03 +00:00
parent ab0d5a87bd
commit 1127762cc1
4 changed files with 66 additions and 2 deletions

View file

@ -393,6 +393,8 @@ extern void pln_init(int, s_char *);
/* plnsub.c */
extern void count_planes(struct shpstr *);
extern int pln_onewaymission(struct sctstr *, int *, int *);
extern int pln_oneway_to_carrier_ok(struct emp_qelem *,
struct emp_qelem *, int);
extern void pln_newlanding(struct emp_qelem *, coord, coord, int);
extern int can_be_on_ship(int, int);
extern int put_plane_on_ship(struct plnstr *, struct shpstr *);

View file

@ -121,10 +121,18 @@ fly(void)
*/
pln_sel(&ni_bomb, &bomb_list, &ap_sect, ap_to_target,
1, wantflags, P_M | P_O);
if (QEMPTY(&bomb_list)) {
pr("No planes could be equipped for the mission.\n");
return RET_FAIL;
}
wantflags |= P_F;
wantflags |= P_ESC;
pln_sel(&ni_esc, &esc_list, &ap_sect, ap_to_target,
1, wantflags, P_M | P_O);
if (cno >= 0 && !pln_oneway_to_carrier_ok(&bomb_list, &esc_list, cno)) {
pr("Not enough room on ship #%d!\n", cno);
return RET_FAIL;
}
/*
* now arm and equip the bombers, transports, whatever.
* tech is stored in high 16 bits of mission_flags.

View file

@ -115,6 +115,10 @@ reco(void)
wantflags |= P_ESC;
pln_sel(&ni_esc, &esc_list, &ap_sect, ap_to_target,
1, wantflags, P_M | P_O);
if (cno >= 0 && !pln_oneway_to_carrier_ok(&bomb_list, &esc_list, cno)) {
pr("Not enough room on ship #%d!\n", cno);
return RET_FAIL;
}
/*
* now arm and equip the bombers, transports, whatever.
*/

View file

@ -159,6 +159,57 @@ pln_onewaymission(struct sctstr *target, int *shipno, int *flagp)
return 0;
}
int
pln_oneway_to_carrier_ok(struct emp_qelem *bomb_list,
struct emp_qelem *esc_list, int cno)
{
struct emp_qelem *list, *qp;
struct plist *plp;
struct plchrstr *pcp;
struct shpstr ship;
struct mchrstr *mcp;
int nchoppers, nxlight, nplane;
if (cno < 0 || !getship(cno, &ship))
return 0;
count_planes(&ship);
nchoppers = ship.shp_nchoppers;
nxlight = ship.shp_nxlight;
nplane = ship.shp_nplane;
mcp = &mchr[(int)ship.shp_type];
/* for both lists */
for (list = bomb_list;
list;
list = list == bomb_list ? esc_list : NULL) {
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
/* FIXME duplicates put_plane_on_ship() logic; refactor */
plp = (struct plist *)qp;
pcp = &plchr[(int)plp->plane.pln_type];
if (plp->plane.pln_ship == ship.shp_uid)
continue;
/* try chopper space */
if ((pcp->pl_flags & P_K) && (mcp->m_flags & M_CHOPPER)
&& nchoppers < mcp->m_nchoppers)
++nchoppers;
/* try xlight space */
else if ((pcp->pl_flags & P_E) && (mcp->m_flags & M_XLIGHT)
&& nxlight < mcp->m_nxlight)
++nxlight;
/* try plane space */
else if ((((pcp->pl_flags & P_L) && (mcp->m_flags & M_FLY))
|| ((pcp->pl_flags & P_M) && (pcp->pl_flags & P_L)
&& (mcp->m_flags & M_MSL)))
&& nplane < mcp->m_nplanes)
++nplane;
else
return 0; /* won't be able to land */
}
}
return 1;
}
void
pln_newlanding(struct emp_qelem *list, coord tx, coord ty, int cno)
{
@ -171,7 +222,6 @@ pln_newlanding(struct emp_qelem *list, coord tx, coord ty, int cno)
getship(cno, &ship);
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
plp = (struct plist *)qp;
/* XXX - need to restrict # of planes per ship */
if (cno >= 0) {
count_planes(&ship);
if (!can_be_on_ship(plp->plane.pln_uid, ship.shp_uid))
@ -681,7 +731,7 @@ pln_put(struct emp_qelem *list)
getsect(pp->pln_x, pp->pln_y, &sect);
if (sect.sct_type == SCT_WATER || sect.sct_type == SCT_WASTE) {
mpr(pp->pln_own,
"Nowwhere to land at %s, plane #%d crashes and burns...\n",
"Nowhere to land at %s, plane #%d crashes and burns...\n",
xyas(pp->pln_x, pp->pln_y, pp->pln_own), pp->pln_uid);
pp->pln_effic = 0;
}