/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2010, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* Dave Pare, 1986
* Ken Stevens, 1995
* Steve McClure, 1998-2000
- * Markus Armbruster, 2004-2008
+ * Markus Armbruster, 2004-2009
*/
#include <config.h>
#include "ship.h"
#include "xy.h"
-static int pln_equip(struct plist *, struct ichrstr *, int, char);
static int fit_plane_on_ship(struct plnstr *, struct shpstr *);
/*
int there;
int max;
- if (ip == 0)
+ if (!ip)
return;
amt = 0;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
plp = (struct plist *)qp;
- amt += plp->misc;
+ amt += plp->load;
}
if (cno < 0) {
getsect(tx, ty, §);
amt = 0;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
plp = (struct plist *)qp;
- amt += plp->misc;
+ amt += plp->load;
}
if (amt > 0) {
/*
* Has PP's type capabilities satisfying WANTFLAGS and NOWANTFLAGS?
* A plane type is capable unless
+ * - it lacks all of the P_B, P_T in WANTFLAGS, or
* - it lacks all of the P_F, P_ESC in WANTFLAGS, or
* - it lacks all of the P_E, P_L, P_K in WANTFLAGS, or
* - it lacks any of the other capabilities in WANTFLAGS, or
{
int flags = plchr[(int)pp->pln_type].pl_flags;
+ if (wantflags & (P_B | P_T)) {
+ if ((flags & wantflags & (P_B | P_T)) == 0)
+ return 0;
+ wantflags &= ~(P_B | P_T);
+ }
+
if (wantflags & (P_F | P_ESC)) {
if ((flags & wantflags & (P_F | P_ESC)) == 0)
return 0;
return 1;
}
+/*
+ * Return union of capabilities of planes in LIST.
+ */
+int
+pln_caps(struct emp_qelem *list)
+{
+ struct emp_qelem *qp;
+ struct plist *plp;
+ int fl;
+
+ fl = 0;
+ for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
+ plp = (struct plist *)qp;
+ fl |= plp->pcp->pl_flags;
+ }
+
+ return fl;
+}
+
/*
* Find plane types that can operate from carrier SP.
* If MSL find missile types, else non-missile types.
plane.pln_mission = 0;
putplane(plane.pln_uid, &plane);
plp = malloc(sizeof(struct plist));
- plp->misc = 0;
- plp->bombs = 0;
+ plp->load = 0;
plp->pcp = pcp;
plp->plane = plane;
emp_insque(&plp->queue, list);
}
void
-pln_arm(struct emp_qelem *list, int dist, char mission, struct ichrstr *ip,
- int flags)
+pln_arm(struct emp_qelem *list, int dist, char mission, struct ichrstr *ip)
{
struct emp_qelem *qp;
struct emp_qelem *next;
pp = &plp->plane;
getplane(pp->pln_uid, pp);
if ((pp->pln_flags & PLN_LAUNCHED)
- || pln_equip(plp, ip, flags, mission) < 0) {
+ || pln_equip(plp, ip, mission) < 0) {
emp_remque(qp);
free(qp);
continue;
}
pp->pln_flags |= PLN_LAUNCHED;
- pp->pln_mobil -= pln_mobcost(dist, pp, flags);
+ pp->pln_mobil -= pln_mobcost(dist, pp, mission);
putplane(pp->pln_uid, pp);
pr("%s equipped\n", prplane(pp));
}
}
-static int
-pln_equip(struct plist *plp, struct ichrstr *ip, int flags, char mission)
+int
+pln_equip(struct plist *plp, struct ichrstr *ip, char mission)
{
struct plchrstr *pcp;
struct plnstr *pp;
item = sect.sct_item;
own = sect.sct_oldown;
}
- if (ip) {
- if (ip->i_uid == I_CIVIL) {
- if (pp->pln_own != own) {
- pr("You don't control those civilians!\n");
- return -1;
- }
- }
- }
if (pcp->pl_fuel > item[I_PETROL]) {
pr("%s not enough petrol there!\n", prplane(pp));
return -1;
}
item[I_PETROL] -= pcp->pl_fuel;
- if ((flags & P_F) == 0) {
- load = pln_load(pp);
- itype = I_NONE;
- needed = 0;
- switch (mission) {
- case 's': /* strategic bomb */
- case 'p': /* pinpoint bomb */
- if (nuk_on_plane(pp) < 0) {
- itype = I_SHELL;
- needed = load;
- }
+ load = pln_load(pp);
+ itype = I_NONE;
+ switch (mission) {
+ case 's': /* strategic bomb */
+ case 'p': /* pinpoint bomb */
+ itype = I_SHELL;
+ break;
+ case 't': /* transport */
+ if (!(pcp->pl_flags & P_C) || !ip)
break;
- case 't': /* transport */
- case 'd': /* drop */
- if ((pcp->pl_flags & P_C) == 0 || ip == 0)
- break;
- itype = ip->i_uid;
- needed = (load * 2) / ip->i_lbs;
+ itype = ip->i_uid;
+ load *= 2;
+ break;
+ case 'm': /* mine */
+ if ((pcp->pl_flags & P_MINE) == 0)
break;
- case 'm': /* mine */
- if ((pcp->pl_flags & P_MINE) == 0)
- break;
- itype = I_SHELL;
- needed = (load * 2) / ip->i_lbs;
+ itype = I_SHELL;
+ load *= 2;
+ break;
+ case 'd': /* drop */
+ if (!(pcp->pl_flags & P_C) || CANT_HAPPEN(!ip))
break;
- case 'a': /* paradrop */
- if ((pcp->pl_flags & (P_V | P_C)) == 0)
- break;
- itype = I_MILIT;
- needed = load / ip->i_lbs;
+ itype = ip->i_uid;
+ if (pcp->pl_flags & P_V)
+ load *= 2;
+ break;
+ case 'a': /* paradrop */
+ if (!(pcp->pl_flags & P_P))
break;
- case 'r': /* reconnaissance */
+ itype = I_MILIT;
+ if (pcp->pl_flags & P_V)
+ load *= 2;
+ break;
+ case 'r': /* reconnaissance */
+ case 'e': /* escort */
+ load = 0;
+ break;
+ case 'i': /* missile interception */
+ if (CANT_HAPPEN(!(pcp->pl_flags & P_M)
+ || !(pcp->pl_flags & (P_N | P_O))))
break;
- default:
- CANT_REACH();
- }
- if (itype != I_NONE && needed <= 0) {
+ if (load)
+ itype = I_SHELL;
+ break;
+ default:
+ CANT_REACH();
+ load = 0;
+ }
+
+ if (itype != I_NONE) {
+ needed = load / ichr[itype].i_lbs;
+ if (needed <= 0) {
pr("%s can't contribute to mission\n", prplane(pp));
return -1;
}
- if (itype != I_NONE) {
-#if 0
- /* Supply is broken somewhere, so don't use it for now */
- if (itype == I_SHELL && item[itype] < needed)
- item[itype] += supply_commod(plp->plane.pln_own,
- plp->plane.pln_x,
- plp->plane.pln_y,
- I_SHELL, needed);
-#endif
- abandon_needed = !!would_abandon(§, itype, needed, NULL);
- if (item[itype] < needed + abandon_needed) {
- pr("Not enough %s for %s\n", ichr[itype].i_name, prplane(pp));
+ if (nuk_on_plane(pp) >= 0) {
+ if (mission == 's' || mission == 't')
+ needed = 0;
+ else {
+ pr("%s can't fly this mission"
+ " while it is carrying a nuclear weapon",
+ prplane(pp));
return -1;
}
- item[itype] -= needed;
}
- if (itype == I_SHELL && (mission == 's' || mission == 'p'))
- plp->bombs = needed;
- else
- plp->misc = needed;
+ if (itype == I_CIVIL && pp->pln_own != own) {
+ pr("You don't control those civilians!\n");
+ return -1;
+ }
+#if 0
+ /* Supply is broken somewhere, so don't use it for now */
+ if (itype == I_SHELL && item[itype] < needed)
+ item[itype] += supply_commod(plp->plane.pln_own,
+ plp->plane.pln_x,
+ plp->plane.pln_y,
+ I_SHELL, needed);
+#endif
+ abandon_needed = !!would_abandon(§, itype, needed, NULL);
+ if (item[itype] < needed + abandon_needed) {
+ pr("Not enough %s for %s\n", ichr[itype].i_name, prplane(pp));
+ return -1;
+ }
+ item[itype] -= needed;
+ plp->load = needed;
}
+
if (pp->pln_ship >= 0) {
if (pp->pln_own != ship.shp_own) {
wu(0, ship.shp_own,
if (mines_there == 0)
return;
- if ((sect.sct_type != SCT_WATER) && (sect.sct_type != SCT_HARBR))
+ if (sect.sct_type != SCT_WATER)
return;
for (qp = plane_list->q_forw; ((qp != plane_list) && (mines_there));
return hitchance;
}
-/* return 0 if there was a nuclear detonation */
-
int
-pln_damage(struct plnstr *pp, coord x, coord y, char type, int *nukedamp,
- int noisy)
+pln_damage(struct plnstr *pp, char type, int noisy)
{
- struct nukstr nuke;
struct plchrstr *pcp = plchr + pp->pln_type;
int load, i;
int hitroll;
int effective = 1;
int pinbomber = 0;
- if (getnuke(nuk_on_plane(pp), &nuke)) {
- mpr(pp->pln_own, "Releasing RV's for %s detonation...\n",
- pp->pln_flags & PLN_AIRBURST ? "airburst" : "groundburst");
- *nukedamp = detonate(&nuke, x, y,
- pp->pln_flags & PLN_AIRBURST);
+ if (CANT_HAPPEN(nuk_on_plane(pp) >= 0))
return 0;
- }
- *nukedamp = 0;
load = pln_load(pp);
if (!load) /* e.g. ab, blowing up on launch pad */
}
int
-pln_mobcost(int dist, struct plnstr *pp, int flags)
+pln_mobcost(int dist, struct plnstr *pp, char mission)
{
double cost;
cost = 20.0 / (pp->pln_effic / 100.0);
- if ((flags & P_F) || (flags & P_ESC))
- cost /= 2;
+ if (mission == 'e' || mission == 0)
+ cost /= 2; /* escort or intercept */
return ldround(cost * dist / pln_range_max(pp) + 5, 1);
}