]> git.pond.sub.org Git - empserver/commitdiff
4.0.2 made land unit mobility costs differ significantly from normal
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 4 Jun 2006 17:41:12 +0000 (17:41 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 4 Jun 2006 17:41:12 +0000 (17:41 +0000)
move costs, but failed to make A* use these costs.  This broke land
unit path finding.  Fix:
(MOB_ROAD, MOB_MOVE, MOB_MARCH): Split MOB_ROAD into MOB_MOVE and
MOB_MARCH.  Users changed.
(lnd_mobcost, sector_mcost): Move minimum mobcost logic to
sector_mcost(), where it is visible to A*.  Also fixes unit reaction
path cost.

(lnd_path): Fix confusing message: don't claim there's no path when
all we really know is that there's no railway.

include/sect.h
src/lib/commands/sinf.c
src/lib/common/move.c
src/lib/common/path.c
src/lib/subs/attsub.c
src/lib/subs/lndsub.c
src/lib/subs/move.c
src/lib/subs/retreat.c
src/lib/subs/supply.c
src/lib/update/deliver.c
src/lib/update/finish.c

index d75b7c6868e49513382106bb91b285f852d17067..ec577043f8d718a9c6cbb7bb504d321cfd2107f9 100644 (file)
@@ -179,8 +179,9 @@ extern struct dchrstr bigcity_dchr;
 #define FORTEFF 5              /* forts must be 5% efficient to fire. */
 
 #define MOB_NONE    0
-#define MOB_ROAD    1
-#define MOB_RAIL    2
+#define MOB_MOVE    1
+#define MOB_MARCH   2
+#define MOB_RAIL    3
 
 #define INT_ROAD    0
 #define INT_RAIL    1
index 23c09bf6673140403cedf718c2e348169989be8f..77219c61fdccbff4fb0f1919888d30309351ee14 100644 (file)
@@ -76,7 +76,7 @@ sinfra(void)
            pr(" ");
        pr("%4d%% ", sect.sct_effic);
        pr("%4d%% ", sect.sct_road);
-       pr("%4.3f ", sector_mcost(&sect, MOB_ROAD));
+       pr("%4.3f ", sector_mcost(&sect, MOB_MOVE));
        pr("%4d%% ", sect.sct_rail);
        pr("%4.3f ", sector_mcost(&sect, MOB_RAIL));
        pr("%4d%% ", SCT_DEFENSE(&sect));
index 141accb5132ac481f34cb1cabda328e53795a7fa..eddc0780679799f4b3fcc840601bba1a11f88885 100644 (file)
@@ -45,12 +45,11 @@ sector_mcost(struct sctstr *sp, int do_bonus)
 {
     double d;
 
-    if (!(d = dchr[sp->sct_type].d_mcst))
+    d = dchr[sp->sct_type].d_mcst;
+    if (d <= 0)
        return -1.0;
 
-/* Note, the best you can get is a 1.0 here. */
-
-    if (do_bonus == MOB_ROAD) {
+    if (do_bonus == MOB_MOVE || do_bonus == MOB_MARCH) {
        d = d / (1.0 + sp->sct_road / 122.0);
     } else if (do_bonus == MOB_RAIL) {
        if (sp->sct_rail <= 0)
@@ -64,11 +63,13 @@ sector_mcost(struct sctstr *sp, int do_bonus)
        d = 1.0;
     if (dchr[sp->sct_type].d_mcst < 25)
        d = (d * 100.0 - sp->sct_effic) / 500.0;
-/*     d = (200.0 + (d - 3.0) * sp->sct_effic) / 500.0;*/
     else
        d = (d * 10.0 - sp->sct_effic) / 115;
 
-    if (d <= 0.0 || d < MIN_MOBCOST)
-       return MIN_MOBCOST;
-    return d;
+    if (do_bonus == MOB_MOVE)
+       return MAX(d, MIN_MOBCOST);
+    if (sp->sct_own != sp->sct_oldown && sp->sct_mobil <= 0
+       && do_bonus != MOB_RAIL)
+       return MAX(d, LND_MINMOBCOST);
+    return MAX(d, 0.01);
 }
index ab4604ad33cad535f3423ce55ba5c0f007d9e252..0f2f5b19ca6a0a9c985258e66fc4f1a30f90eaf8 100644 (file)
@@ -342,7 +342,7 @@ BestDistPath(char *path,
             struct sctstr *from,
             struct sctstr *to, double *cost)
 {
-    return BestLandPath(path, from, to, cost, MOB_ROAD);
+    return BestLandPath(path, from, to, cost, MOB_MOVE);
 }
 
 char *
index aabf9d088d4a4f5ea7e3ce549b2579b56d767cc7..0394f96becedd1093b65151901e1516d16f20605 100644 (file)
@@ -793,7 +793,7 @@ get_mob_support(int combat_mode, struct combat *off, struct combat *def)
     switch (combat_mode) {
     case A_ATTACK:
        mob_support = off->mob / sector_mcost(getsectp(def->x, def->y),
-                                             MOB_ROAD);
+                                             MOB_MOVE);
        if (mob_support < 0)
            mob_support = 0;
 /*             mob_support = off->mob / sector_mcost(def->sct_type, def->eff);*/
@@ -854,7 +854,7 @@ calc_mobcost(int combat_mode, struct combat *off, struct combat *def,
        off->mobcost +=
            MAX(1,
                (int)(attacking_mil *
-                     sector_mcost(getsectp(def->x, def->y), MOB_ROAD)));
+                     sector_mcost(getsectp(def->x, def->y), MOB_MOVE)));
        break;
     case A_LBOARD:
        off->mobcost += MAX(1, attacking_mil / 5);
@@ -1506,7 +1506,7 @@ att_reacting_units(struct combat *def, struct emp_qelem *list, int a_spy,
            continue;
 
        getsect(def->x, def->y, &dsect);
-       if (!BestLandPath(buf, &sect, &dsect, &move_cost, MOB_ROAD))
+       if (!BestLandPath(buf, &sect, &dsect, &move_cost, MOB_MARCH))
            continue;
 
        mobcost = land.lnd_effic * 0.01 * lchr[(int)land.lnd_type].l_spd;
@@ -2445,7 +2445,7 @@ ask_move_in_off(struct combat *off, struct combat *def)
        return;
     if (off->own != player->cnum)
        return;
-    d = sector_mcost(getsectp(def->x, def->y), MOB_ROAD);
+    d = sector_mcost(getsectp(def->x, def->y), MOB_MOVE);
     if ((mob_support = MIN(off->troops, (int)(off->mob / d))) <= 0)
        return;
     sprintf(prompt, "How many mil to move in from %s (%d max)? ",
index 790d6677d11ae3f671568b8b2dc490314fe10dd3..787ad15a732d146a7407db42cc7871fb256737e7 100644 (file)
@@ -242,7 +242,7 @@ lnd_take_casualty(int combat_mode, struct llist *llp, int cas)
                llp->land.lnd_x = bx;
                llp->land.lnd_y = by;
                getsect(bx, by, &rsect);
-               mobcost = lnd_mobcost(&llp->land, &rsect, MOB_ROAD);
+               mobcost = lnd_mobcost(&llp->land, &rsect, MOB_MARCH);
                mob = llp->land.lnd_mobil - (int)mobcost;
                if (mob < -127)
                    mob = -127;
@@ -996,38 +996,20 @@ lnd_hit_mine(struct lndstr *lp, struct lchrstr *lcp)
 double
 lnd_mobcost(struct lndstr *lp, struct sctstr *sp, int mobtype)
 {
-    double mobcost;
-    double smobcost;
+    double effspd;
 
-    /* supply unit's speed depends on their eff, since
-       that is their purpose */
+    effspd = lp->lnd_spd;
     if (lchr[(int)lp->lnd_type].l_flags & L_SUPPLY)
-       mobcost = lp->lnd_effic * 0.01 * lp->lnd_spd;
-    else
-       mobcost = lp->lnd_spd;
-    if (mobcost < 0.01)
-       mobcost = 0.01;
-
-/* sector_mcost now takes 2 different arguments, a sector pointer, and
-   whether or not to figure in the highway bonus, rail bonus or none.
-   bridge heads, bridges and highways have built-in highways bonus
-   because they are a 1, and this will discount that. */
-
-    smobcost = sector_mcost(sp, mobtype);
-    if (smobcost < 0.01)
-       smobcost = 0.01;
-
-/* marching through 0 mobility conquered sectors takes lots of mobility,
-   unless you are a train.  Capturing railways is a good thing. */
-
-    if (sp->sct_own != sp->sct_oldown && sp->sct_mobil <= 0 &&
-       smobcost < LND_MINMOBCOST && mobtype != MOB_RAIL)
-       smobcost = LND_MINMOBCOST;
-
-    mobcost = smobcost * 5.0 * 480.0 /
-       (mobcost + techfact(lp->lnd_tech, mobcost));
-
-    return mobcost;
+       effspd *= lp->lnd_effic * 0.01;
+
+    /*
+     * The return value must be sector_mcost(...) times a factor that
+     * depends only on the land unit.  Anything else breaks path
+     * finding.  In particular, you can't add or enforce a minimum
+     * cost here.  Do it in sector_mcost().
+     */
+    return sector_mcost(sp, mobtype) * 5.0 * 480.0
+       / (effspd + techfact(lp->lnd_tech, effspd));
 }
 
 int
@@ -1122,7 +1104,7 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor,
        if (lchr[(int)llp->land.lnd_type].l_flags & L_TRAIN) {
            llp->mobil -= lnd_mobcost(&llp->land, &sect, MOB_RAIL);
        } else {
-           llp->mobil -= lnd_mobcost(&llp->land, &sect, MOB_ROAD);
+           llp->mobil -= lnd_mobcost(&llp->land, &sect, MOB_MARCH);
        }
        llp->land.lnd_mobil = (int)llp->mobil;
        llp->land.lnd_harden = 0;
@@ -1282,6 +1264,7 @@ lnd_path(int together, struct lndstr *lp, char *buf)
     struct sctstr d_sect, sect;
     char *cp;
     double dummy;
+    int mtype;
 
     if (!sarg_xy(buf, &destx, &desty))
        return 0;
@@ -1295,11 +1278,13 @@ lnd_path(int together, struct lndstr *lp, char *buf)
     }
     getsect(lp->lnd_x, lp->lnd_y, &sect);
     if (lchr[(int)lp->lnd_type].l_flags & L_TRAIN)
-       cp = BestLandPath(buf, &sect, &d_sect, &dummy, MOB_RAIL);
+       mtype = MOB_RAIL;
     else
-       cp = BestLandPath(buf, &sect, &d_sect, &dummy, MOB_ROAD);
+       mtype = MOB_MARCH;
+    cp = BestLandPath(buf, &sect, &d_sect, &dummy, mtype);
     if (!cp) {
-       pr("No owned path from %s to %s!\n",
+       pr("No owned %s from %s to %s!\n",
+          mtype == MOB_RAIL ? "railway" : "path",
           xyas(lp->lnd_x, lp->lnd_y, player->cnum),
           xyas(d_sect.sct_x, d_sect.sct_y, player->cnum));
        return 0;
index 7a17153446ec9fd3bc9b1f0bffc58c8b40183fa5..52aa893337d7e488d2cfe7bd1fd4018bad439ab2 100644 (file)
@@ -85,7 +85,7 @@ move_ground(struct sctstr *start, struct sctstr *end,
        }
        pr("Looking for best path to %s\n", path);
        path = BestLandPath(buf2, start, &ending_sect, &total_mcost,
-                           MOB_ROAD);
+                           MOB_MOVE);
        if (exploring && path)  /* take off the 'h' */
            path[strlen(path) - 1] = '\0';
        if (!path)
@@ -126,7 +126,7 @@ move_ground(struct sctstr *start, struct sctstr *end,
        if (movstr && sarg_xy(movstr, &dx, &dy)) {
            if (getsect(dx, dy, &dsect)) {
                movstr = BestLandPath(buf2, &sect, &dsect, &mv_cost,
-                                     MOB_ROAD);
+                                     MOB_MOVE);
            } else {
                pr("Invalid destination sector!\n");
                movstr = NULL;
@@ -190,7 +190,7 @@ move_ground(struct sctstr *start, struct sctstr *end,
                *movstr = 0;
                continue;
            }
-           sect_mcost = sector_mcost(&next, MOB_ROAD);
+           sect_mcost = sector_mcost(&next, MOB_MOVE);
            if ((!player->owner && (!exploring
                                    || next.sct_item[I_MILIT]
                                    || next.sct_item[I_CIVIL]))
index 2902f0f99c3b4209a7a34f1859ff4a35f5127afd..ecb198939eed6758cd71b402c0d8baf84f8b37c2 100644 (file)
@@ -471,7 +471,7 @@ retreat_land1(struct lndstr *lp, char code, int orig)
                putland(lp->lnd_uid, lp);
            return 0;
        }
-       mobcost = lnd_mobcost(lp, &sect, MOB_ROAD);
+       mobcost = lnd_mobcost(lp, &sect, MOB_MARCH);
        lp->lnd_x = newx;
        lp->lnd_y = newy;
        lp->lnd_mobil -= mobcost;
index 8795d045fb025ee09fb267717be4ce536436389a..6384cc924c6c8c841aed4390ea67ea6c1d63fd0f 100644 (file)
@@ -200,7 +200,7 @@ s_commod(int own, int x, int y, i_type type, int total_wanted,
            continue;
        if (sect.sct_effic < 60)
            continue;
-       if (!BestLandPath(buf, &dest, &sect, &move_cost, MOB_ROAD))
+       if (!BestLandPath(buf, &dest, &sect, &move_cost, MOB_MOVE))
            continue;
        if (!opt_NOFOOD && type == I_FOOD)
            minimum = 1 + (int)ceil(food_needed(sect.sct_item,
@@ -273,7 +273,7 @@ s_commod(int own, int x, int y, i_type type, int total_wanted,
            continue;
        if (sect.sct_effic < 2)
            continue;
-       if (!BestLandPath(buf, &dest, &sect, &move_cost, MOB_ROAD))
+       if (!BestLandPath(buf, &dest, &sect, &move_cost, MOB_MOVE))
            continue;
        if (!opt_NOFOOD && type == I_FOOD)
            minimum = 1 + (int)ceil(food_needed(ship.shp_item,
@@ -347,7 +347,7 @@ s_commod(int own, int x, int y, i_type type, int total_wanted,
            continue;
 
        getsect(land.lnd_x, land.lnd_y, &sect);
-       if (!BestLandPath(buf, &dest, &sect, &move_cost, MOB_ROAD))
+       if (!BestLandPath(buf, &dest, &sect, &move_cost, MOB_MOVE))
            continue;
 
        if ((land.lnd_ship >= 0) && (sect.sct_type != SCT_HARBR))
index c6992b7fde6f05605d7940ad91314d022ed611af..4a99b1474079d6631c747870ed92c05e48e1a9f7 100644 (file)
@@ -100,7 +100,7 @@ deliver(struct sctstr *from, struct ichrstr *ip, int dir,
      * calculate unit movement cost; decrease amount if
      * there isn't enough mobility.
      */
-    mcost = sector_mcost(to, MOB_ROAD) * ip->i_lbs / ip->i_pkg[packing];
+    mcost = sector_mcost(to, MOB_MOVE) * ip->i_lbs / ip->i_pkg[packing];
     mcost /= DELIVER_BONUS;
 
     if (mobility < mcost * amt_moved) {
index f6c646001fad1d0696218f279cea3e5e0fbf36ce..785faa3dc65dd506953c421b035baec1317ab01b 100644 (file)
@@ -220,7 +220,7 @@ assemble_dist_paths(struct distinfo *distptrs)
            p = ReversePath(path);
            /* And walk the path back to the dist center to get the export
               cost */
-           infptr->excost = pathcost(sp, p, MOB_ROAD);
+           infptr->excost = pathcost(sp, p, MOB_MOVE);
 #ifdef SAVE_FINISH_PATHS
            memcpy(infptr->path, p, len);
 #else