diff --git a/include/retreat.h b/include/retreat.h index 29adaaab..38f3bd18 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 356eb379..6db81b96 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 3067bb01..5e4888cd 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 f5151e6e..04900bac 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 c997e7dd..a7e02db9 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 e470e039..2941cf1d 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 867ab50e..d945d180 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 15acd72f..fad0e96b 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 5b9fcb68..4841b954 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 1bd1de00..874d35b0 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 ec215345..fee3e622 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