diff --git a/src/lib/subs/lndsub.c b/src/lib/subs/lndsub.c index ab21fc6f..94a1e41a 100644 --- a/src/lib/subs/lndsub.c +++ b/src/lib/subs/lndsub.c @@ -57,6 +57,20 @@ static void lnd_stays(natid, char *, struct ulist *); static int lnd_hit_mine(struct lndstr *); static int has_helpful_engineer(coord, coord, natid); +static struct ulist * +lnd_find_capable(struct emp_qelem *list, int flags) +{ + struct emp_qelem *qp; + struct ulist *llp; + + for (qp = list->q_back; qp != list; qp = qp->q_back) { + llp = (struct ulist *)qp; + if (lchr[llp->unit.land.lnd_type].l_flags & flags) + return llp; + } + return NULL; +} + double attack_val(int combat_mode, struct lndstr *lp) { @@ -578,9 +592,11 @@ lnd_put_one(struct ulist *llp) /* * Sweep landmines with engineers in LAND_LIST for ACTOR. + * All land units in LAND_LIST must be in the same sector. * If EXPLICIT is non-zero, this is for an explicit sweep command from * a player. Else it's an automatic "on the move" sweep. * If TAKEMOB is non-zero, require and charge mobility. + * Return non-zero when the land units should stop. */ int lnd_sweep(struct emp_qelem *land_list, int explicit, int takemob, @@ -593,36 +609,43 @@ lnd_sweep(struct emp_qelem *land_list, int explicit, int takemob, int mines, m, max, sshells, lshells; int stopping = 0; + llp = lnd_find_capable(land_list, L_ENGINEER); + if (!llp) { + if (explicit) + mpr(actor, "No engineers!\n"); + return 0; + } + + getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, §); + if (!explicit + && relations_with(sect.sct_oldown, actor) == ALLIED) + return 0; + if (SCT_MINES_ARE_SEAMINES(§)) { + if (explicit) + mpr(actor, "%s is a %s. No landmines there!\n", + xyas(sect.sct_x, sect.sct_y, actor), + dchr[sect.sct_type].d_name); + return 0; + } + for (qp = land_list->q_back; qp != land_list; qp = next) { next = qp->q_back; llp = (struct ulist *)qp; - if (!(lchr[llp->unit.land.lnd_type].l_flags & L_ENGINEER)) { - if (explicit) - mpr(actor, "%s is not an engineer!\n", - prland(&llp->unit.land)); + if (!(lchr[llp->unit.land.lnd_type].l_flags & L_ENGINEER)) continue; - } - if (takemob && llp->mobil <= 0.0) { - if (explicit) - mpr(actor, "%s is out of mobility!\n", - prland(&llp->unit.land)); - continue; - } - getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, §); - if (!explicit && relations_with(sect.sct_oldown, actor) == ALLIED) - continue; - if (SCT_MINES_ARE_SEAMINES(§)) { - if (explicit) - mpr(actor, "%s is in a %s sector. No landmines there!\n", - prland(&llp->unit.land), dchr[sect.sct_type].d_name); - continue; - } if (takemob) { + if (llp->mobil <= 0.0) { + if (explicit) + mpr(actor, "%s is out of mobility!\n", + prland(&llp->unit.land)); + continue; + } llp->mobil -= lnd_pathcost(&llp->unit.land, 0.2); llp->unit.land.lnd_mobil = (int)llp->mobil; llp->unit.land.lnd_harden = 0; } putland(llp->unit.land.lnd_uid, &llp->unit.land); + getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, §); if (!(mines = sect.sct_mines)) continue; max = lchr[llp->unit.land.lnd_type].l_item[I_SHELL]; diff --git a/src/lib/subs/shpsub.c b/src/lib/subs/shpsub.c index 9692e8e4..2c8423c3 100644 --- a/src/lib/subs/shpsub.c +++ b/src/lib/subs/shpsub.c @@ -58,6 +58,20 @@ static int shp_check_one_mines(struct ulist *); static int shp_hit_mine(struct shpstr *); static void shp_stays(natid, char *, struct ulist *); +static struct ulist * +shp_find_capable(struct emp_qelem *list, int flags) +{ + struct emp_qelem *qp; + struct ulist *mlp; + + for (qp = list->q_back; qp != list; qp = qp->q_back) { + mlp = (struct ulist *)qp; + if (mchr[mlp->unit.ship.shp_type].m_flags & flags) + return mlp; + } + return NULL; +} + void shp_sel(struct nstr_item *ni, struct emp_qelem *list) { @@ -192,8 +206,17 @@ shp_nav_put_one(struct ulist *mlp) free(mlp); } +/* + * Sweep seamines with engineers in SHIP_LIST for ACTOR. + * All ships in SHIP_LIST must be in the same sector. + * If EXPLICIT is non-zero, this is for an explicit sweep command from + * a player. Else it's an automatic "on the move" sweep. + * If TAKEMOB is non-zero, require and charge mobility. + * Return non-zero when the ships should stop. + */ int -shp_sweep(struct emp_qelem *ship_list, int verbose, int takemob, natid actor) +shp_sweep(struct emp_qelem *ship_list, int explicit, int takemob, + natid actor) { struct emp_qelem *qp; struct emp_qelem *next; @@ -203,33 +226,39 @@ shp_sweep(struct emp_qelem *ship_list, int verbose, int takemob, natid actor) int changed = 0; int stopping = 0; + mlp = shp_find_capable(ship_list, M_SWEEP); + if (!mlp) { + if (explicit) + mpr(actor, "No minesweepers!\n"); + return 0; + } + + getsect(mlp->unit.ship.shp_x, mlp->unit.ship.shp_y, §); + if (sect.sct_type != SCT_WATER) { + if (explicit) + mpr(actor, "%s is a %s. No seamines there!\n", + xyas(sect.sct_x, sect.sct_y, actor), + dchr[sect.sct_type].d_name); + return 0; + } + for (qp = ship_list->q_back; qp != ship_list; qp = next) { next = qp->q_back; mlp = (struct ulist *)qp; - if (!(mchr[mlp->unit.ship.shp_type].m_flags & M_SWEEP)) { - if (verbose) - mpr(actor, "%s doesn't have minesweeping capability!\n", - prship(&mlp->unit.ship)); + if (!(mchr[mlp->unit.ship.shp_type].m_flags & M_SWEEP)) continue; - } - if (takemob && mlp->mobil <= 0.0) { - if (verbose) - mpr(actor, "%s is out of mobility!\n", - prship(&mlp->unit.ship)); - continue; - } - getsect(mlp->unit.ship.shp_x, mlp->unit.ship.shp_y, §); - if (sect.sct_type != SCT_WATER) { - if (verbose) - mpr(actor, "%s is not at sea. No mines there!\n", - prship(&mlp->unit.ship)); - continue; - } if (takemob) { + if (mlp->mobil <= 0.0) { + if (explicit) + mpr(actor, "%s is out of mobility!\n", + prship(&mlp->unit.ship)); + continue; + } mlp->mobil -= shp_mobcost(&mlp->unit.ship); mlp->unit.ship.shp_mobil = (int)mlp->mobil; } putship(mlp->unit.ship.shp_uid, &mlp->unit.ship); + getsect(mlp->unit.ship.shp_x, mlp->unit.ship.shp_y, §); if (!(mines = sect.sct_mines)) continue; max = mchr[mlp->unit.ship.shp_type].m_item[I_SHELL]; diff --git a/tests/navi-march/journal.log b/tests/navi-march/journal.log index b2d9d098..93c6e639 100644 --- a/tests/navi-march/journal.log +++ b/tests/navi-march/journal.log @@ -556,15 +556,14 @@ Play#1 input navi 0/1 mh Play#1 command navigate Play#1 output Play#1 1 Flagship is pt patrol boat (#0) - Play#1 output Play#1 1 pt patrol boat (#0) doesn't have minesweeping capability! - Play#1 output Play#1 1 cs cargo ship (#1) doesn't have minesweeping capability! + Play#1 output Play#1 1 No minesweepers! Play#1 output Play#1 1 pt patrol boat (#0) stopped at 1,1 Play#1 output Play#1 1 cs cargo ship (#1) stopped at 1,1 Play#1 output Play#1 6 0 594 Play#1 input navi 5 mh Play#1 command navigate Play#1 output Play#1 1 Flagship is ms minesweeper (#5) - Play#1 output Play#1 1 ms minesweeper (#5) is not at sea. No mines there! + Play#1 output Play#1 1 1,1 is a harbor. No seamines there! Play#1 output Play#1 1 ms minesweeper (#5) stopped at 1,1 Play#1 output Play#1 6 0 593 Play#1 input navi 121/122/128 j @@ -643,7 +642,6 @@ Play#1 output Play#1 1 . . Play#1 output Play#1 4 <117.8:76.0: 11,-5> Play#1 input mmmh - Play#1 output Play#1 1 pt patrol boat (#135) doesn't have minesweeping capability! Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Kawhomp! Mine detected in 11,-5! Play#1 output Play#1 1 ms minesweeper (#130) takes 15 @@ -654,11 +652,6 @@ Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Kawhomp! Mine detected in 11,-5! Play#1 output Play#1 1 ms minesweeper (#131) takes 10 - Play#1 output Play#1 1 pt patrol boat (#136) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#137) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#138) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#139) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#135) doesn't have minesweeping capability! Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... @@ -671,11 +664,6 @@ Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 pt patrol boat (#136) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#137) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#138) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#139) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#135) doesn't have minesweeping capability! Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... @@ -684,10 +672,6 @@ Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Kawhomp! Mine detected in 11,-5! Play#1 output Play#1 1 ms minesweeper (#131) takes 11 - Play#1 output Play#1 1 pt patrol boat (#136) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#137) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#138) doesn't have minesweeping capability! - Play#1 output Play#1 1 pt patrol boat (#139) doesn't have minesweeping capability! Play#1 output Play#1 1 pt patrol boat (#135) stopped at 11,-5 Play#1 output Play#1 1 ms minesweeper (#130) stopped at 11,-5 Play#1 output Play#1 1 ms minesweeper (#131) stopped at 11,-5 @@ -1215,15 +1199,14 @@ Play#1 input march 0/2 mh Play#1 command march Play#1 output Play#1 1 Leader is cav cavalry #0 - Play#1 output Play#1 1 cav cavalry #0 is not an engineer! - Play#1 output Play#1 1 spy infiltrator #2 is not an engineer! + Play#1 output Play#1 1 No engineers! Play#1 output Play#1 1 cav cavalry #0 stopped at 1,1 Play#1 output Play#1 1 spy infiltrator #2 stopped at 1,1 Play#1 output Play#1 6 0 550 Play#1 input march 120 mh Play#1 command march Play#1 output Play#1 1 Leader is eng engineer #120 - Play#1 output Play#1 1 eng engineer #120 is in a bridge span sector. No landmines there! + Play#1 output Play#1 1 2,0 is a bridge span. No landmines there! Play#1 output Play#1 1 eng engineer #120 stopped at 2,0 Play#1 output Play#1 6 0 549 Play#1 input march 121/128 j @@ -1282,7 +1265,6 @@ Play#1 output Play#1 1 m m Play#1 output Play#1 4 <104.7:86.0: 8,6> Play#1 input mmmh - Play#1 output Play#1 1 cav cavalry #135 is not an engineer! Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... @@ -1291,37 +1273,23 @@ Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 cav cavalry #136 is not an engineer! - Play#1 output Play#1 1 cav cavalry #137 is not an engineer! - Play#1 output Play#1 1 cav cavalry #138 is not an engineer! - Play#1 output Play#1 1 cav cavalry #139 is not an engineer! - Play#1 output Play#1 1 cav cavalry #135 is not an engineer! - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Blammo! Landmines detected in 8,6! - Play#1 output Play#1 1 eng engineer #130 takes 6 - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 cav cavalry #136 is not an engineer! - Play#1 output Play#1 1 cav cavalry #137 is not an engineer! - Play#1 output Play#1 1 cav cavalry #138 is not an engineer! - Play#1 output Play#1 1 cav cavalry #139 is not an engineer! - Play#1 output Play#1 1 cav cavalry #135 is not an engineer! - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 Sweep... - Play#1 output Play#1 1 cav cavalry #136 is not an engineer! - Play#1 output Play#1 1 cav cavalry #137 is not an engineer! - Play#1 output Play#1 1 cav cavalry #138 is not an engineer! - Play#1 output Play#1 1 cav cavalry #139 is not an engineer! + Play#1 output Play#1 1 Blammo! Landmines detected in 8,6! + Play#1 output Play#1 1 eng engineer #130 takes 6 + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... + Play#1 output Play#1 1 Sweep... Play#1 output Play#1 1 cav cavalry #135 stopped at 8,6 Play#1 output Play#1 1 eng engineer #130 stopped at 8,6 Play#1 output Play#1 1 eng engineer #131 stopped at 8,6