diff --git a/include/land.h b/include/land.h index c1bd797d..e4266477 100644 --- a/include/land.h +++ b/include/land.h @@ -192,12 +192,12 @@ extern void lnd_submil(struct lndstr *, int); extern void lnd_takemob(struct emp_qelem *, double); extern int lnd_spyval(struct lndstr *); extern void intelligence_report(int, struct lndstr *, int, char *); -extern void lnd_mar(struct emp_qelem *, double *, double *, int *, natid); +extern void lnd_mar(struct emp_qelem *, double *, double *, natid); extern void lnd_put(struct emp_qelem *); extern void lnd_put_one(struct ulist *); extern int lnd_hardtarget(struct lndstr *); extern int lnd_abandon_askyn(struct emp_qelem *); -extern int lnd_mar_one_sector(struct emp_qelem *, int, natid, int); +extern int lnd_mar_one_sector(struct emp_qelem *, int, natid); extern int lnd_support(natid, natid, coord, coord, int); extern int lnd_can_attack(struct lndstr *); extern int lnd_fortify(struct lndstr *lp, int hard_amt); diff --git a/info/march.t b/info/march.t index ecb5bc58..bfc1afd1 100644 --- a/info/march.t +++ b/info/march.t @@ -3,7 +3,8 @@ .LV Basic .SY "march " The march command is the \*Qmove\*U command applied to land units. -You can control one unit or an entire army with it. +You can control one unit or an entire army with it, but they must all +start in the same sector. .s1 Land units may only move into sectors you own, sectors of countries you are allied with or deity-owned sectors with 1 exception. Spies. Spies @@ -115,10 +116,6 @@ For example, war band #18 stopped at -5,-3 .FI .s1 -Note that if you are marching multiple units, you may only specify a -destination sector on the command line if all the units start in the -same sector. -.s1 See \*Qinfo Mobility\*U for the mobility cost to march land units. .s1 Moving a unit through a sector that has been mined diff --git a/src/lib/commands/marc.c b/src/lib/commands/marc.c index 65b5a157..951aedaf 100644 --- a/src/lib/commands/marc.c +++ b/src/lib/commands/marc.c @@ -44,12 +44,12 @@ march(void) struct nstr_item ni_land; struct emp_qelem land_list; double minmob, maxmob; - int together; + int together = 1; if (!snxtitem(&ni_land, EF_LAND, player->argp[1], NULL)) return RET_SYN; lnd_sel(&ni_land, &land_list); - lnd_mar(&land_list, &minmob, &maxmob, &together, player->cnum); + lnd_mar(&land_list, &minmob, &maxmob, player->cnum); if (QEMPTY(&land_list)) { pr("No lands\n"); return RET_FAIL; diff --git a/src/lib/commands/navi.c b/src/lib/commands/navi.c index c398e848..54ab8c05 100644 --- a/src/lib/commands/navi.c +++ b/src/lib/commands/navi.c @@ -101,7 +101,7 @@ do_unit_move(struct emp_qelem *ulist, int *together, if (type == EF_SHIP) shp_nav(ulist, minmob, maxmob, together, player->cnum); else - lnd_mar(ulist, minmob, maxmob, together, player->cnum); + lnd_mar(ulist, minmob, maxmob, player->cnum); if (QEMPTY(ulist)) { pr("No %s left\n", type == EF_SHIP ? "ships" : "lands"); return RET_OK; @@ -128,7 +128,7 @@ do_unit_move(struct emp_qelem *ulist, int *together, if (type == EF_SHIP) shp_nav(ulist, minmob, maxmob, together, player->cnum); else - lnd_mar(ulist, minmob, maxmob, together, player->cnum); + lnd_mar(ulist, minmob, maxmob, player->cnum); if (QEMPTY(ulist)) { pr("No %s left\n", type == EF_SHIP ? "ships" : "lands"); return RET_OK; @@ -157,9 +157,7 @@ do_unit_move(struct emp_qelem *ulist, int *together, else { if (!moved && !lnd_abandon_askyn(ulist)) return RET_FAIL; - stopping |= - lnd_mar_one_sector(ulist, dir, player->cnum, - *together); + stopping |= lnd_mar_one_sector(ulist, dir, player->cnum); } moved = 1; cp++; diff --git a/src/lib/subs/lndsub.c b/src/lib/subs/lndsub.c index c80da183..ab6ac4aa 100644 --- a/src/lib/subs/lndsub.c +++ b/src/lib/subs/lndsub.c @@ -454,21 +454,17 @@ lnd_insque(struct lndstr *lp, struct emp_qelem *list) /* This function assumes that the list was created by lnd_sel */ void lnd_mar(struct emp_qelem *list, double *minmobp, double *maxmobp, - int *togetherp, natid actor) + natid actor) { struct emp_qelem *qp; struct emp_qelem *next; struct ulist *llp; - struct lndstr *lp; + struct lndstr *lp, *ldr = NULL; struct sctstr sect; - coord allx; - coord ally; - int first = 1; char mess[128]; *minmobp = 9876.0; *maxmobp = -9876.0; - *togetherp = 1; for (qp = list->q_back; qp != list; qp = next) { next = qp->q_back; llp = (struct ulist *)qp; @@ -519,13 +515,12 @@ lnd_mar(struct emp_qelem *list, double *minmobp, double *maxmobp, lnd_stays(actor, mess, llp); continue; } - if (first) { - allx = lp->lnd_x; - ally = lp->lnd_y; - first = 0; + if (!ldr) + ldr = lp; + else if (lp->lnd_x != ldr->lnd_x || lp->lnd_y != ldr->lnd_y) { + lnd_stays(actor, "is not with the leader", llp); + continue; } - if (lp->lnd_x != allx || lp->lnd_y != ally) - *togetherp = 0; if (lp->lnd_mobil + 1 < (int)llp->mobil) { llp->mobil = lp->lnd_mobil; } @@ -978,14 +973,12 @@ int lnd_abandon_askyn(struct emp_qelem *list) } int -lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor, - int together) +lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor) { struct sctstr sect, osect; struct emp_qelem *qp; struct emp_qelem *next; struct ulist *llp; - struct emp_qelem cur, done; coord dx; coord dy; coord newx; @@ -998,6 +991,9 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor, int rel; int oldown; + if (CANT_HAPPEN(QEMPTY(list))) + return 1; + if (dir <= DIR_STOP || dir >= DIR_VIEW) { lnd_mar_put(list, actor); return 1; @@ -1005,19 +1001,21 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor, dx = diroff[dir][0]; dy = diroff[dir][1]; + llp = (struct ulist *)list->q_back; + getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, &osect); + oldown = osect.sct_own; + newx = xnorm(llp->unit.land.lnd_x + dx); + newy = ynorm(llp->unit.land.lnd_y + dy); + getsect(newx, newy, §); + rel = relations_with(sect.sct_own, actor); + move = 0; for (qp = list->q_back; qp != list; qp = next) { next = qp->q_back; llp = (struct ulist *)qp; - getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, &osect); - oldown = osect.sct_own; - newx = xnorm(llp->unit.land.lnd_x + dx); - newy = ynorm(llp->unit.land.lnd_y + dy); - getsect(newx, newy, §); stuck = lnd_check_mar(&llp->unit.land, §); if (stuck == LND_STUCK_NOT - && (relations_with(sect.sct_own, actor) == ALLIED - || !sect.sct_own + && (!sect.sct_own || rel == ALLIED || (lchr[llp->unit.land.lnd_type].l_flags & L_SPY))) { move = 1; } @@ -1026,19 +1024,13 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor, for (qp = list->q_back; qp != list; qp = next) { next = qp->q_back; llp = (struct ulist *)qp; - getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, &osect); - oldown = osect.sct_own; - newx = xnorm(llp->unit.land.lnd_x + dx); - newy = ynorm(llp->unit.land.lnd_y + dy); - getsect(newx, newy, §); - rel = relations_with(sect.sct_own, actor); stuck = lnd_check_mar(&llp->unit.land, §); if (stuck != LND_STUCK_NOT || (sect.sct_own && rel != ALLIED && !(lchr[llp->unit.land.lnd_type].l_flags & L_SPY))) { if (stuck == LND_STUCK_NO_RAIL && (!sect.sct_own || rel == ALLIED)) { - if (together && !move) { + if (!move) { mpr(actor, "no rail system in %s\n", xyas(newx, newy, actor)); return 1; @@ -1049,7 +1041,7 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor, continue; } } else { - if (together && !move) { + if (!move) { mpr(actor, "can't go to %s\n", xyas(newx, newy, actor)); return 1; } else { @@ -1104,38 +1096,15 @@ lnd_mar_one_sector(struct emp_qelem *list, int dir, natid actor, if (QEMPTY(list)) return stopping; - /* interdict land units sector by sector */ - emp_initque(&cur); - emp_initque(&done); - while (!QEMPTY(list)) { - llp = (struct ulist *)list->q_back; - newx = llp->unit.land.lnd_x; - newy = llp->unit.land.lnd_y; - /* move units in NEWX,NEWY to cur */ - visible = 0; - for (qp = list->q_back; qp != list; qp = next) { - next = qp->q_back; - llp = (struct ulist *)qp; - if (llp->unit.land.lnd_x == newx && llp->unit.land.lnd_y == newy) { - emp_remque(qp); - emp_insque(qp, &cur); - if (!(lchr[(int)llp->unit.land.lnd_type].l_flags & L_SPY)) - visible = 1; - } - } - /* interdict them */ - if (visible) - stopping |= lnd_interdict(&cur, newx, newy, actor); - /* move survivors to done */ - for (qp = cur.q_back; qp != &cur; qp = next) { - next = qp->q_back; - emp_remque(qp); - emp_insque(qp, &done); - } + visible = 0; + for (qp = list->q_back; qp != list; qp = next) { + next = qp->q_back; + llp = (struct ulist *)qp; + if (!(lchr[(int)llp->unit.land.lnd_type].l_flags & L_SPY)) + visible = 1; } - /* assign surviving land units back to list */ - emp_insque(list, &done); - emp_remque(&done); + if (visible) + stopping |= lnd_interdict(list, newx, newy, actor); return stopping; } diff --git a/tests/navi-march-test b/tests/navi-march-test index f4ca34b6..776b739e 100755 --- a/tests/navi-march-test +++ b/tests/navi-march-test @@ -17,7 +17,6 @@ MARKET 1 EOF customize big-city # TODO cover scattered navigate -# TODO cover scattered march # TODO cover RAILWAYS 0 begin_test "$srcdir"/tests/navi-march/setup-POGO diff --git a/tests/navi-march/02-march-1 b/tests/navi-march/02-march-1 index 1d6ac57c..6aee63b1 100644 --- a/tests/navi-march/02-march-1 +++ b/tests/navi-march/02-march-1 @@ -16,6 +16,9 @@ march 22/21/23 jh march 24 nh | kidnapped in -5,3 march 25 gh +| not with leader +march 21/10 nh +__cmd added 1 1 0 || get stuck on the way | die, by hitting mine in 8,6 | #31 hits a mine, #30 doesn't diff --git a/tests/navi-march/final.xdump b/tests/navi-march/final.xdump index 04c3fddf..0388a371 100644 --- a/tests/navi-march/final.xdump +++ b/tests/navi-march/final.xdump @@ -214,7 +214,7 @@ uid owner xloc yloc type effic mobil off tech opx opy mission radius army ship h 14 1 1 1 0 100 127 0 30 1 1 none 3 "" 1 0 42 () "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 15 1 1 1 0 100 127 0 30 1 1 none 3 "" -1 0 42 () "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 1 0 20 1 3 3 0 100 105 0 30 1 3 none 3 "" -1 0 42 () "" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 -21 1 1 3 0 100 127 0 30 1 3 reserve 3 "" -1 127 42 (bombed) "hhhhn" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 +21 1 2 4 0 100 105 0 30 1 3 none 3 "" -1 0 42 () "" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 22 1 3 3 7 100 60 0 40 0 0 none 0 "" -1 0 42 () "" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 23 1 3 3 7 50 -5 0 40 0 0 none 0 "" -1 0 42 () "" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 24 1 2 2 7 100 127 0 40 0 0 none 0 "" -1 0 42 () "" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 -1 0 diff --git a/tests/navi-march/journal.log b/tests/navi-march/journal.log index e1570b35..42af4f6f 100644 --- a/tests/navi-march/journal.log +++ b/tests/navi-march/journal.log @@ -786,6 +786,15 @@ Play#1 output Play#1 1 No lands Play#1 output Play#1 1 command failed Play#1 output Play#1 6 0 583 + Play#1 input march 21/10 nh + Play#1 command march + Play#1 output Play#1 1 cav cavalry #10 is not with the leader & stays in 2,2 + Play#1 output Play#1 1 Leader is cav cavalry #21 + Play#1 output Play#1 1 cav cavalry #21 stopped at 2,4 + Play#1 output Play#1 6 0 582 + Play#1 input __cmd added 1 1 0 + Play#1 command __cmd + Play#1 output Play#1 6 0 583 Play#1 input march 31/30 jX Play#1 command march Play#1 output Play#1 1 Leader is cav cavalry #31 @@ -1480,7 +1489,7 @@ Play#0 output Play#0 1 1 14 cav cavalry 1,1 100% 2 0 127 0 30 42% 0 0 1S Play#0 output Play#0 1 1 15 cav cavalry 1,1 100% 2 0 127 0 30 42% 0 0 1L Play#0 output Play#0 1 1 20 cav cavalry 3,3 100% 5 0 105 0 30 42% 0 0 - Play#0 output Play#0 1 1 21 cav cavalry 1,3 100% 5 127 127 0 30 42% 0 0 + Play#0 output Play#0 1 1 21 cav cavalry 2,4 100% 5 0 105 0 30 42% 0 0 Play#0 output Play#0 1 1 22 tra train 3,3 100% 5 0 60 0 40 42% 0 0 Play#0 output Play#0 1 1 23 tra train 3,3 50% 5 0 -5 0 40 42% 0 0 Play#0 output Play#0 1 1 24 tra train 2,2 100% 5 0 127 0 40 42% 0 0 @@ -1554,8 +1563,7 @@ Play#0 output Play#0 1 1 4 eng engineer 1,1 hhhhn b Play#0 output Play#0 1 2 11 cav cavalry 1,1 hhhhn b Play#0 output Play#0 1 1 12 cav cavalry 1,1 hhhhn b - Play#0 output Play#0 1 1 21 cav cavalry 1,3 hhhhn b - Play#0 output Play#0 1 5 units + Play#0 output Play#0 1 4 units Play#0 output Play#0 6 0 636 Play#0 input miss l * ?mission#0 q Play#0 command mission @@ -1563,7 +1571,6 @@ Play#0 output Play#0 1 eng engineer #4 1,1 1,1 1 is on a reserve mission Play#0 output Play#0 1 cav cavalry #11 1,1 1,1 3 is on a reserve mission Play#0 output Play#0 1 cav cavalry #12 1,1 1,1 3 is on a reserve mission - Play#0 output Play#0 1 cav cavalry #21 1,3 1,3 3 is on a reserve mission Play#0 output Play#0 6 0 634 Play#0 input ctld Play#0 output Play#0 1 Bye-bye