]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/aircombat.c
Intercept the same all along the flight path
[empserver] / src / lib / subs / aircombat.c
index 6832712798f7f3407a2e24185348373df5050bd9..8413a102a144f2b8381fe66630854b989ab50432 100644 (file)
@@ -73,17 +73,14 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
             int no_air_defense)
 {
     int val;
-    int rel;
     int dir;
-    int nats[MAXNOC];
-    int lnats[MAXNOC];
+    unsigned char gotships[MAXNOC];
+    unsigned char gotlands[MAXNOC];
     int gotilist[MAXNOC];
-    int unfriendly[MAXNOC];
+    unsigned char rel[MAXNOC];
     int overfly[MAXNOC];
     int flags;
     struct emp_qelem ilist[MAXNOC];
-    char mypath[1024];
-    int myp;
     int civ, mil;
     natid plane_owner;
     struct sctstr sect;
@@ -91,7 +88,6 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
     struct lndstr land;
     struct nstr_item ni;
     natid cn;
-    struct natstr *over, *mynatp;
     struct plist *plp;
     int evaded;
     struct shiplist *head = NULL;
@@ -103,22 +99,11 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
     plp = (struct plist *)bomb_list->q_forw;
     plane_owner = plp->plane.pln_own;
 
-    strncpy(mypath, path, sizeof(mypath));
-    myp = 0;
-
     memset(overfly, 0, sizeof(overfly));
     memset(gotilist, 0, sizeof(gotilist));
-    memset(unfriendly, 0, sizeof(unfriendly));
-    for (cn = 1; cn < MAXNOC; cn++) {
-       if ((mynatp = getnatp(cn)) == 0)
-           continue;
-       rel = getrel(mynatp, plane_owner);
-       if (rel > HOSTILE)
-           continue;
-       if (plane_owner == cn)
-           continue;
-       unfriendly[cn]++;
-    }
+    for (cn = 0; cn < MAXNOC; cn++)
+       rel[cn] = getrel(getnatp(cn), plane_owner);
+
     if (mission_flags & PM_R) {
        flags = plane_caps(bomb_list);
        if (flags & P_S) {
@@ -133,14 +118,22 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
        }
     }
 
-    while ((dir = mypath[myp++]) && !QEMPTY(bomb_list)) {
-       if ((val = diridx(dir)) == DIR_STOP)
-           break;
-       /* XXX using xnorm is probably bad */
-       x = xnorm(x + diroff[val][0]);
-       y = ynorm(y + diroff[val][1]);
+    for (;;) {
        getsect(x, y, &sect);
-       over = getnatp(sect.sct_own);
+       memset(gotships, 0, sizeof(gotships));
+       snxtitem_xy(&ni, EF_SHIP, x, y);
+       while (nxtitem(&ni, &ship)) {
+           if (mchr[(int)ship.shp_type].m_flags & M_SUB)
+               continue;
+           gotships[ship.shp_own] = 1;
+       }
+       memset(gotlands, 0, sizeof(gotlands));
+       snxtitem_xy(&ni, EF_LAND, x, y);
+       while (nxtitem(&ni, &land)) {
+           if (land.lnd_ship >= 0 || land.lnd_land >= 0)
+               continue;
+           gotlands[land.lnd_own] = 1;
+       }
 
        if (mission_flags & PM_R) {
            flags = plane_caps(bomb_list);
@@ -190,116 +183,85 @@ ac_encounter(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
            }
            if (flags & P_S)
                satdisp_units(sect.sct_x, sect.sct_y);
+           else {
+               for (cn = 1; cn < MAXNOC; cn++) {
+                   if (cn == plane_owner)
+                       continue;
+                   if (gotships[cn])
+                       PR(plane_owner, "Flying over %s ships in %s\n",
+                          cname(cn), xyas(x, y, plane_owner));
+                   if (gotlands[cn])
+                       PR(plane_owner, "Flying over %s land units in %s\n",
+                          cname(cn), xyas(x, y, plane_owner));
+               }
+           }
        } else {
            PR(plane_owner, "flying over %s at %s\n",
               dchr[sect.sct_type].d_name, xyas(x, y, plane_owner));
            changed += map_set(plane_owner, sect.sct_x, sect.sct_y,
                               dchr[sect.sct_type].d_mnem, 0);
        }
-       if ((rel = getrel(over, plane_owner)) == ALLIED)
-           continue;
 
        evaded = do_evade(bomb_list, esc_list);
-       if (evaded)
-           continue;
-
-       if (sect.sct_own != 0 && sect.sct_own != plane_owner) {
+       if (!evaded) {
            overfly[sect.sct_own]++;
-           PR(sect.sct_own, "%s planes spotted over %s\n",
-              cname(plane_owner), xyas(x, y, sect.sct_own));
-           if (opt_HIDDEN)
-               setcont(sect.sct_own, plane_owner, FOUND_FLY);
+           for (cn = 1; cn < MAXNOC; cn++) {
+               if (cn == plane_owner || rel[cn] == ALLIED)
+                   continue;
+               if (cn != sect.sct_own && !gotships[cn] && !gotlands[cn])
+                   continue;
+               PR(cn, "%s planes spotted over %s\n",
+                  cname(plane_owner), xyas(x, y, cn));
+               if (opt_HIDDEN)
+                   setcont(cn, plane_owner, FOUND_FLY);
+           }
+
+           /* Fire flak */
+           if (rel[sect.sct_own] <= HOSTILE)
+               ac_doflak(bomb_list, &sect);
+           /* If bombers left, fire flak from units and ships */
+           if (!QEMPTY(bomb_list))
+               ac_landflak(bomb_list, x, y);
+           if (!QEMPTY(bomb_list))
+               ac_shipflak(bomb_list, x, y);
+           /* mission planes aborted due to flak -- don't send escorts */
+           if (QEMPTY(bomb_list))
+               break;
+
+           if (!no_air_defense)
+               air_defense(x, y, plane_owner, bomb_list, esc_list);
+
+           for (cn = 1; cn < MAXNOC && !QEMPTY(bomb_list); cn++) {
+               if (rel[cn] > HOSTILE)
+                   continue;
+               if (cn != sect.sct_own && !gotships[cn] && !gotlands[cn])
+                   continue;
+               if (!gotilist[cn]) {
+                   getilist(&ilist[cn], cn);
+                   gotilist[cn]++;
+               }
+               ac_intercept(bomb_list, esc_list, &ilist[cn], cn, x, y);
+           }
        }
 
-       /* Fire flak */
-       if (unfriendly[sect.sct_own])
-           ac_doflak(bomb_list, &sect);
-       /* If bombers left, fire flak from units and ships */
-       if (!QEMPTY(bomb_list))
-           ac_landflak(bomb_list, x, y);
-       if (!QEMPTY(bomb_list))
-           ac_shipflak(bomb_list, x, y);
-       /* mission planes aborted due to flak -- don't send escorts */
-       if (QEMPTY(bomb_list))
+       dir = *path++;
+       if (!dir || QEMPTY(bomb_list) || (val = diridx(dir)) == DIR_STOP)
            break;
-
-       if (!no_air_defense)
-           air_defense(x, y, plane_owner, bomb_list, esc_list);
-
-       if (sect.sct_own == 0 || sect.sct_own == plane_owner)
-           continue;
-
-       if (unfriendly[sect.sct_own] && !gotilist[sect.sct_own]) {
-           getilist(&ilist[sect.sct_own], sect.sct_own);
-           gotilist[sect.sct_own]++;
-       }
-       if (rel > HOSTILE)
-           continue;
-       ac_intercept(bomb_list, esc_list, &ilist[sect.sct_own],
-                    sect.sct_own, x, y);
+       x = xnorm(x + diroff[val][0]);
+       y = ynorm(y + diroff[val][1]);
     }
 
     /* Let's report all of the overflights even if aborted */
     for (cn = 1; cn < MAXNOC; cn++) {
        if (plane_owner == cn)
            continue;
-       if (overfly[cn] > 0)
+       if (overfly[cn] > 0 && rel[cn] != ALLIED)
            nreport(plane_owner, N_OVFLY_SECT, cn, overfly[cn]);
     }
     /* If the map changed, update it */
     if (changed)
        writemap(player->cnum);
-    /* Now, if the bomber and escort lists are empty, we are done */
-    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 */
-    memset(nats, 0, sizeof(nats));
-    snxtitem_xy(&ni, EF_SHIP, x, y);
-    while (nxtitem(&ni, &ship)) {
-       if (mchr[(int)ship.shp_type].m_flags & M_SUB)
-           continue;
-       nats[ship.shp_own]++;
-    }
-    /* Go figure out if there are units in this sector, and who's they are */
-    memset(lnats, 0, sizeof(lnats));
-    snxtitem_xy(&ni, EF_LAND, x, y);
-    while (nxtitem(&ni, &land)) {
-       if (land.lnd_ship >= 0 || land.lnd_land >= 0)
-           continue;
-       lnats[land.lnd_own]++;
-    }
-
-    /* Now, let's make life a little rougher. */
-    for (cn = 1; cn < MAXNOC && !QEMPTY(bomb_list); cn++) {
-       if (plane_owner == cn)
-           continue;
-       if (nats[cn] != 0) {
-           PR(plane_owner, "Flying over %s ships in %s\n",
-              cname(cn), xyas(x, y, plane_owner));
-           PR(cn, "%s planes spotted over ships in %s\n",
-              cname(plane_owner), xyas(x, y, cn));
-       }
-       if (lnats[cn] != 0) {
-           PR(plane_owner, "Flying over %s land units in %s\n",
-              cname(cn), xyas(x, y, plane_owner));
-           PR(cn, "%s planes spotted over land units in %s\n",
-              cname(plane_owner), xyas(x, y, cn));
-       }
-       if (nats[cn] || lnats[cn]) {
-           if (opt_HIDDEN)
-               setcont(cn, plane_owner, FOUND_FLY);
-           if (unfriendly[cn] && !evaded) {
-               if (!gotilist[cn]) {
-                   getilist(&ilist[cn], cn);
-                   gotilist[cn]++;
-               }
-               ac_intercept(bomb_list, esc_list, &ilist[cn], cn, x, y);
-           }
-       }
-    }
-out:
     free_shiplist(&head);
     for (cn = 1; cn < MAXNOC; cn++) {
        if (gotilist[cn])
@@ -350,11 +312,8 @@ sam_intercept(struct emp_qelem *att_list, struct emp_qelem *def_list,
                continue;
 
            if (dplp->plane.pln_range <
-               mapdist(x, y, dplp->plane.pln_x, dplp->plane.pln_y)) {
-               emp_remque(dqp);
-               free(dqp);
+               mapdist(x, y, dplp->plane.pln_x, dplp->plane.pln_y))
                continue;
-           }
            if (CANT_HAPPEN(dplp->plane.pln_flags & PLN_LAUNCHED)
                || mission_pln_equip(dplp, 0, P_F, 0) < 0) {
                emp_remque(dqp);
@@ -410,7 +369,7 @@ ac_intercept(struct emp_qelem *bomb_list, struct emp_qelem *esc_list,
     plane_owner = plp->plane.pln_own;
 
     sam_intercept(bomb_list, def_list, def_own, plane_owner, x, y, 0);
-    sam_intercept(esc_list, def_list, def_own, plane_owner, x, y, 1);
+    sam_intercept(esc_list, def_list, def_own, plane_owner, x, y, 0);
 
     att_count = 0;
     for (qp = bomb_list->q_forw; qp != bomb_list; qp = qp->q_forw)
@@ -726,12 +685,10 @@ ac_shipflak(struct emp_qelem *list, coord x, coord y)
     struct plist *plp;
     natid plane_owner;
     natid from;
-    int nats[MAXNOC];
 
     plp = (struct plist *)list->q_forw;
     plane_owner = plp->plane.pln_own;
 
-    memset(nats, 0, sizeof(nats));
     total = ngun = 0;
     snxtitem_xy(&ni, EF_SHIP, x, y);
     while (!QEMPTY(list) && nxtitem(&ni, &ship)) {
@@ -760,14 +717,6 @@ ac_shipflak(struct emp_qelem *list, coord x, coord y)
        ngun += flak;
        total += techfact(ship.shp_tech, flak * 2.0);
 
-       if (!nats[ship.shp_own]) {
-           /* First time here, print the message */
-           PR(ship.shp_own, "%s planes spotted over ships in %s\n",
-              cname(plane_owner), xyas(x, y, ship.shp_own));
-           PR(plane_owner, "Flying over %s ships in %s\n",
-              cname(ship.shp_own), xyas(x, y, plane_owner));
-           nats[ship.shp_own] = 1;
-       }
        PR(ship.shp_own, "firing %.0f flak guns from %s...\n",
           flak, prship(&ship));
        from = ship.shp_own;
@@ -796,12 +745,10 @@ ac_landflak(struct emp_qelem *list, coord x, coord y)
     struct plist *plp;
     natid plane_owner;
     natid from;
-    int nats[MAXNOC];
 
     plp = (struct plist *)list->q_forw;
     plane_owner = plp->plane.pln_own;
 
-    memset(nats, 0, sizeof(nats));
     total = ngun = 0;
     snxtitem_xy(&ni, EF_LAND, x, y);
     while (!QEMPTY(list) && nxtitem(&ni, &land)) {
@@ -820,14 +767,6 @@ ac_landflak(struct emp_qelem *list, coord x, coord y)
        ngun += flak;
        total += techfact(land.lnd_tech, flak * 2.0);
 
-       if (!nats[land.lnd_own]) {
-           /* First time here, print the message */
-           PR(land.lnd_own, "%s planes spotted over land units in %s\n",
-              cname(plane_owner), xyas(x, y, land.lnd_own));
-           PR(plane_owner, "Flying over %s land units in %s\n",
-              cname(land.lnd_own), xyas(x, y, plane_owner));
-           nats[land.lnd_own] = 1;
-       }
        PR(land.lnd_own, "firing flak guns from unit %s (aa rating %d)\n",
           prland(&land), aaf);
        from = land.lnd_own;