* ---
*
* aircombat.c: Deal with air to air combat
- *
+ *
* Known contributors to this file:
* Dave Pare, 1986
* Thomas Ruschak, 1992
* Steve McClure, 1996
- * Markus Armbruster, 2006
+ * Markus Armbruster, 2006-2008
*/
#include <config.h>
static void ac_landflak(struct emp_qelem *, coord, coord);
static void ac_shipflak(struct emp_qelem *, coord, coord);
static void ac_fireflak(struct emp_qelem *, natid, int);
-static void getilist(struct emp_qelem *, natid,
- struct emp_qelem *, struct emp_qelem *,
- struct emp_qelem *, struct emp_qelem *);
+static void getilist(struct emp_qelem *, natid);
static int do_evade(struct emp_qelem *, struct emp_qelem *);
void
ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
coord x, coord y, char *path, int mission_flags,
- int no_air_defense, struct emp_qelem *obomb,
- struct emp_qelem *oesc)
+ int no_air_defense)
{
int val, non_missiles;
int rel;
}
}
- pln_removedupes(bomb_list, esc_list);
while ((dir = mypath[myp++]) && !QEMPTY(bomb_list)) {
if ((val = diridx(dir)) == DIR_STOP)
break;
continue;
if (unfriendly[sect.sct_own] && !gotilist[sect.sct_own]) {
- getilist(&ilist[sect.sct_own], sect.sct_own,
- bomb_list, esc_list, obomb, oesc);
+ getilist(&ilist[sect.sct_own], sect.sct_own);
gotilist[sect.sct_own]++;
}
if (rel > HOSTILE)
if (changed)
writemap(player->cnum);
/* Now, if the bomber and escort lists are empty, we are done */
- if (QEMPTY(bomb_list) && QEMPTY(esc_list)) {
- if (mission_flags & P_A)
- free_shiplist(&head);
- return;
- }
+ if (QEMPTY(bomb_list) && QEMPTY(esc_list))
+ goto out;
/* Something made it through */
/* Go figure out if there are ships in this sector, and who's they are */
if (unfriendly[cn]) {
/* They are unfriendly too */
if (!gotilist[cn]) {
- getilist(&ilist[cn], cn, bomb_list, esc_list, obomb,
- oesc);
+ getilist(&ilist[cn], cn);
gotilist[cn]++;
}
PR(plane_owner, "Flying over %s ships in %s\n",
if (unfriendly[cn]) {
/* They are unfriendly too */
if (!gotilist[cn]) {
- getilist(&ilist[cn], cn, bomb_list, esc_list, obomb,
- oesc);
+ getilist(&ilist[cn], cn);
gotilist[cn]++;
}
PR(plane_owner, "Flying over %s land units in %s\n",
}
}
}
+out:
if (mission_flags & P_A)
free_shiplist(&head);
+ for (cn = 1; cn < MAXNOC; cn++) {
+ if (gotilist[cn])
+ pln_put(&ilist[cn]);
+ }
}
static int
free(dqp);
continue;
}
- if (mission_pln_equip(dplp, 0, P_F, 0) < 0) {
+ if (CANT_HAPPEN(dplp->plane.pln_flags & PLN_LAUNCHED)
+ || mission_pln_equip(dplp, 0, P_F, 0) < 0) {
emp_remque(dqp);
free(dqp);
continue;
}
+ dplp->plane.pln_flags |= PLN_LAUNCHED;
+ putplane(dplp->plane.pln_uid, &dplp->plane);
if (first) {
first = 0;
PR(plane_owner, "%s launches SAMs!\n", cname(def_own));
- PR(def_own, "Launching SAMs at %s planes!\n",
- cname(plane_owner));
+ PR(def_own, "Launching SAMs at %s planes over %s!\n",
+ cname(plane_owner), xyas(x, y, def_own));
ac_combat_headers(plane_owner, def_own);
}
ac_dog(aplp, dplp);
dist = mapdist(x, y, pp->pln_x, pp->pln_y) * 2;
if (pp->pln_range < dist)
continue;
- if (mission_pln_equip(plp, 0, P_F, 0) < 0) {
+ if (CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED)
+ || mission_pln_equip(plp, 0, P_F, 0) < 0) {
emp_remque(qp);
free(qp);
continue;
/* got one; delete from def_list, add to int_list */
emp_remque(qp);
emp_insque(qp, &int_list);
+ pp->pln_flags |= PLN_LAUNCHED;
pp->pln_mobil -= pln_mobcost(dist, pp, P_F);
putplane(pp->pln_uid, pp);
icount++;
return;
PR(plane_owner, "%d %s fighter%s rising to intercept!\n",
icount, cname(def_own), icount == 1 ? " is" : "s are");
- PR(def_own, "%d fighter%s intercepting %s planes!\n",
- icount, icount == 1 ? " is" : "s are", cname(plane_owner));
+ PR(def_own, "%d fighter%s intercepting %s planes over %s!\n",
+ icount, icount == 1 ? " is" : "s are", cname(plane_owner),
+ xyas(x, y, def_own));
ac_combat_headers(plane_owner, def_own);
ac_airtoair(esc_list, &int_list);
ac_airtoair(bomb_list, &int_list);
PR(plane_owner, "\n");
PR(def_own, "\n");
+ pln_put(&int_list);
}
void
PR(def_own, " %3.3s #%-4d %3.3s #%-4d",
dp->pcp->pl_name,
dp->plane.pln_uid, ap->pcp->pl_name, ap->plane.pln_uid);
- if (ap->plane.pln_att == 0) {
- att = ap->plane.pln_def * ap->plane.pln_effic / 100;
- att = MAX(att, ap->pcp->pl_def / 2);
- } else {
- att = ap->plane.pln_att * ap->plane.pln_effic / 100;
- att = MAX(att, ap->pcp->pl_att / 2);
- }
+ att = pln_att(&ap->plane);
+ if (att == 0)
+ att = pln_def(&ap->plane);
+ att = att * ap->plane.pln_effic / 100;
+ att = MAX(att, ap->pcp->pl_def / 2);
- def = dp->plane.pln_def * dp->plane.pln_effic / 100;
+ def = pln_def(&dp->plane) * dp->plane.pln_effic / 100;
def = MAX(def, dp->pcp->pl_def / 2);
if ((ap->pcp->pl_flags & P_F) && ap->bombs != 0)
int disp;
char dmess[255];
int eff;
- struct shpstr ship;
- struct lndstr land;
natid plane_owner;
disp = 0;
pp->pln_effic = eff;
pp->pln_mobil -= MIN(32 + pp->pln_mobil, dam / 2);
- if (disp == 1) {
- if (from != 0 && (plp->pcp->pl_flags & P_M) == 0)
+ if (disp) {
+ if (disp == 1 && from != 0 && (plp->pcp->pl_flags & P_M) == 0)
nreport(from, N_DOWN_PLANE, pp->pln_own, 1);
- if (pp->pln_ship >= 0) {
- getship(pp->pln_ship, &ship);
- take_plane_off_ship(pp, &ship);
- }
- if (pp->pln_land >= 0) {
- getland(pp->pln_land, &land);
- take_plane_off_land(pp, &land);
- }
- pp->pln_effic = 0;
- putplane(pp->pln_uid, pp);
- emp_remque(&plp->queue);
- free(plp);
- } else if (disp == 2) {
- putplane(pp->pln_uid, pp);
- emp_remque(&plp->queue);
- free(plp);
+ pln_put1(plp);
} else
putplane(pp->pln_uid, pp);
strcpy(mesg, dmess);
struct lndstr land;
struct lchrstr *lcp;
double flak, total, ngun;
- int gun;
+ int aaf, gun;
int rel;
struct plist *plp;
natid plane_owner;
if (land.lnd_own == 0 || land.lnd_own == plane_owner)
continue;
lcp = &lchr[(int)land.lnd_type];
- if ((lcp->l_flags & L_FLAK) == 0 || land.lnd_aaf == 0)
+ aaf = lnd_aaf(&land);
+ if ((lcp->l_flags & L_FLAK) == 0 || aaf == 0)
continue;
if (land.lnd_ship >= 0 || land.lnd_land >= 0)
continue;
rel = getrel(getnatp(land.lnd_own), plane_owner);
if (rel > HOSTILE)
continue;
- flak = land.lnd_aaf * 1.5 * land.lnd_effic / 100.0;
+ flak = aaf * 1.5 * land.lnd_effic / 100.0;
ngun += flak;
total += techfact(land.lnd_tech, flak * 2.0);
nats[land.lnd_own] = 1;
}
PR(land.lnd_own, "firing flak guns from unit %s (aa rating %d)\n",
- prland(&land), land.lnd_aaf);
+ prland(&land), aaf);
from = land.lnd_own;
}
for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
plp = (struct plist *)qp;
- n = ac_flak_dam(guns, plp->plane.pln_def, plp->pcp->pl_flags);
+ n = ac_flak_dam(guns, pln_def(&plp->plane), plp->pcp->pl_flags);
ac_planedamage(plp, from, n, 0, 2, 1, msg);
}
}
return dam;
}
-/*
- * See if this plane is flying in this list
- */
-int
-ac_isflying(struct plnstr *plane, struct emp_qelem *list)
-{
- struct emp_qelem *qp;
- struct emp_qelem *next;
- struct plnstr *pp;
- struct plist *plp;
-
- if (!list)
- return 0;
- for (qp = list->q_forw; qp != list; qp = next) {
- next = qp->q_forw;
- plp = (struct plist *)qp;
- pp = &plp->plane;
- if (plane->pln_uid == pp->pln_uid)
- return 1;
- }
- return 0;
-}
-
-
/*
* Get a list of planes available for interception duties.
*/
static void
-getilist(struct emp_qelem *list, natid own, struct emp_qelem *a,
- struct emp_qelem *b, struct emp_qelem *c, struct emp_qelem *d)
+getilist(struct emp_qelem *list, natid own)
{
struct plchrstr *pcp;
struct plnstr plane;
pcp = &plchr[(int)plane.pln_type];
if ((pcp->pl_flags & P_F) == 0)
continue;
+ if (plane.pln_flags & PLN_LAUNCHED)
+ continue;
if (plane.pln_mission != 0)
continue;
if (plane.pln_mobil <= 0)
continue;
if (!pln_airbase_ok(&plane, 0, 0))
continue;
- /* Finally, is it in the list of planes already in
- flight? */
- if (ac_isflying(&plane, a))
- continue;
- if (ac_isflying(&plane, b))
- continue;
- if (ac_isflying(&plane, c))
- continue;
- if (ac_isflying(&plane, d))
- continue;
/* got one! */
ip = malloc(sizeof(*ip));
ip->bombs = 0;