From fff476ac4b958cbfecf4690590df9fa8a9db21c0 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 12 Jan 2015 21:19:02 +0100 Subject: [PATCH] retreat: Fix group retreat after failed board sinks ship Group retreat still doesn't work, because when boar() passes a sunk ship to retreat_ship(), its owner has been reset to POGO already. This makes it impossible to find the group to retreat. Instead, it attempts to retreat ships that sank in the same sector with group retreat orders and with the same fleet letter assigned. If any exist, shp_may_nav() oopses, and prevents actual retreat of these ghosts. The other retreat conditions don't have this problem, because they call putship(), which resets the owner, only after retreat_ship(). Making boar() work the same is not practical. Instead, add an owner parameter to retreat_ship(), and for symmetry also to retreat_land(). Signed-off-by: Markus Armbruster --- include/retreat.h | 5 +++-- src/lib/commands/boar.c | 4 +++- src/lib/commands/bomb.c | 8 ++++---- src/lib/commands/laun.c | 2 +- src/lib/commands/mfir.c | 6 +++--- src/lib/commands/sona.c | 2 +- src/lib/commands/torp.c | 2 +- src/lib/subs/retreat.c | 20 ++++++++++---------- tests/retreat/01-retreat-1 | 1 - tests/retreat/final.xdump | 2 +- tests/retreat/journal.log | 8 ++++---- 11 files changed, 31 insertions(+), 29 deletions(-) diff --git a/include/retreat.h b/include/retreat.h index 29adaaabe..38f3bd182 100644 --- a/include/retreat.h +++ b/include/retreat.h @@ -28,6 +28,7 @@ * * Known contributors to this file: * Ken Stevens, 1995 + * Markus Armbruster, 2014-2015 */ #ifndef RETREAT_H @@ -48,7 +49,7 @@ #define RET_DCHRGED 64 /* Retreat when depth-charged */ #define RET_BOARDED 128 /* Retreat when unsuccessfully boarded */ -extern void retreat_ship(struct shpstr *, char); -extern void retreat_land(struct lndstr *, char); +extern void retreat_ship(struct shpstr *, natid, char); +extern void retreat_land(struct lndstr *, natid, char); #endif diff --git a/src/lib/commands/boar.c b/src/lib/commands/boar.c index 356eb3797..6db81b967 100644 --- a/src/lib/commands/boar.c +++ b/src/lib/commands/boar.c @@ -54,6 +54,7 @@ boar(void) struct lndstr land; struct nstr_item ni; int foundland, def_uid; + natid def_own; char *p; char buf[1024]; @@ -161,10 +162,11 @@ boar(void) * *def (see FIXME there). */ def_uid = def->shp_uid; + def_own = def->own; if (!(att_fight(A_BOARD, off, &olist, 1.0, def, &dlist, 1.0))) { getship(def_uid, &ship); if (ship.shp_rflags & RET_BOARDED) { - retreat_ship(&ship, 'u'); + retreat_ship(&ship, def_own, 'u'); putship(def_uid, &ship); } } diff --git a/src/lib/commands/bomb.c b/src/lib/commands/bomb.c index 3067bb01a..5e4888cd2 100644 --- a/src/lib/commands/bomb.c +++ b/src/lib/commands/bomb.c @@ -481,9 +481,9 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target) prship(&ship), xyas(target->sct_x, target->sct_y, player->cnum)); if (dam && (ship.shp_rflags & RET_INJURED)) - retreat_ship(&ship, 'i'); + retreat_ship(&ship, ship.shp_own, 'i'); else if (ship.shp_rflags & RET_BOMBED) - retreat_ship(&ship, 'b'); + retreat_ship(&ship, ship.shp_own, 'b'); putship(ship.shp_uid, &ship); collateral_damage(target->sct_x, target->sct_y, dam / 2); } @@ -671,9 +671,9 @@ land_bomb(struct emp_qelem *list, struct sctstr *target) xyas(target->sct_x, target->sct_y, own)); landdamage(&land, dam); if (dam && (land.lnd_rflags & RET_INJURED)) - retreat_land(&land, 'i'); + retreat_land(&land, own, 'i'); else if (land.lnd_rflags & RET_BOMBED) - retreat_land(&land, 'b'); + retreat_land(&land, own, 'b'); nreport(player->cnum, N_UNIT_BOMB, own, 1); putland(land.lnd_uid, &land); collateral_damage(target->sct_x, target->sct_y, dam); diff --git a/src/lib/commands/laun.c b/src/lib/commands/laun.c index f5151e6ec..04900bac0 100644 --- a/src/lib/commands/laun.c +++ b/src/lib/commands/laun.c @@ -277,7 +277,7 @@ launch_missile(struct plnstr *pp) if (target_ship.shp_effic < SHIP_MINEFF) pr("%s sunk!\n", prship(&target_ship)); if (dam && (target_ship.shp_rflags & RET_INJURED)) - retreat_ship(&target_ship, 'i'); + retreat_ship(&target_ship, target_ship.shp_own, 'i'); putship(target_ship.shp_uid, &target_ship); } return RET_OK; diff --git a/src/lib/commands/mfir.c b/src/lib/commands/mfir.c index c997e7dd3..a7e02db93 100644 --- a/src/lib/commands/mfir.c +++ b/src/lib/commands/mfir.c @@ -427,11 +427,11 @@ multifire(void) if (vship.shp_effic < SHIP_MINEFF) pr("%s sunk!\n", prsub(&vship)); if (dam && (vship.shp_rflags & RET_INJURED)) - retreat_ship(&vship, 'i'); + retreat_ship(&vship, vict, 'i'); else if (target == targ_sub && (vship.shp_rflags & RET_DCHRGED)) - retreat_ship(&vship, 'd'); + retreat_ship(&vship, vict, 'd'); else if (totaldefdam == 0 && (vship.shp_rflags & RET_HELPLESS)) - retreat_ship(&vship, 'h'); + retreat_ship(&vship, vict, 'h'); putship(vship.shp_uid, &vship); break; } diff --git a/src/lib/commands/sona.c b/src/lib/commands/sona.c index e470e0397..2941cf1d2 100644 --- a/src/lib/commands/sona.c +++ b/src/lib/commands/sona.c @@ -163,7 +163,7 @@ sona(void) xyas(ship.shp_x, ship.shp_y, targ.shp_own), prship(&targ)); if (targ.shp_rflags & RET_SONARED) { - retreat_ship(&targ, 's'); + retreat_ship(&targ, targ.shp_own, 's'); putship(targ.shp_uid, &targ); } } diff --git a/src/lib/commands/torp.c b/src/lib/commands/torp.c index 867ab50ee..d945d1808 100644 --- a/src/lib/commands/torp.c +++ b/src/lib/commands/torp.c @@ -189,7 +189,7 @@ torp(void) if (vship.shp_effic < SHIP_MINEFF) pr("%s sunk!\n", prsub(&vship)); if (vship.shp_rflags & RET_TORPED) - retreat_ship(&vship, 't'); + retreat_ship(&vship, vshipown, 't'); putship(vship.shp_uid, &vship); } else { pr("Missed\n"); diff --git a/src/lib/subs/retreat.c b/src/lib/subs/retreat.c index 15acd72f9..fad0e96b5 100644 --- a/src/lib/subs/retreat.c +++ b/src/lib/subs/retreat.c @@ -68,15 +68,16 @@ consume_step(char *rpath, int *rflags) } void -retreat_ship(struct shpstr *sp, char code) +retreat_ship(struct shpstr *sp, natid own, char code) { int n, i; - natid own; struct emp_qelem list; struct nstr_item ni; struct shpstr ship; - if (sp->shp_own == player->cnum || !sp->shp_rpath[0]) + if (CANT_HAPPEN(!own || (sp->shp_own && sp->shp_own != own))) + return; + if (own == player->cnum || !sp->shp_rpath[0]) return; n = retreat_steps(sp->shp_rpath); @@ -87,10 +88,9 @@ retreat_ship(struct shpstr *sp, char code) * We're going to put a copy of *sp into list. The movement loop * will use that copy, which may render *sp stale. To avoid * leaving the caller with a stale *sp, we'll re-get it at the - * end. To make that work, we need to put it now. However, that - * resets sp->shp_own when the ship sinks, so save it first. + * end. To make that work, we need to put it now. Resets + * sp->shp_own when the ship sinks. */ - own = sp->shp_own; putship(sp->shp_uid, sp); emp_initque(&list); @@ -174,15 +174,16 @@ retreat_ships_step(struct emp_qelem *list, char step, natid actor) } void -retreat_land(struct lndstr *lp, char code) +retreat_land(struct lndstr *lp, natid own, char code) { int n, i; - natid own; struct emp_qelem list; struct nstr_item ni; struct lndstr land; - if (lp->lnd_own == player->cnum || !lp->lnd_rpath[0]) + if (CANT_HAPPEN(!own || (lp->lnd_own && lp->lnd_own != own))) + return; + if (own == player->cnum || !lp->lnd_rpath[0]) return; n = retreat_steps(lp->lnd_rpath); @@ -190,7 +191,6 @@ retreat_land(struct lndstr *lp, char code) return; /* See explanation in retreat_ship() */ - own = lp->lnd_own; putland(lp->lnd_uid, lp); emp_initque(&list); diff --git a/tests/retreat/01-retreat-1 b/tests/retreat/01-retreat-1 index 5b9fcb683..4841b9543 100644 --- a/tests/retreat/01-retreat-1 +++ b/tests/retreat/01-retreat-1 @@ -145,7 +145,6 @@ board 130 5 | as group (fleet u): 132 sinks, 131 unremarkable board 132 5 50 -| BUG: group does not retreat __cmd added 1 4 0 ||| Land units | BUG: condition b triggers only on hit diff --git a/tests/retreat/final.xdump b/tests/retreat/final.xdump index 1bd1de00c..874d35b0a 100644 --- a/tests/retreat/final.xdump +++ b/tests/retreat/final.xdump @@ -83,7 +83,7 @@ uid owner xloc yloc type effic mobil off tech opx opy mission radius fleet civil 104 2 0 4 10 100 127 0 45 0 4 interdiction 1 "" 0 10 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" -3 1 1 (injured torpedoed helpless) "nn" 120 2 -9 1 18 100 93 0 60 -5 1 none 1 "" 0 10 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" -3 1 1 () "" 130 2 -9 1 12 100 96 0 60 -5 1 none 1 "" 0 10 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" -3 1 1 () "" -131 2 -5 1 12 100 127 0 60 -5 1 interdiction 1 "u" 0 10 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" -3 1 1 (group boarded) "gg" +131 2 -9 1 12 100 96 0 60 -5 1 none 1 "u" 0 10 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" -3 1 1 () "" 132 0 -5 1 12 0 127 0 60 -5 1 interdiction 1 "u" 0 65 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" -3 1 1 (group boarded) "gg" 149 0 0 0 0 0 0 0 0 0 0 none 0 "" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 0 0 0 () "" /config diff --git a/tests/retreat/journal.log b/tests/retreat/journal.log index ec215345f..fee3e622b 100644 --- a/tests/retreat/journal.log +++ b/tests/retreat/journal.log @@ -1415,6 +1415,8 @@ Play#0 output Play#0 1 1 (#1) lost 50 troops trying to board tt troop transport (#132) Play#0 output Play#0 1 We lost 15 troops defending Play#0 output Play#0 1 tt troop transport (#132) sunk! + Play#0 output Play#0 1 tt troop transport (#131) retreats along path gg + Play#0 output Play#0 1 tt troop transport (#131) stopped at -9,1 Play#0 output Play#0 1 1 planes spotted over 0,2 Play#0 output Play#0 1 1 bombs did 44% damage to cav cavalry #30 at 0,2 Play#0 output Play#0 1 cav cavalry #30 takes 17 @@ -1598,7 +1600,7 @@ Play#0 output Play#0 1 2 104 lc light cruis 0,4 100% 0 10 0 0 0 0 0 0 127 45 Play#0 output Play#0 1 2 120 sb submarine -9,1 100% 0 10 0 0 0 0 0 0 93 60 Play#0 output Play#0 1 2 130 tt troop trans -9,1 100% 0 10 0 0 0 0 0 0 96 60 - Play#0 output Play#0 1 2 131 tt troop trans -5,1 u 100% 0 10 0 0 0 0 0 0 127 60 + Play#0 output Play#0 1 2 131 tt troop trans -9,1 u 100% 0 10 0 0 0 0 0 0 96 60 Play#0 output Play#0 1 58 ships Play#0 output Play#0 6 0 640 Play#0 input retr * ?rflags#0 q @@ -1635,8 +1637,7 @@ Play#0 output Play#0 1 2 84 dd destroyer -6,2 nn ihb Play#0 output Play#0 1 2 101 lc light cruis 0,4 nn ith Play#0 output Play#0 1 2 104 lc light cruis 0,4 nn ith - Play#0 output Play#0 1 2 131 tt troop trans -5,1 u gg Yes u - Play#0 output Play#0 1 32 ships + Play#0 output Play#0 1 31 ships Play#0 output Play#0 6 0 639 Play#0 input miss s * ?mission#0 q Play#0 command mission @@ -1662,7 +1663,6 @@ Play#0 output Play#0 1 dd destroyer (#84) -6,2 -6,2 1 is on an interdiction mission Play#0 output Play#0 1 lc light cruiser (#101) 0,4 0,4 1 is on an interdiction mission Play#0 output Play#0 1 lc light cruiser (#104) 0,4 0,4 1 is on an interdiction mission - Play#0 output Play#0 1 tt troop transport (#131) -5,1 -5,1 1 is on an interdiction mission Play#0 output Play#0 6 0 637 Play#0 input land * Play#0 command land -- 2.43.0