]> 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 b874682b3234550036cea8573351f714c467d04a..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.
  */
 
@@ -361,8 +361,6 @@ put_combat(struct combat *com)
                    sect.sct_mobil = (short)(com->mob - com->mobcost);
            }
        }
-       makelost(EF_SECTOR, sect.sct_own, 0, sect.sct_x, sect.sct_y);
-       makenotlost(EF_SECTOR, com->own, 0, sect.sct_x, sect.sct_y);
        sect.sct_own = com->own;
        if (com->plague) {
            if (sect.sct_pstage == PLG_HEALTHY)
@@ -381,18 +379,13 @@ put_combat(struct combat *com)
            else
                land.lnd_mobil = (signed char)(com->mob - com->mobcost);
        }
-       makelost(EF_LAND, land.lnd_own, land.lnd_uid,
-                land.lnd_x, land.lnd_y);
        land.lnd_own = com->own;
-       makenotlost(EF_LAND, land.lnd_own, land.lnd_uid,
-                   land.lnd_x, land.lnd_y);
        if (com->plague) {
            if (land.lnd_pstage == PLG_HEALTHY)
                land.lnd_pstage = PLG_EXPOSED;
        }
        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,17 +402,12 @@ put_combat(struct combat *com)
            else
                ship.shp_mobil = (signed char)(com->mob - com->mobcost);
        }
-       makelost(EF_SHIP, ship.shp_own, ship.shp_uid,
-                ship.shp_x, ship.shp_y);
        ship.shp_own = com->own;
-       makenotlost(EF_SHIP, ship.shp_own, ship.shp_uid,
-                   ship.shp_x, ship.shp_y);
        if (com->plague) {
            if (ship.shp_pstage == PLG_HEALTHY)
                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;
@@ -461,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",
@@ -951,11 +940,11 @@ att_prompt(char *prompt, char army)
        army = '~';
     for (;;) {
        p = getstring(prompt, buf);
-       if (player->aborted || (p && *p == 'q')) {
+       if (!p || *p == 'q') {
            abort_attack();
            return 'N';
        }
-       if (!p || !*p)
+       if (!*p)
            return 'n';
        if (tolower(*p) == 'y' || tolower(*p) == 'n')
            return *p;
@@ -977,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;
@@ -1051,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;
                }
            }
@@ -1083,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;
@@ -1244,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)
@@ -1480,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];
@@ -1494,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;
@@ -1510,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)))
@@ -1857,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
@@ -2263,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)
@@ -2598,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