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
|
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)
|
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
|
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
|
tty: turn off an optimization that is the suspected cause of Windows reported
|
||||||
partial status lines following level changes
|
partial status lines following level changes
|
||||||
tty: ensure that current status fields are always copied to prior status
|
tty: ensure that current status fields are always copied to prior status
|
||||||
|
|||||||
+38
-13
@@ -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. */
|
/* Copyright (c) Kevin Hugo, 1998-1999. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ int reason; /* Player was thrown off etc. */
|
|||||||
{
|
{
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
coord cc;
|
coord cc, steedcc;
|
||||||
const char *verb = "fall";
|
const char *verb = "fall";
|
||||||
boolean repair_leg_damage = (Wounded_legs != 0L);
|
boolean repair_leg_damage = (Wounded_legs != 0L);
|
||||||
unsigned save_utrap = u.utrap;
|
unsigned save_utrap = u.utrap;
|
||||||
@@ -548,19 +548,44 @@ int reason; /* Player was thrown off etc. */
|
|||||||
/* Release the steed and saddle */
|
/* Release the steed and saddle */
|
||||||
u.usteed = 0;
|
u.usteed = 0;
|
||||||
u.ugallop = 0L;
|
u.ugallop = 0L;
|
||||||
|
/*
|
||||||
/* Set player and steed's position. Try moving the player first
|
* rloc(), rloc_to(), and monkilled()->mondead()->m_detach() all
|
||||||
unless we're in the midst of creating a bones file. */
|
* expect mtmp to be on the map or else have mtmp->mx be 0, but
|
||||||
if (reason == DISMOUNT_BONES) {
|
* setting the latter to 0 here would interfere with dropping
|
||||||
/* move the steed to an adjacent square */
|
* the saddle. Prior to 3.6.2, being off the map didn't matter.
|
||||||
if (enexto(&cc, u.ux, u.uy, mtmp->data))
|
*
|
||||||
rloc_to(mtmp, cc.x, cc.y);
|
* place_monster() expects mtmp to be alive and not be u.usteed.
|
||||||
else /* evidently no room nearby; move steed elsewhere */
|
*
|
||||||
(void) rloc(mtmp, FALSE);
|
* Unfortunately, <u.ux,u.uy> (former steed's implicit location)
|
||||||
return;
|
* 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)) {
|
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) {
|
if (!u.uswallow && !u.ustuck && have_spot) {
|
||||||
struct permonst *mdat = mtmp->data;
|
struct permonst *mdat = mtmp->data;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user