]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/attsub.c
Fix automatic supply of defending and reacting units
[empserver] / src / lib / subs / attsub.c
index 2d56188a297a950b6107fd092163887e566cdbf8..7f47f1323057d6073e0e1e00d7fc6b30027250fb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
  *                           Ken Stevens, Steve McClure
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,7 @@
  *  ---
  *
  *  attsub.c: Attack subroutines
- * 
+ *
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1996-2000
@@ -155,7 +155,7 @@ prcom(int inon, struct combat *com)
 
 /*
  * This is the combat object "type" based integrity check.  It basically
- * splits along three divisions: ship/sector, attacker/defender, 
+ * splits along three divisions: ship/sector, attacker/defender,
  * first time/not first time.
  */
 
@@ -386,7 +386,6 @@ put_combat(struct combat *com)
        }
        if (!(com->lnd_lcp->l_flags & L_SPY))
            land.lnd_item[I_MILIT] = com->mil;
-       lnd_count_units(&land);
        if (com->own == player->cnum) {
            land.lnd_mission = 0;
            land.lnd_rflags = 0;
@@ -409,7 +408,6 @@ put_combat(struct combat *com)
                ship.shp_pstage = PLG_EXPOSED;
        }
        ship.shp_item[I_MILIT] = com->mil;
-       count_units(&ship);
        if (com->own == player->cnum) {
            ship.shp_mission = 0;
            ship.shp_rflags = 0;
@@ -451,6 +449,7 @@ att_abort(int combat_mode, struct combat *off, struct combat *def)
        if (att_get_combat(off, 0) < 0)
            return abort_attack();
        if (off->type == EF_SHIP &&
+           !(off->x == def->x && off->y == def->y) &&
            (!getsect(off->x, off->y, &sect) ||
             sect.sct_type != SCT_WATER)) {
            pr("%s can not %s from that far inland!\n",
@@ -967,7 +966,8 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def,
 {
     struct nstr_item ni;
     struct lndstr land;
-    double mobcost;
+    double pathcost, mobcost;
+    int reqmob;
     struct ulist *llp;
     struct lchrstr *lcp;
     double att_val;
@@ -1041,17 +1041,18 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def,
             * of high-mobility sectors (mountains): for those we
             * still require attack mobility.
             */
-           mobcost = att_mobcost(off->own, def, lnd_mobtype(&land));
-           if (mobcost < 1.0) {
+           pathcost = att_mobcost(off->own, def, lnd_mobtype(&land));
+           mobcost = lnd_pathcost(&land, pathcost);
+           if (pathcost < 1.0) {
                if (land.lnd_mobil <= 0) {
                    pr("%s is out of mobility\n", prland(&land));
                    continue;
                }
            } else {
-               mobcost = lnd_pathcost(&land, mobcost);
-               if (land.lnd_mobil < mobcost) {
+               reqmob = MIN(land_mob_max, (int)ceil(mobcost));
+               if (land.lnd_mobil < reqmob) {
                    pr("%s does not have enough mobility (%d needed)\n",
-                      prland(&land), (int)ceil(mobcost));
+                      prland(&land), reqmob);
                    continue;
                }
            }
@@ -1073,7 +1074,7 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def,
        }
        resupply_all(&land);
        putland(land.lnd_uid, &land);
-       if (!has_supply(&land)) {
+       if (!lnd_in_supply(&land)) {
            pr("%s is out of supply, and cannot %s\n",
               prland(&land), att_mode[combat_mode]);
            continue;
@@ -1234,7 +1235,9 @@ get_dlist(struct combat *def, struct emp_qelem *list, int a_spy,
        }
        memset(llp, 0, sizeof(struct ulist));
        emp_insque(&llp->queue, list);
-       llp->supplied = has_supply(&land);
+       resupply_all(&land);
+       putland(land.lnd_uid, &land);
+       llp->supplied = lnd_in_supply(&land);
        if (!get_land(A_DEFEND, def, land.lnd_uid, llp, 1))
            continue;
        if (lnd_spyval(&land) > *d_spyp)
@@ -1470,8 +1473,6 @@ att_reacting_units(struct combat *def, struct emp_qelem *list, int a_spy,
     double new_land = 0;
     double mobcost;
     double pathcost;
-    int dist;
-    int radius;
     int origx, origy;
     double eff = att_combat_eff(def);
     char buf[1024];
@@ -1484,7 +1485,7 @@ att_reacting_units(struct combat *def, struct emp_qelem *list, int a_spy,
     while (nxtitem(&ni, &land) && dtotal + new_land * eff < 1.2 * ototal) {
        if (!land.lnd_own)
            continue;
-       if (!land.lnd_rad_max)
+       if (land.lnd_mission != MI_RESERVE)
            continue;
        if ((land.lnd_x == def->x) && (land.lnd_y == def->y))
            continue;
@@ -1500,24 +1501,20 @@ att_reacting_units(struct combat *def, struct emp_qelem *list, int a_spy,
            continue;
 
        /* Only supplied units can react */
-       if (!has_supply(&land))
-           continue;
-
-       dist = mapdist(land.lnd_x, land.lnd_y, def->x, def->y);
-
-       getsect(land.lnd_x, land.lnd_y, &sect);
-       /* Units on efficient headquarters can react 1 farther */
-       if ((sect.sct_type == SCT_HEADQ) && (sect.sct_effic >= 60))
-           radius = land.lnd_rad_max + 1;
-       else
-           radius = land.lnd_rad_max;
-
-       if (land.lnd_mission == MI_RESERVE)
-           radius += 2;
+       if (list) {
+           resupply_all(&land);
+           putland(land.lnd_uid, &land);
+           if (!lnd_in_supply(&land))
+               continue;
+       } else {
+           if (!lnd_could_be_supplied(&land))
+               continue;
+       }
 
-       if (dist > radius)
+       if (!in_oparea((struct empobj *)&land, def->x, def->y))
            continue;
 
+       getsect(land.lnd_x, land.lnd_y, &sect);
        getsect(def->x, def->y, &dsect);
        if (!BestLandPath(buf, &sect, &dsect, &pathcost,
                          lnd_mobtype(&land)))
@@ -1847,7 +1844,7 @@ att_fight(int combat_mode, struct combat *off, struct emp_qelem *olist,
     att_infect_units(dlist, def->plague);
 
     /*
-     * Fighting is slightly random.  There is always that last little 
+     * Fighting is slightly random.  There is always that last little
      * effort you see people put in.  Or the stray bullet that takes out
      * an officer and the rest go into chaos.  Things like that.
      * Thus, we have added a very slight random factor that will sometimes
@@ -2253,11 +2250,11 @@ take_def(int combat_mode, struct emp_qelem *list, struct combat *off,
        putsect(&sect);
     } else if (def->type == EF_SHIP) {
        getship(def->shp_uid, &ship);
-       takeover_ship(&ship, player->cnum, 1);
+       takeover_ship(&ship, player->cnum);
        putship(ship.shp_uid, &ship);
     } else if (def->type == EF_LAND) {
        getland(def->lnd_uid, &land);
-       takeover_land(&land, player->cnum, 1);
+       takeover_land(&land, player->cnum);
        putland(land.lnd_uid, &land);
     }
     if (delete_me)
@@ -2588,7 +2585,7 @@ att_free_lists(struct emp_qelem *olist, struct emp_qelem *dlist)
 /*
  * sector_strength - Everyone starts at 1.  You can get up to a max
  *                   of d_dstr, depending on how much you build up the
- *                   defenses of the sector. 
+ *                   defenses of the sector.
  */
 
 double