-
-/*
- * Check to see if anyone hostile to the victim
- * is running an air defense mission on this
- * sector. If so, do air combat
- */
-int
-air_defense(coord x, coord y, natid victim, struct emp_qelem *bomb_list,
- struct emp_qelem *esc_list)
-{
- int dam = 0, cn;
- int combat = 0, rel, dist, z;
- struct emp_qelem *qp, interceptors, airp, i, empty, *next;
- struct plist *plp;
- struct genlist *glp;
- struct empobj *gp;
- struct genlist mi[MAXNOC];
- char buf[512];
- char *path;
- int count;
- int tcount;
-
- count = 0;
- for (qp = bomb_list->q_forw; qp != bomb_list; qp = qp->q_forw)
- count++;
- for (qp = esc_list->q_forw; qp != esc_list; qp = qp->q_forw)
- count++;
-
- memset(mi, 0, sizeof(mi));
- for (z = 1; z < MAXNOC; z++)
- emp_initque((struct emp_qelem *)&mi[z]);
-
- build_mission_list_type(mi, x, y, MI_AIR_DEFENSE, EF_PLANE, victim);
-
- for (cn = 1; cn < MAXNOC; cn++) {
- /* Check our relations */
- rel = getrel(getnatp(cn), victim);
-
- if (rel > HOSTILE)
- continue;
-
- if (QEMPTY(&mi[cn].queue))
- continue;
-
- /* Ok, make a list of all the interceptors. Note that this *copies* the
- * list from the mission creation. This list must be deleted later. */
- emp_initque(&interceptors);
- for (qp = mi[cn].queue.q_forw; qp != (&mi[cn].queue); qp = next) {
- next = qp->q_forw;
- glp = (struct genlist *)qp;
- gp = glp->thing;
- if (CANT_HAPPEN(gp->ef_type != EF_PLANE))
- break;
-
- dist = mapdist(x, y, gp->x, gp->y);
-
- plp = malloc(sizeof(struct plist));
- memset(plp, 0, sizeof(struct plist));
- plp->pcp = glp->cp;
- memcpy(&plp->plane, glp->thing, sizeof(struct plnstr));
-
- /* missiles go one way, so we can use all the range */
- if (!(plp->pcp->pl_flags & P_M))
- dist *= 2;
- /* If it's out of range, free it and continue on */
- if (dist > plp->plane.pln_range) {
- free(plp);
- continue;
- }
- emp_insque(&plp->queue, &interceptors);
- }
-
- /* Remove those who cannot go */
- mission_pln_sel(&interceptors, P_F, 0, SECT_HARDTARGET);
-
- if (QEMPTY(&interceptors))
- continue;
-
- /* Now, delete all the extras, but delete the first ones, not the last ones, so
- * that the higher numbered planes go into battle (they should be the better ones
- * at fighting, if all went well.) */
- tcount = 0;
- for (qp = interceptors.q_forw; qp != (&interceptors);
- qp = qp->q_forw)
- tcount++;
- tcount -= count * 2;
- /* Just in case there are more incoming than we have */
- if (tcount < 0)
- tcount = 0;
- for (qp = interceptors.q_forw; qp != (&interceptors); qp = next) {
- next = qp->q_forw;
- if (tcount) {
- tcount--;
- /* Free it up and continue */
- emp_remque(qp);
- glp = (struct genlist *)qp;
- free(glp);
- }
- }
-
- /* Now, make a list of all the airports these planes are coming from */
- emp_initque(&airp);
- for (qp = interceptors.q_forw; qp != (&interceptors);
- qp = qp->q_forw) {
- plp = (struct plist *)qp;
- if (!find_airport(&airp, plp->plane.pln_x, plp->plane.pln_y))
- add_airport(&airp, plp->plane.pln_x, plp->plane.pln_y);
- }
-
- /* Now, fly them out one airport at a time */
- for (qp = airp.q_forw; qp != (&airp); qp = qp->q_forw) {
- struct airport *air;
-
- air = (struct airport *)qp;
- dist = mapdist(x, y, air->x, air->y);
-
- emp_initque(&i);
-
- /* Split off the interceptors at this base into i */
- divide(&interceptors, &i, air->x, air->y);
-
- sam_intercept(bomb_list, &i, cn, victim, x, y, 0);
- sam_intercept(esc_list, &i, cn, victim, x, y, 1);
-
- /* Did we run out of interceptors? */
- if (QEMPTY(&i))
- continue;
- /* Did we run out of bombers? */
- if (QEMPTY(bomb_list)) {
- /* Yes, so we have to put the rest of the interceptors back, and
- then continue, or we leak memory */
- pln_put(&i);
- continue;
- }
- mission_pln_arm(&i, air->x, air->y, 2 * dist, 0, 0, P_F);
-
- /* Did we run out of interceptors? */
- if (QEMPTY(&i))
- continue;
- /* Did we run out of bombers? */
- if (QEMPTY(bomb_list)) {
- /* Yes, so we have to put the rest of the interceptors back, and
- then continue, or we leak memory */
- pln_put(&i);
- continue;
- }
-
- path = BestAirPath(buf, air->x, air->y, x, y);
- if (CANT_HAPPEN(!path)) {
- pln_put(&i);
- continue;
- }
- wu(0, cn, "Flying %s mission from %s to %s\n",
- mission_name(MI_AIR_DEFENSE),
- xyas(air->x, air->y, cn),
- xyas(x, y, cn));
- if (air->own && (air->own != cn)) {
- wu(0, air->own, "%s is flying %s mission from %s to %s\n",
- cname(cn), mission_name(MI_AIR_DEFENSE),
- xyas(air->x, air->y, air->own),
- xyas(x, y, air->own));
- }
-
- /* Now, fly the planes to the sector */
- emp_initque(&empty);
- ac_encounter(&i, &empty, air->x, air->y, path, 0, 1);
-
- /* If none made it, continue */
- if (QEMPTY(&i))
- continue;
-
- /* Some made it, so now they get to try to fight. */
- /* Intercept the escorts first */
- combat = 0;
- if (!QEMPTY(esc_list)) {
- mpr(victim, "%s air defense planes intercept!\n",
- cname(cn));
- ac_combat_headers(victim, cn);
- ac_airtoair(esc_list, &i);
- combat = 1;
- }
- /* Now intercept the bombers */
- if (!QEMPTY(bomb_list)) {
- if (!combat) {
- mpr(victim, "%s air defense planes intercept!\n",
- cname(cn));
- ac_combat_headers(victim, cn);
- }
- ac_airtoair(bomb_list, &i);
- PR(cn, "\n");
- PR(victim, "\n");
- }
-
- pln_put(&i);
- }
- if (CANT_HAPPEN(!QEMPTY(&interceptors)))
- pln_put(&interceptors);
- }
-
- /* We have to free all of these, if they are still there, otherwise they get
- lost and we leak memory all over the place. */
- for (cn = 1; cn < MAXNOC; cn++) {
- /* free up all this memory if it's still there */
- for (qp = mi[cn].queue.q_forw; qp != (&mi[cn].queue); qp = next) {
- next = qp->q_forw;
- glp = (struct genlist *)qp;
- free(glp->thing);
- free(glp);
- }
- }
-
- return dam;
-}