]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/mission.c
Update copyright notice
[empserver] / src / lib / subs / mission.c
index f1aefe2c30bb8dc8c36e9a3124fac59f1fea4e66..517826ff35ee8a0b42bd2f5748219238442721ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2009, 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
@@ -80,8 +80,14 @@ static int perform_mission_msl(int, struct emp_qelem *, coord, coord,
                               natid, int);
 static int perform_mission_bomb(int, struct emp_qelem *, coord, coord,
                                natid, int, char *, int, int);
-static int perform_mission(coord, coord, natid, struct emp_qelem *, int,
-                          char *, int);
+static int perform_mission(coord, coord, natid, struct emp_qelem *,
+                          int, char *, int);
+
+static int
+tally_dam(int dam, int newdam)
+{
+    return dam < 0 ? newdam : dam + newdam;
+}
 
 /*
  * Interdict commodities & transported planes
@@ -92,11 +98,10 @@ ground_interdict(coord x, coord y, natid victim, char *s)
     int cn;
     int dam = 0, newdam, rel;
     struct genlist mi[MAXNOC];
-    int z;
 
     memset(mi, 0, sizeof(mi));
-    for (z = 1; z < MAXNOC; z++)
-       emp_initque((struct emp_qelem *)&mi[z]);
+    for (cn = 1; cn < MAXNOC; cn++)
+       emp_initque((struct emp_qelem *)&mi[cn]);
 
     build_mission_list(mi, x, y, MI_INTERDICT, victim);
 
@@ -110,10 +115,11 @@ ground_interdict(coord x, coord y, natid victim, char *s)
 
        newdam = perform_mission(x, y, victim, &mi[cn].queue,
                                 MI_INTERDICT, s, SECT_HARDTARGET);
-       dam += newdam;
-       if (newdam)
+       if (newdam > 0) {
+           dam += newdam;
            mpr(victim, "%s interdiction mission does %d damage!\n",
                cname(cn), newdam);
+       }
     }
     if (dam) {
        collateral_damage(x, y, dam);
@@ -171,15 +177,13 @@ int
 unit_interdict(coord x, coord y, natid victim, char *s, int hardtarget,
               int mission)
 {
-    int cn;
-    int dam = 0, newdam;
+    int cn, newdam, osubs;
+    int dam = -1;
     struct genlist mi[MAXNOC];
-    int z;
-    int osubs;
 
     memset(mi, 0, sizeof(mi));
-    for (z = 1; z < MAXNOC; z++)
-       emp_initque((struct emp_qelem *)&mi[z]);
+    for (cn = 1; cn < MAXNOC; cn++)
+       emp_initque((struct emp_qelem *)&mi[cn]);
 
     build_mission_list(mi, x, y, mission, victim);
 
@@ -198,17 +202,13 @@ unit_interdict(coord x, coord y, natid victim, char *s, int hardtarget,
        osubs = only_subs(&mi[cn].queue);
        newdam = perform_mission(x, y, victim, &mi[cn].queue,
                                 mission, s, hardtarget);
-       dam += newdam;
-       if (newdam) {
-           /* If only subs responded, then we don't know who's
-              subs they are */
+       dam = tally_dam(dam, newdam);
+       if (newdam > 0)
            mpr(victim, "%s interdiction mission does %d damage!\n",
                osubs ? "Enemy" : cname(cn), newdam);
-       }
     }
-    if (dam) {
+    if (dam > 0)
        collateral_damage(x, y, dam);
-    }
     return dam;
 }
 
@@ -220,11 +220,11 @@ off_support(coord x, coord y, natid victim, natid actee)
 {
     int dam = 0;
     struct genlist mi[MAXNOC];
-    int z;
+    int cn;
 
     memset(mi, 0, sizeof(mi));
-    for (z = 1; z < MAXNOC; z++)
-       emp_initque((struct emp_qelem *)&mi[z]);
+    for (cn = 1; cn < MAXNOC; cn++)
+       emp_initque((struct emp_qelem *)&mi[cn]);
 
     build_mission_list(mi, x, y, MI_SUPPORT, victim);
     build_mission_list(mi, x, y, MI_OSUPPORT, victim);
@@ -241,11 +241,11 @@ def_support(coord x, coord y, natid victim, natid actee)
 {
     int dam = 0;
     struct genlist mi[MAXNOC];
-    int z;
+    int cn;
 
     memset(mi, 0, sizeof(mi));
-    for (z = 1; z < MAXNOC; z++)
-       emp_initque((struct emp_qelem *)&mi[z]);
+    for (cn = 1; cn < MAXNOC; cn++)
+       emp_initque((struct emp_qelem *)&mi[cn]);
 
     build_mission_list(mi, x, y, MI_SUPPORT, victim);
     build_mission_list(mi, x, y, MI_DSUPPORT, victim);
@@ -258,7 +258,7 @@ static int
 dosupport(struct genlist *mi, coord x, coord y, natid victim, natid actee)
 {
     int cn;
-    int rel;
+    int rel, newdam;
     int dam = 0;
 
     for (cn = 1; cn < MAXNOC; cn++) {
@@ -272,8 +272,10 @@ dosupport(struct genlist *mi, coord x, coord y, natid victim, natid actee)
        if (QEMPTY(&mi[cn].queue))
            continue;
 
-       dam += perform_mission(x, y, victim, &mi[cn].queue, MI_SUPPORT,
-                              "", SECT_HARDTARGET);
+       newdam = perform_mission(x, y, victim, &mi[cn].queue, MI_SUPPORT,
+                                "", SECT_HARDTARGET);
+       if (newdam > 0)
+           dam += newdam;
     }
     return dam;
 }
@@ -384,18 +386,16 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list,
     struct emp_qelem *qp, missiles, bombers;
     struct genlist *glp;
     struct plist *plp;
-    struct sctstr sect;
     struct plchrstr *pcp;
-    int dam = 0;
+    int dam = -1;
     int targeting_ships = *s == 's'; /* "subs" or "ships" FIXME gross! */
 
-    getsect(x, y, &sect);
-
     emp_initque(&missiles);
     emp_initque(&bombers);
 
-    for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
+    for (qp = list->q_forw; qp != list; ) {
        glp = (struct genlist *)qp;
+       qp = qp->q_forw;
 
        if (glp->thing->ef_type == EF_LAND) {
            dam = perform_mission_land(dam, (struct lndstr *)glp->thing,
@@ -426,21 +426,13 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list,
            CANT_REACH();
            break;
        }
+       free(glp->thing);
+       free(glp);
     }
 
     dam = perform_mission_msl(dam, &missiles, x, y, victim, hardtarget);
     dam = perform_mission_bomb(dam, &bombers, x, y, victim, mission, s,
                               hardtarget, targeting_ships);
-
-    qp = list->q_forw;
-    while (qp != list) {
-       glp = (struct genlist *)qp;
-       qp = qp->q_forw;
-
-       free(glp->thing);
-       free(glp);
-    }
-
     return dam;
 }
 
@@ -483,7 +475,7 @@ perform_mission_land(int dam, struct lndstr *lp, coord x, coord y,
     mpr(victim, "%s %s fires at you at %s\n",
        cname(lp->lnd_own), prland(lp), xyas(x, y, victim));
 
-    return dam + dam2;
+    return tally_dam(dam, dam2);
 }
 
 static int
@@ -542,7 +534,7 @@ perform_mission_ship(int dam, struct shpstr *sp, coord x, coord y,
            mpr(victim,
                "Incoming torpedo sighted @ %s missed (whew)!\n",
                xyas(x, y, victim));
-           return dam;
+           return tally_dam(dam, 0);
        }
        wu(0, sp->shp_own, "\tBOOM!...\n");
        nreport(victim, N_TORP_SHIP, 0, 1);
@@ -576,24 +568,23 @@ perform_mission_ship(int dam, struct shpstr *sp, coord x, coord y,
            cname(sp->shp_own), prship(sp), xyas(x, y, victim));
     }
 
-    return dam + dam2;
+    return tally_dam(dam, dam2);
 }
 
 static int
 perform_mission_msl(int dam, struct emp_qelem *missiles, coord x, coord y,
                    natid victim, int hardtarget)
 {
-    int air_dam;
+    int performed, air_dam, sublaunch, dam2;
     struct emp_qelem *qp, *newqp;
     struct plist *plp;
-    int sublaunch, dam2;
 
     /*
      * Missiles, except for interdiction of ships or land units,
      * because that happens elsewhere, in shp_missile_interdiction()
      * and lnd_missile_interdiction().
      */
-    air_dam = 0;
+    performed = air_dam = 0;
     for (qp = missiles->q_back; qp != missiles; qp = newqp) {
        newqp = qp->q_back;
        plp = (struct plist *)qp;
@@ -605,6 +596,7 @@ perform_mission_msl(int dam, struct emp_qelem *missiles, coord x, coord y,
            if (msl_launch(&plp->plane, EF_SECTOR, "sector", x, y, victim,
                           &sublaunch) < 0)
                goto use_up_msl;
+           performed = 1;
            if (!msl_hit(&plp->plane, SECT_HARDTARGET, EF_SECTOR,
                         N_SCT_MISS, N_SCT_SMISS, sublaunch, victim))
                CANT_REACH();
@@ -617,7 +609,8 @@ perform_mission_msl(int dam, struct emp_qelem *missiles, coord x, coord y,
        emp_remque(qp);
        free(qp);
     }
-    return dam + air_dam;
+
+    return performed ? tally_dam(dam, air_dam) : dam;
 }
 
 static int
@@ -627,7 +620,7 @@ perform_mission_bomb(int dam, struct emp_qelem *bombers, coord x, coord y,
 {
     struct emp_qelem *qp, *newqp, escorts, airp, b, e;
     struct plist *plp;
-    int plane_owner, air_dam, md;
+    int plane_owner, performed, air_dam, md;
 
     emp_initque(&escorts);
     emp_initque(&airp);
@@ -659,7 +652,7 @@ perform_mission_bomb(int dam, struct emp_qelem *bombers, coord x, coord y,
            add_airport(&airp, plp->plane.pln_x, plp->plane.pln_y);
     }
 
-    air_dam = 0;
+    performed = air_dam = 0;
     for (qp = airp.q_forw; qp != (&airp); qp = qp->q_forw) {
        struct airport *air;
        char buf[512];
@@ -687,6 +680,7 @@ perform_mission_bomb(int dam, struct emp_qelem *bombers, coord x, coord y,
        pp = BestAirPath(buf, air->x, air->y, x, y);
        if (CANT_HAPPEN(!pp))
            continue;
+       performed = 1;
        wu(0, plane_owner, "Flying %s mission from %s to %s\n",
           mission_name(mission),
           xyas(air->x, air->y, plane_owner),
@@ -731,7 +725,7 @@ perform_mission_bomb(int dam, struct emp_qelem *bombers, coord x, coord y,
        qp = newqp;
     }
 
-    return dam + air_dam;
+    return performed ? tally_dam(dam, air_dam) : dam;
 }
 
 int