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 <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2015-01-12 21:19:02 +01:00
parent 7b3d541c0d
commit fff476ac4b
11 changed files with 31 additions and 29 deletions

View file

@ -28,6 +28,7 @@
* *
* Known contributors to this file: * Known contributors to this file:
* Ken Stevens, 1995 * Ken Stevens, 1995
* Markus Armbruster, 2014-2015
*/ */
#ifndef RETREAT_H #ifndef RETREAT_H
@ -48,7 +49,7 @@
#define RET_DCHRGED 64 /* Retreat when depth-charged */ #define RET_DCHRGED 64 /* Retreat when depth-charged */
#define RET_BOARDED 128 /* Retreat when unsuccessfully boarded */ #define RET_BOARDED 128 /* Retreat when unsuccessfully boarded */
extern void retreat_ship(struct shpstr *, char); extern void retreat_ship(struct shpstr *, natid, char);
extern void retreat_land(struct lndstr *, char); extern void retreat_land(struct lndstr *, natid, char);
#endif #endif

View file

@ -54,6 +54,7 @@ boar(void)
struct lndstr land; struct lndstr land;
struct nstr_item ni; struct nstr_item ni;
int foundland, def_uid; int foundland, def_uid;
natid def_own;
char *p; char *p;
char buf[1024]; char buf[1024];
@ -161,10 +162,11 @@ boar(void)
* *def (see FIXME there). * *def (see FIXME there).
*/ */
def_uid = def->shp_uid; def_uid = def->shp_uid;
def_own = def->own;
if (!(att_fight(A_BOARD, off, &olist, 1.0, def, &dlist, 1.0))) { if (!(att_fight(A_BOARD, off, &olist, 1.0, def, &dlist, 1.0))) {
getship(def_uid, &ship); getship(def_uid, &ship);
if (ship.shp_rflags & RET_BOARDED) { if (ship.shp_rflags & RET_BOARDED) {
retreat_ship(&ship, 'u'); retreat_ship(&ship, def_own, 'u');
putship(def_uid, &ship); putship(def_uid, &ship);
} }
} }

View file

@ -481,9 +481,9 @@ ship_bomb(struct emp_qelem *list, struct sctstr *target)
prship(&ship), prship(&ship),
xyas(target->sct_x, target->sct_y, player->cnum)); xyas(target->sct_x, target->sct_y, player->cnum));
if (dam && (ship.shp_rflags & RET_INJURED)) 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) else if (ship.shp_rflags & RET_BOMBED)
retreat_ship(&ship, 'b'); retreat_ship(&ship, ship.shp_own, 'b');
putship(ship.shp_uid, &ship); putship(ship.shp_uid, &ship);
collateral_damage(target->sct_x, target->sct_y, dam / 2); 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)); xyas(target->sct_x, target->sct_y, own));
landdamage(&land, dam); landdamage(&land, dam);
if (dam && (land.lnd_rflags & RET_INJURED)) if (dam && (land.lnd_rflags & RET_INJURED))
retreat_land(&land, 'i'); retreat_land(&land, own, 'i');
else if (land.lnd_rflags & RET_BOMBED) else if (land.lnd_rflags & RET_BOMBED)
retreat_land(&land, 'b'); retreat_land(&land, own, 'b');
nreport(player->cnum, N_UNIT_BOMB, own, 1); nreport(player->cnum, N_UNIT_BOMB, own, 1);
putland(land.lnd_uid, &land); putland(land.lnd_uid, &land);
collateral_damage(target->sct_x, target->sct_y, dam); collateral_damage(target->sct_x, target->sct_y, dam);

View file

@ -277,7 +277,7 @@ launch_missile(struct plnstr *pp)
if (target_ship.shp_effic < SHIP_MINEFF) if (target_ship.shp_effic < SHIP_MINEFF)
pr("%s sunk!\n", prship(&target_ship)); pr("%s sunk!\n", prship(&target_ship));
if (dam && (target_ship.shp_rflags & RET_INJURED)) 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); putship(target_ship.shp_uid, &target_ship);
} }
return RET_OK; return RET_OK;

View file

@ -427,11 +427,11 @@ multifire(void)
if (vship.shp_effic < SHIP_MINEFF) if (vship.shp_effic < SHIP_MINEFF)
pr("%s sunk!\n", prsub(&vship)); pr("%s sunk!\n", prsub(&vship));
if (dam && (vship.shp_rflags & RET_INJURED)) 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)) 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)) else if (totaldefdam == 0 && (vship.shp_rflags & RET_HELPLESS))
retreat_ship(&vship, 'h'); retreat_ship(&vship, vict, 'h');
putship(vship.shp_uid, &vship); putship(vship.shp_uid, &vship);
break; break;
} }

View file

@ -163,7 +163,7 @@ sona(void)
xyas(ship.shp_x, ship.shp_y, xyas(ship.shp_x, ship.shp_y,
targ.shp_own), prship(&targ)); targ.shp_own), prship(&targ));
if (targ.shp_rflags & RET_SONARED) { if (targ.shp_rflags & RET_SONARED) {
retreat_ship(&targ, 's'); retreat_ship(&targ, targ.shp_own, 's');
putship(targ.shp_uid, &targ); putship(targ.shp_uid, &targ);
} }
} }

View file

@ -189,7 +189,7 @@ torp(void)
if (vship.shp_effic < SHIP_MINEFF) if (vship.shp_effic < SHIP_MINEFF)
pr("%s sunk!\n", prsub(&vship)); pr("%s sunk!\n", prsub(&vship));
if (vship.shp_rflags & RET_TORPED) if (vship.shp_rflags & RET_TORPED)
retreat_ship(&vship, 't'); retreat_ship(&vship, vshipown, 't');
putship(vship.shp_uid, &vship); putship(vship.shp_uid, &vship);
} else { } else {
pr("Missed\n"); pr("Missed\n");

View file

@ -68,15 +68,16 @@ consume_step(char *rpath, int *rflags)
} }
void void
retreat_ship(struct shpstr *sp, char code) retreat_ship(struct shpstr *sp, natid own, char code)
{ {
int n, i; int n, i;
natid own;
struct emp_qelem list; struct emp_qelem list;
struct nstr_item ni; struct nstr_item ni;
struct shpstr ship; 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; return;
n = retreat_steps(sp->shp_rpath); 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 * 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 * 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 * 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 * end. To make that work, we need to put it now. Resets
* resets sp->shp_own when the ship sinks, so save it first. * sp->shp_own when the ship sinks.
*/ */
own = sp->shp_own;
putship(sp->shp_uid, sp); putship(sp->shp_uid, sp);
emp_initque(&list); emp_initque(&list);
@ -174,15 +174,16 @@ retreat_ships_step(struct emp_qelem *list, char step, natid actor)
} }
void void
retreat_land(struct lndstr *lp, char code) retreat_land(struct lndstr *lp, natid own, char code)
{ {
int n, i; int n, i;
natid own;
struct emp_qelem list; struct emp_qelem list;
struct nstr_item ni; struct nstr_item ni;
struct lndstr land; 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; return;
n = retreat_steps(lp->lnd_rpath); n = retreat_steps(lp->lnd_rpath);
@ -190,7 +191,6 @@ retreat_land(struct lndstr *lp, char code)
return; return;
/* See explanation in retreat_ship() */ /* See explanation in retreat_ship() */
own = lp->lnd_own;
putland(lp->lnd_uid, lp); putland(lp->lnd_uid, lp);
emp_initque(&list); emp_initque(&list);

View file

@ -145,7 +145,6 @@ board 130 5
| as group (fleet u): 132 sinks, 131 unremarkable | as group (fleet u): 132 sinks, 131 unremarkable
board 132 5 board 132 5
50 50
| BUG: group does not retreat
__cmd added 1 4 0 __cmd added 1 4 0
||| Land units ||| Land units
| BUG: condition b triggers only on hit | BUG: condition b triggers only on hit

View file

@ -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" 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 () "" 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 () "" 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" 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 () "" 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 /config

View file

@ -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 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 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 (#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 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 1 bombs did 44% damage to cav cavalry #30 at 0,2
Play#0 output Play#0 1 cav cavalry #30 takes 17 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 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 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 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 1 58 ships
Play#0 output Play#0 6 0 640 Play#0 output Play#0 6 0 640
Play#0 input retr * ?rflags#0 q 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 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 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 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 31 ships
Play#0 output Play#0 1 32 ships
Play#0 output Play#0 6 0 639 Play#0 output Play#0 6 0 639
Play#0 input miss s * ?mission#0 q Play#0 input miss s * ?mission#0 q
Play#0 command mission 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 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 (#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 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 output Play#0 6 0 637
Play#0 input land * Play#0 input land *
Play#0 command land Play#0 command land