steed vs "no monster to remove"
Noticed whlie testing the steed-in-pit fix. The EXTRA_SANITY_CHECKS for remove_monster() are being tripped if riding hero has steed killed out from under him because the steed is not on the map. This started out simple but got a bit complicated. It seems to be sufficient but I'm not very confident about it. Being engulfed while mounted gave "placing monster over another?" due to a change made along with EXTRA_SANITY_CHECKS but not conditional on it. (The change was to issue a warning about an actual problem which was previously undiagnosed.) I think bumping the engulfer off the map in favor of the former steed only worked because some u.uswallow code eventually used the hero's location to put the engulfer back. I didn't pursue that to try to figure what really happened, just prevent it. The DISMOUNT_BONES handling was being executed even if the steed was dead. DISMOUNT_BONES only happens if the hero is dead. Since I don't know whether it's possible for dead hero and dead steed to happen at the same time, move it inside the steed-not-dead block just in case.
This commit is contained in:
@@ -246,6 +246,8 @@ ensure tmp_at() structures are initialized for all code paths when swallowed
|
||||
trapped-vs-levitation/flying change broke Sting releasing hero from web
|
||||
life-saving while poly'd and Unchanging wasn't restoring u.mh (HP as monster)
|
||||
change in searching stopped finding unseen monsters except hiders and eels
|
||||
buliding with EXTRA_SANITY_CHECKS enabled would issue "no monster to remove"
|
||||
warning if steed was killed out from under the hero
|
||||
tty: turn off an optimization that is the suspected cause of Windows reported
|
||||
partial status lines following level changes
|
||||
tty: ensure that current status fields are always copied to prior status
|
||||
|
||||
51
src/steed.c
51
src/steed.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 steed.c $NHDT-Date: 1542765364 2018/11/21 01:56:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.57 $ */
|
||||
/* NetHack 3.6 steed.c $NHDT-Date: 1543522486 2018/11/29 20:14:46 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.58 $ */
|
||||
/* Copyright (c) Kevin Hugo, 1998-1999. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -481,7 +481,7 @@ int reason; /* Player was thrown off etc. */
|
||||
{
|
||||
struct monst *mtmp;
|
||||
struct obj *otmp;
|
||||
coord cc;
|
||||
coord cc, steedcc;
|
||||
const char *verb = "fall";
|
||||
boolean repair_leg_damage = (Wounded_legs != 0L);
|
||||
unsigned save_utrap = u.utrap;
|
||||
@@ -548,19 +548,44 @@ int reason; /* Player was thrown off etc. */
|
||||
/* Release the steed and saddle */
|
||||
u.usteed = 0;
|
||||
u.ugallop = 0L;
|
||||
|
||||
/* Set player and steed's position. Try moving the player first
|
||||
unless we're in the midst of creating a bones file. */
|
||||
if (reason == DISMOUNT_BONES) {
|
||||
/* move the steed to an adjacent square */
|
||||
if (enexto(&cc, u.ux, u.uy, mtmp->data))
|
||||
rloc_to(mtmp, cc.x, cc.y);
|
||||
else /* evidently no room nearby; move steed elsewhere */
|
||||
(void) rloc(mtmp, FALSE);
|
||||
return;
|
||||
/*
|
||||
* rloc(), rloc_to(), and monkilled()->mondead()->m_detach() all
|
||||
* expect mtmp to be on the map or else have mtmp->mx be 0, but
|
||||
* setting the latter to 0 here would interfere with dropping
|
||||
* the saddle. Prior to 3.6.2, being off the map didn't matter.
|
||||
*
|
||||
* place_monster() expects mtmp to be alive and not be u.usteed.
|
||||
*
|
||||
* Unfortunately, <u.ux,u.uy> (former steed's implicit location)
|
||||
* might now be occupied by an engulfer, so we can't just put mtmp
|
||||
* at that spot. An engulfer's previous spot will be unoccupied
|
||||
* but we don't know where that was and even if we did, it might
|
||||
* be hostile terrain.
|
||||
*/
|
||||
steedcc.x = u.ux, steedcc.y = u.uy;
|
||||
if (m_at(u.ux, u.uy))
|
||||
(void) enexto(&steedcc, u.ux, u.uy, mtmp->data);
|
||||
if (!m_at(steedcc.x, steedcc.y)) {
|
||||
if (mtmp->mhp < 1)
|
||||
mtmp->mhp = 0; /* make sure it isn't negative */
|
||||
mtmp->mhp++; /* force at least one hit point, possibly resurrecting */
|
||||
place_monster(mtmp, steedcc.x, steedcc.y);
|
||||
mtmp->mhp--; /* take the extra hit point away: cancel resurrection */
|
||||
} else {
|
||||
impossible("Dismounting: can't place former steed on map.");
|
||||
}
|
||||
|
||||
if (!DEADMONSTER(mtmp)) {
|
||||
place_monster(mtmp, u.ux, u.uy);
|
||||
/* Set player and steed's position. Try moving the player first
|
||||
unless we're in the midst of creating a bones file. */
|
||||
if (reason == DISMOUNT_BONES) {
|
||||
/* move the steed to an adjacent square */
|
||||
if (enexto(&cc, u.ux, u.uy, mtmp->data))
|
||||
rloc_to(mtmp, cc.x, cc.y);
|
||||
else /* evidently no room nearby; move steed elsewhere */
|
||||
(void) rloc(mtmp, FALSE);
|
||||
return;
|
||||
}
|
||||
if (!u.uswallow && !u.ustuck && have_spot) {
|
||||
struct permonst *mdat = mtmp->data;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user