]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/attsub.c
Remove get_land() parameter uid
[empserver] / src / lib / subs / attsub.c
index b541283e1bcd17b3f6cf79cc80beec5bbc8d283c..ebf3f65a088c0824124b5e5575d4a7c540f41557 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
  *  ---
  *
  *  attsub.c: Attack subroutines
- * 
+ *
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1996-2000
- *     Markus Armbruster, 2006-2008
+ *     Markus Armbruster, 2006-2009
  */
 
 #include <config.h>
@@ -83,7 +83,7 @@ static void send_reacting_units_home(struct emp_qelem *list);
 static int take_def(int combat_mode, struct emp_qelem *list,
                    struct combat *off, struct combat *def);
 
-static int get_land(int combat_mode, struct combat *def, int uid,
+static int get_land(int combat_mode, struct combat *def,
                    struct ulist *llp, int victim_land);
 
 char *att_mode[] = {
@@ -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.
  */
 
@@ -353,12 +353,12 @@ put_combat(struct combat *com)
                if ((com->mob - com->mobcost) < -127)
                    sect.sct_mobil = -127;
                else
-                   sect.sct_mobil = (short)(com->mob - com->mobcost);
+                   sect.sct_mobil = com->mob - com->mobcost;
            } else {
                if ((com->mob - com->mobcost) < 0)
                    sect.sct_mobil = 0;
                else
-                   sect.sct_mobil = (short)(com->mob - com->mobcost);
+                   sect.sct_mobil = com->mob - com->mobcost;
            }
        }
        sect.sct_own = com->own;
@@ -449,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",
@@ -708,29 +709,29 @@ att_ask_support(int offset, int *fortp, int *shipp, int *landp,
        *fortp = *shipp = 0;
        *landp = *planep = 0;
 
-       if (!(p = getstarg(player->argp[offset], "Use fort support? ",
-                          buf)))
+       p = getstarg(player->argp[offset], "Use fort support? ", buf);
+       if (!p)
            return RET_SYN;
 
        if ((*p == 'y') || (*p == 'Y'))
            *fortp = 1;
 
-       if (!(p = getstarg(player->argp[offset + 1], "Use ship support? ",
-                          buf)))
+       p = getstarg(player->argp[offset + 1], "Use ship support? ", buf);
+       if (!p)
            return RET_SYN;
 
        if ((*p == 'y') || (*p == 'Y'))
            *shipp = 1;
 
-       if (!(p = getstarg(player->argp[offset + 2], "Use land support? ",
-                          buf)))
+       p = getstarg(player->argp[offset + 2], "Use land support? ", buf);
+       if (!p)
            return RET_SYN;
 
        if ((*p == 'y') || (*p == 'Y'))
            *landp = 1;
 
-       if (!(p = getstarg(player->argp[offset + 3], "Use plane support? ",
-                          buf)))
+       p = getstarg(player->argp[offset + 3], "Use plane support? ", buf);
+       if (!p)
            return RET_SYN;
 
        if ((*p == 'y') || (*p == 'Y'))
@@ -911,7 +912,7 @@ ask_off(int combat_mode, struct combat *off, struct combat *def)
        sprintf(prompt, "Number of mil from %s (max %d) : ",
                prcom(0, off), mob_support);
     }
-    if ((attacking_mil = onearg(0, prompt)) < 0)
+    if ((attacking_mil = onearg(NULL, prompt)) < 0)
        abort_attack();
     if (att_abort(combat_mode, off, def))
        return 0;
@@ -965,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;
@@ -1039,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;
                }
            }
@@ -1069,9 +1072,7 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def,
            pr("%s has no offensive strength\n", prland(&land));
            continue;
        }
-       resupply_all(&land);
-       putland(land.lnd_uid, &land);
-       if (!has_supply(&land)) {
+       if (!lnd_supply_all(&land)) {
            pr("%s is out of supply, and cannot %s\n",
               prland(&land), att_mode[combat_mode]);
            continue;
@@ -1106,8 +1107,11 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def,
        memset(llp, 0, sizeof(struct ulist));
        emp_insque(&llp->queue, olist);
        llp->mobil = mobcost;
-       if (!get_land(combat_mode, def, land.lnd_uid, llp, 0))
-           continue;
+       getland(land.lnd_uid, &llp->unit.land);
+       llp->x = llp->unit.land.lnd_x;
+       llp->y = llp->unit.land.lnd_y;
+       llp->chrp = (struct empobj_chr *)&lchr[(int)llp->unit.land.lnd_type];
+       llp->eff = llp->unit.land.lnd_effic;
        if (lnd_spyval(&land) > *a_spyp)
            *a_spyp = lnd_spyval(&land);
        if (((struct lchrstr *)llp->chrp)->l_flags & L_ENGINEER)
@@ -1232,9 +1236,12 @@ 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);
-       if (!get_land(A_DEFEND, def, land.lnd_uid, llp, 1))
-           continue;
+       llp->supplied = lnd_supply_all(&land);
+       getland(land.lnd_uid, &llp->unit.land);
+       llp->x = llp->unit.land.lnd_x;
+       llp->y = llp->unit.land.lnd_y;
+       llp->chrp = (struct empobj_chr *)&lchr[(int)llp->unit.land.lnd_type];
+       llp->eff = llp->unit.land.lnd_effic;
        if (lnd_spyval(&land) > *d_spyp)
            *d_spyp = lnd_spyval(&land);
     }
@@ -1270,7 +1277,8 @@ get_ototal(int combat_mode, struct combat *off, struct emp_qelem *olist,
     for (qp = olist->q_forw; qp != olist; qp = next) {
        next = qp->q_forw;
        llp = (struct ulist *)qp;
-       if (check && !get_land(combat_mode, 0, llp->unit.land.lnd_uid, llp, 0))
+       if (check &&
+           !get_land(combat_mode, NULL, llp, 0))
            continue;
        if (combat_mode == A_ATTACK) {
            w = -1;
@@ -1319,7 +1327,7 @@ get_dtotal(struct combat *def, struct emp_qelem *list, double dsupport,
     for (qp = list->q_forw; qp != list; qp = next) {
        next = qp->q_forw;
        llp = (struct ulist *)qp;
-       if (check && !get_land(A_DEFEND, def, llp->unit.land.lnd_uid, llp, 1))
+       if (check && !get_land(A_DEFEND, def, llp, 1))
            continue;
        d_unit = defense_val(&llp->unit.land);
        if (!llp->supplied)
@@ -1338,51 +1346,45 @@ get_dtotal(struct combat *def, struct emp_qelem *list, double dsupport,
  */
 
 static int
-get_land(int combat_mode, struct combat *def, int uid, struct ulist *llp,
+get_land(int combat_mode, struct combat *def, struct ulist *llp,
         int victim_land)
 {
     struct lndstr *lp = &llp->unit.land;
     char buf[512];
 
-    getland(uid, lp);
+    getland(llp->unit.land.lnd_uid, lp);
 
-    if (!llp->chrp) {          /* first time */
-       llp->x = llp->unit.land.lnd_x;
-       llp->y = llp->unit.land.lnd_y;
-       llp->chrp = (struct empobj_chr *)&lchr[(int)llp->unit.land.lnd_type];
-    } else {                   /* not first time */
-       if (lp->lnd_effic < LAND_MINEFF) {
-           sprintf(buf, "was destroyed and is no longer a part of the %s",
+    if (lp->lnd_effic < LAND_MINEFF) {
+       sprintf(buf, "was destroyed and is no longer a part of the %s",
+               att_mode[combat_mode]);
+       lnd_delete(llp, buf);
+       return 0;
+    }
+    if (victim_land) {
+       if (lp->lnd_x != def->x || lp->lnd_y != def->y) {
+           lnd_delete(llp,
+                      "left to go fight another battle and is no longer a part of the defense");
+           return 0;
+       }
+    } else {
+       if (lp->lnd_own != player->cnum) {
+           sprintf(buf,
+                   "was destroyed and is no longer a part of the %s",
                    att_mode[combat_mode]);
            lnd_delete(llp, buf);
            return 0;
        }
-       if (victim_land) {
-           if (lp->lnd_x != def->x || lp->lnd_y != def->y) {
-               lnd_delete(llp,
-                          "left to go fight another battle and is no longer a part of the defense");
-               return 0;
-           }
-       } else {
-           if (lp->lnd_own != player->cnum) {
-               sprintf(buf,
-                       "was destroyed and is no longer a part of the %s",
-                       att_mode[combat_mode]);
-               lnd_delete(llp, buf);
-               return 0;
-           }
-           if (lp->lnd_x != llp->x || lp->lnd_y != llp->y) {
-               sprintf(buf,
-                       "left to fight another battle and is no longer a part of the %s",
-                       att_mode[combat_mode]);
-               lnd_delete(llp, buf);
-               return 0;
-           }
-           if (lp->lnd_effic < llp->eff) {
-               sprintf(buf, "damaged from %d%% to %d%%",
-                       llp->eff, lp->lnd_effic);
-               lnd_print(llp, buf);
-           }
+       if (lp->lnd_x != llp->x || lp->lnd_y != llp->y) {
+           sprintf(buf,
+                   "left to fight another battle and is no longer a part of the %s",
+                   att_mode[combat_mode]);
+           lnd_delete(llp, buf);
+           return 0;
+       }
+       if (lp->lnd_effic < llp->eff) {
+           sprintf(buf, "damaged from %d%% to %d%%",
+                   llp->eff, lp->lnd_effic);
+           lnd_print(llp, buf);
        }
     }
     llp->eff = llp->unit.land.lnd_effic;
@@ -1447,7 +1449,7 @@ put_land(struct emp_qelem *list)
            emp_remque((struct emp_qelem *)llp);
            free(llp);
        } else
-           get_land(A_ATTACK, 0, llp->unit.land.lnd_uid, llp, 0);
+           get_land(A_ATTACK, NULL, llp, 0);
     }
 }
 
@@ -1468,8 +1470,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];
@@ -1482,7 +1482,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;
@@ -1498,24 +1498,13 @@ att_reacting_units(struct combat *def, struct emp_qelem *list, int a_spy,
            continue;
 
        /* Only supplied units can react */
-       if (!has_supply(&land))
+       if (list ? !lnd_supply_all(&land) : !lnd_could_be_supplied(&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 (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)))
@@ -1667,7 +1656,8 @@ get_mine_dsupport(struct combat *def, int a_engineer)
     getsect(def->x, def->y, &sect);
 
     if (sect.sct_oldown != player->cnum) {
-       mines = MIN(sect.sct_mines, 20);
+       mines = SCT_LANDMINES(&sect);
+       mines = MIN(mines, 20);
        if (a_engineer)
            mines = ldround(mines / 2.0, 1);
        if (mines > 0) {
@@ -1845,7 +1835,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
@@ -2193,7 +2183,7 @@ take_def(int combat_mode, struct emp_qelem *list, struct combat *off,
 {
     int n;
     int occuppied = 0;
-    struct ulist *llp, *delete_me = 0;
+    struct ulist *llp, *delete_me = NULL;
     char buf[1024];
     struct sctstr sect;
     struct shpstr ship;
@@ -2300,9 +2290,9 @@ ask_move_in(struct combat *off, struct emp_qelem *olist,
            *answerp = 'N';
        if (*answerp == 'Y')
            continue;
+       if (!get_land(A_ATTACK, def, llp, 0))
+           continue;
        if (*answerp != 'N') {
-           if (!get_land(A_ATTACK, def, llp->unit.land.lnd_uid, llp, 0))
-               continue;
            sprintf(prompt, "Move in with %s (%c %d%%) [ynYNq?] ",
                    prland(&llp->unit.land),
                    llp->unit.land.lnd_army ? llp->unit.land.lnd_army : '~',
@@ -2310,7 +2300,7 @@ ask_move_in(struct combat *off, struct emp_qelem *olist,
            *answerp = att_prompt(prompt, llp->unit.land.lnd_army);
            if (player->aborted || att_get_combat(def, 0) < 0)
                *answerp = 'N';
-           if (!get_land(A_ATTACK, def, llp->unit.land.lnd_uid, llp, 0))
+           if (!get_land(A_ATTACK, def, llp, 0))
                continue;
        }
        if (*answerp == 'y' || *answerp == 'Y')
@@ -2326,7 +2316,7 @@ ask_move_in(struct combat *off, struct emp_qelem *olist,
        for (qp = olist->q_forw; qp != olist; qp = next) {
            next = qp->q_forw;
            llp = (struct ulist *)qp;
-           if (!get_land(A_ATTACK, def, llp->unit.land.lnd_uid, llp, 0))
+           if (!get_land(A_ATTACK, def, llp, 0))
                continue;
            sprintf(buf, "stays in %s",
                    xyas(llp->unit.land.lnd_x, llp->unit.land.lnd_y,
@@ -2355,7 +2345,7 @@ move_in_land(int combat_mode, struct combat *off, struct emp_qelem *olist,
     for (qp = olist->q_forw; qp != olist; qp = next) {
        next = qp->q_forw;
        llp = (struct ulist *)qp;
-       if (!get_land(combat_mode, def, llp->unit.land.lnd_uid, llp, 0))
+       if (!get_land(combat_mode, def, llp, 0))
            continue;
        take_move_in_mob(combat_mode, llp, off, def);
        llp->unit.land.lnd_x = def->x;
@@ -2462,7 +2452,8 @@ ask_move_in_off(struct combat *off, struct combat *def)
        return;
     sprintf(prompt, "How many mil to move in from %s (%d max)? ",
            xyas(off->x, off->y, player->cnum), mob_support);
-    if (!(p = getstring(prompt, buf)) || !*p || (num_mil = atoi(p)) <= 0)
+    p = getstring(prompt, buf);
+    if (!p || !*p || (num_mil = atoi(p)) <= 0)
        return;
 /* Make sure we don't move in more than we can support mobility-wise */
     if (num_mil > mob_support)
@@ -2586,7 +2577,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