Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-06-01 18:05:42 -04:00
9 changed files with 287 additions and 47 deletions

View File

@@ -125,21 +125,24 @@ Commands:
O Review current options and possibly change them.
A menu displaying the option settings will be displayed
and most can be changed by simply selecting their entry.
Options are usually set before the game with a NETHACKOPTIONS
environment variable, or via a config file (defaults.nh,
NetHack Defaults, nethack.cnf, .nethackrc, etc.), not with
the 'O' command.
Options are usually set before the game with NETHACKOPTIONS
environment variable or via a configuration file (defaults.nh,
NetHack Defaults, nethack.cnf, ~/.nethackrc, etc.) rather
than with the 'O' command.
p Pay your shopping bill.
P Put on an accessory (ring, amulet, etc).
^P Repeat last message (subsequent ^P's repeat earlier messages).
The behavior can be varied via the msg_window option.
q Drink (quaff) something (potion, water, etc).
Q Select ammunition for quiver.
#quit Exit the program without saving the current game.
r Read a scroll or spellbook.
R Remove an accessory (ring, amulet, etc).
^R Redraw the screen.
s Search for secret doors and traps around you.
S Save the game.
S Save the game. Also exits the program.
[To restore, just play again and use the same character name.]
[There is no "save current data but keep playing" capability.]
t Throw an object or shoot a projectile.
T Take off armor.
^T Teleport, if you are able.
@@ -151,9 +154,12 @@ Commands:
x Swap wielded and secondary weapons.
X Toggle two-weapon combat.
^X Show your attributes.
#explore Switch to Explore Mode (aka Discovery Mode) where dying and
deleting the save file during restore can both be overridden.
z Zap a wand. (Use y instead of z if number_pad is -1.)
Z Cast a spell. (Use Y instead of Z if number_pad is -1.)
^Z Suspend the game. (^Y instead of ^Z if number_pad is -1.)
[To resume, use the shell command 'fg'.]
: Look at what is here.
; Look at what is somewhere else.
, Pick up some things.
@@ -170,6 +176,7 @@ Commands:
\ Show what types of objects have been discovered.
` Show discovered types for one class of objects.
! Escape to a shell, if supported in your version and OS.
[To resume play, terminate the shell subprocess via 'exit'.]
# Introduces one of the "extended" commands. To get a list of
the commands you can use with "#" type "#?". The extended
commands you can use depends upon what options the game was
@@ -192,7 +199,7 @@ Commands:
u Untrap a trapped object or door.
You can put a number before a command to repeat it that many times,
as in "40." or "20s.". If you have the number_pad option set, you
as in "40." or "20s". If you have the number_pad option set, you
must type 'n' to prefix the count, as in "n40." or "n20s".

4
dat/hh
View File

@@ -25,8 +25,10 @@ General commands:
? help display one of several informative texts
#quit quit end the game without saving current game
S save save the game (to be continued later) and exit
! sh escape to some SHELL (if allowed)
[to restore, play again and use the same character name]
! sh escape to some SHELL (if allowed; 'exit' to resume play)
^Z suspend suspend the game (independent of your current suspend char)
[on UNIX(tm)-based systems, use the 'fg' command to resume]
O options set options
/ what-is tell what a map symbol represents
\ known display list of what's been discovered

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.29 $ $NHDT-Date: 1559313320 2019/05/31 14:35:20 $
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.31 $ $NHDT-Date: 1559422205 2019/06/01 20:50:05 $
This fixes36.3 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -35,6 +35,9 @@ fix a memory leak that occurred if player used wizard mode to leave and return
free sortloot data if object handling is short-circuited by cockatrice corpse
on the Plane of Water, make water go all the way to the edges of the level
on the Plane of Air, make clouds disrupt line of sight along the edges
have '&' (whatdoes) command describe movement keystrokes instead of reporting
them as unknown or showing their number_pad action when that is Off
some improvement to the handling of endgame levels filling up with monsters
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1558485640 2019/05/22 00:40:40 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.706 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1559422206 2019/06/01 20:50:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.707 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1391,6 +1391,7 @@ E int FDECL(can_carry, (struct monst *, struct obj *));
E int FDECL(mfndpos, (struct monst *, coord *, long *, long));
E boolean FDECL(monnear, (struct monst *, int, int));
E void NDECL(dmonsfree);
E void FDECL(elemental_clog, (struct monst *));
E int FDECL(mcalcmove, (struct monst *));
E void NDECL(mcalcdistress);
E void FDECL(replmon, (struct monst *, struct monst *));

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monst.h $NHDT-Date: 1550524559 2019/02/18 21:15:59 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.28 $ */
/* NetHack 3.6 monst.h $NHDT-Date: 1559422218 2019/06/01 20:50:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.31 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2016. */
/* NetHack may be freely redistributed. See license for details. */
@@ -50,6 +50,17 @@ enum m_ap_types {
M_AP_MONSTER = 3 /* a monster; mostly used for cloned Wizard */
};
#define MON_FLOOR 0x00
#define MON_OFFMAP 0x01
#define MON_DETACH 0x02
#define MON_MIGRATING 0x04
#define MON_LIMBO 0x08
#define MON_BUBBLEMOVE 0x10
#define MON_ENDGAME_FREE 0x20
#define MON_ENDGAME_MIGR 0x40
#define MON_OBLITERATE 0x80
#define MSTATE_MASK 0xFF
#define M_AP_TYPMASK 0x7
#define M_AP_F_DKNOWN 0x8
#define U_AP_TYPE (g.youmonst.m_ap_type & M_AP_TYPMASK)
@@ -149,8 +160,8 @@ struct monst {
long mtrapseen; /* bitmap of traps we've been trapped in */
long mlstmv; /* for catching up with lost time */
long mspare1;
#define mstate mspare1 /* only for debug exam right now, not code flow */
struct obj *minvent; /* mon's inventory */
struct obj *mw; /* mon's weapon */
long misc_worn_check; /* mon's wornmask */
xchar weapon_check; /* flag for whether to try switching weapons */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1557088405 2019/05/05 20:33:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */
/* NetHack 3.6 cmd.c $NHDT-Date: 1559382745 2019/06/01 09:52:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.335 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -23,6 +23,9 @@
#define C(c) (0x1f & (c))
#endif
#define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
#define unmeta(c) (0x7f & (c))
#ifdef ALTMETA
STATIC_VAR boolean alt_esc = FALSE;
#endif
@@ -3444,14 +3447,71 @@ struct ext_func_tab extcmdlist[] = {
{ '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
};
/* for key2extcmddesc() to support dowhatdoes() */
struct movcmd {
uchar k1, k2, k3, k4; /* 'normal', 'qwertz', 'numpad', 'phone' */
const char *txt, *alt; /* compass direction, screen direction */
};
static const struct movcmd movtab[] = {
{ 'h', 'h', '4', '4', "west", "left" },
{ 'j', 'j', '2', '8', "south", "down" },
{ 'k', 'k', '8', '2', "north", "up" },
{ 'l', 'l', '6', '6', "east", "right" },
{ 'b', 'b', '1', '7', "southwest", "lower left" },
{ 'n', 'n', '3', '9', "southeast", "lower right" },
{ 'u', 'u', '9', '3', "northeast", "upper right" },
{ 'y', 'z', '7', '1', "northwest", "upper left" },
{ 0, 0, 0, 0, (char *) 0, (char *) 0 }
};
int extcmdlist_length = SIZE(extcmdlist) - 1;
const char *
key2extcmddesc(key)
uchar key;
{
if (g.Cmd.commands[key] && g.Cmd.commands[key]->ef_txt)
return g.Cmd.commands[key]->ef_desc;
static char key2cmdbuf[48];
const struct movcmd *mov;
int k, c;
uchar M_5 = (uchar) M('5'), M_0 = (uchar) M('0');
/* need to check for movement commands before checking the extended
commands table because it contains entries for number_pad commands
that match !number_pad movement (like 'j' for "jump") */
key2cmdbuf[0] = '\0';
if (movecmd(k = key))
Strcpy(key2cmdbuf, "move"); /* "move or attack"? */
else if (movecmd(k = unctrl(key)))
Strcpy(key2cmdbuf, "rush");
else if (movecmd(k = (g.Cmd.num_pad ? unmeta(key) : lowc(key))))
Strcpy(key2cmdbuf, "run");
if (*key2cmdbuf) {
for (mov = &movtab[0]; mov->k1; ++mov) {
c = !g.Cmd.num_pad ? (!g.Cmd.swap_yz ? mov->k1 : mov->k2)
: (!g.Cmd.phone_layout ? mov->k3 : mov->k4);
if (c == k) {
Sprintf(eos(key2cmdbuf), " %s (screen %s)",
mov->txt, mov->alt);
return key2cmdbuf;
}
}
} else if (digit(key) || (g.Cmd.num_pad && digit(unmeta(key)))) {
key2cmdbuf[0] = '\0';
if (!g.Cmd.num_pad)
Strcpy(key2cmdbuf, "start of, or continuation of, a count");
else if (key == '5' || key == M_5)
Sprintf(key2cmdbuf, "%s prefix",
(!!g.Cmd.pcHack_compat ^ (key == M_5)) ? "run" : "rush");
else if (key == '0' || (g.Cmd.pcHack_compat && key == M_0))
Strcpy(key2cmdbuf, "synonym for 'i'");
if (*key2cmdbuf)
return key2cmdbuf;
}
if (g.Cmd.commands[key]) {
if (g.Cmd.commands[key]->ef_txt)
return g.Cmd.commands[key]->ef_desc;
}
return (char *) 0;
}
@@ -4122,9 +4182,6 @@ wiz_migrate_mons()
}
#endif
#define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
#define unmeta(c) (0x7f & (c))
struct {
int nhkf;
char key;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mkmaze.c $NHDT-Date: 1559299316 2019/05/31 10:41:56 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.73 $ */
/* NetHack 3.6 mkmaze.c $NHDT-Date: 1559422240 2019/06/01 20:50:40 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.74 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2018. */
/* NetHack may be freely redistributed. See license for details. */
@@ -644,14 +644,14 @@ unsigned long mflags;
/* once in a blue moon, he won't be at the very bottom */
if (!rn2(40))
nlev--;
mtmp->mspare1 = MIGR_LEFTOVERS;
mtmp->mspare1 |= MIGR_LEFTOVERS;
} else {
nlev = rn2((max_depth - cur_depth) + 1) + cur_depth;
if (nlev == cur_depth)
nlev++;
if (nlev > max_depth)
nlev = max_depth;
mtmp->mspare1 = 0L;
mtmp->mspare1 = (mtmp->mspare1 & ~MIGR_LEFTOVERS);
}
get_level(&dest, nlev);
migrate_to_level(mtmp, ledger_no(&dest), MIGR_RANDOM, (coord *) 0);
@@ -1456,6 +1456,7 @@ movebubbles()
newsym(x, y); /* clean up old position */
mon->mx = mon->my = 0;
mon->mstate |= MON_BUBBLEMOVE;
}
if (!u.uswallow && x == u.ux && y == u.uy) {
cons = (struct container *) alloc(sizeof *cons);
@@ -1887,12 +1888,10 @@ boolean ini;
case CONS_MON: {
struct monst *mon = (struct monst *) cons->list;
/* mnearto() might fail, and putting the monster into limbo
to try next time hero comes to this level makes no sense
because we can't leave and return (outside wizard mode) */
if (!mnearto(mon, cons->x, cons->y, TRUE)) {
; /* ? */
}
/* mnearto() might fail. We can jump right to elemental_clog
from here rather than deal_with_overcrowding() */
if (!mnearto(mon, cons->x, cons->y, TRUE))
elemental_clog(mon);
break;
}

178
src/mon.c
View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1559227828 2019/05/30 14:50:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.286 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1559422247 2019/06/01 20:50:47 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.287 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -26,6 +26,9 @@ STATIC_DCL struct permonst *FDECL(accept_newcham_form, (int));
STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
STATIC_DCL void FDECL(migrate_mon, (struct monst *, XCHAR_P, XCHAR_P));
STATIC_DCL boolean FDECL(ok_to_obliterate, (struct monst *));
STATIC_DCL void FDECL(deal_with_overcrowding, (struct monst *));
/* note: duplicated in dog.c */
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
@@ -612,7 +615,8 @@ register struct monst *mtmp;
xkilled(mtmp, XKILL_NOMSG);
if (!DEADMONSTER(mtmp)) {
water_damage_chain(mtmp->minvent, FALSE);
(void) rloc(mtmp, FALSE);
if (!rloc(mtmp, TRUE))
deal_with_overcrowding(mtmp);
return 0;
}
return 1;
@@ -1599,7 +1603,9 @@ dmonsfree()
{
struct monst **mtmp, *freetmp;
int count = 0;
char buf[QBUFSZ];
buf[0] = '\0';
for (mtmp = &fmon; *mtmp;) {
freetmp = *mtmp;
if (DEADMONSTER(freetmp) && !freetmp->isgd) {
@@ -1611,9 +1617,11 @@ dmonsfree()
mtmp = &(freetmp->nmon);
}
if (count != iflags.purge_monsters)
impossible("dmonsfree: %d removed doesn't match %d pending",
count, iflags.purge_monsters);
if (count != iflags.purge_monsters) {
describe_level(buf);
impossible("dmonsfree: %d removed doesn't match %d pending on %s",
count, iflags.purge_monsters, buf);
}
iflags.purge_monsters = 0;
}
@@ -1789,8 +1797,13 @@ void
dealloc_monst(mon)
struct monst *mon;
{
if (mon->nmon)
panic("dealloc_monst with nmon");
char buf[QBUFSZ];
buf[0] = '\0';
if (mon->nmon) {
describe_level(buf);
panic("dealloc_monst with nmon on %s", buf);
}
if (mon->mextra)
dealloc_mextra(mon);
free((genericptr_t) mon);
@@ -1832,6 +1845,11 @@ struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
shkgone(mtmp);
if (mtmp->wormno)
wormgone(mtmp);
if (In_endgame(&u.uz)) {
mtmp->mx = mtmp->my = 0;
mtmp->mstate |= MON_ENDGAME_FREE;
}
mtmp->mstate |= MON_DETACH;
iflags.purge_monsters++;
}
@@ -2571,10 +2589,121 @@ struct monst *mtmp;
void
m_into_limbo(mtmp)
struct monst *mtmp;
{
xchar target_lev = ledger_no(&u.uz), xyloc = MIGR_APPROX_XY;
mtmp->mstate |= MON_LIMBO;
migrate_mon(mtmp, target_lev, xyloc);
}
STATIC_OVL void
migrate_mon(mtmp, target_lev, xyloc)
struct monst *mtmp;
xchar target_lev, xyloc;
{
unstuck(mtmp);
mdrop_special_objs(mtmp);
migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_APPROX_XY, (coord *) 0);
migrate_to_level(mtmp, target_lev, xyloc, (coord *) 0);
mtmp->mstate |= MON_MIGRATING;
}
STATIC_OVL boolean
ok_to_obliterate(mtmp)
struct monst *mtmp;
{
/*
* Add checks for monsters that should not be obliterated
* here (return FALSE).
*/
if (mtmp->data == &mons[PM_WIZARD_OF_YENDOR] || is_rider(mtmp->data)
|| has_emin(mtmp) || has_epri(mtmp) || has_eshk(mtmp))
return FALSE;
return TRUE;
}
void
elemental_clog(mon)
struct monst *mon;
{
int m_lev = 0;
static long msgmv = 0L;
struct monst *mtmp, *m1, *m2, *m3, *m4, *m5, *zm;
if (In_endgame(&u.uz)) {
m1 = m2 = m3 = m4 = m5 = zm = (struct monst *) 0;
if (!msgmv || (g.moves - msgmv) > 200L) {
if (!msgmv || rn2(2))
You("feel besieged.");
msgmv = g.moves;
}
/*
* m1 an elemental from another plane.
* m2 an elemental from this plane.
* m3 the least powerful monst encountered in loop so far.
* m4 some other non-tame monster.
* m5 a pet.
*/
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp))
continue;
if (mtmp->mx == 0 && mtmp->my == 0)
continue;
if (mon_has_amulet(mtmp) || !ok_to_obliterate(mtmp))
continue;
if (mtmp->data->mlet == S_ELEMENTAL) {
if (!is_home_elemental(mtmp->data)) {
if (!m1)
m1 = mtmp;
} else {
if (!m2)
m2 = mtmp;
}
} else {
if (!mtmp->mtame) {
if (!m_lev || mtmp->m_lev < m_lev) {
m_lev = mtmp->m_lev;
m3 = mtmp;
} else if (!m4) {
m4 = mtmp;
}
} else {
if (!m5)
m5 = mtmp;
break;
}
}
}
mtmp = m1 ? m1 : m2 ? m2 : m3 ? m3 : m4 ? m4 : m5 ? m5 : zm;
if (mtmp) {
int mx = mtmp->mx, my = mtmp->my;
mtmp->mstate |= MON_OBLITERATE;
mongone(mtmp);
mtmp->mx = mtmp->my = 0;
rloc_to(mon, mx, my);
} else {
/* last resort - migrate mon to the next plane */
if (Is_waterlevel(&u.uz) || Is_firelevel(&u.uz) || Is_earthlevel(&u.uz)) {
/* try sending mon on to the next plane */
xchar target_lev = 0, xyloc = 0;
struct trap *trap = g.ftrap;
while (trap) {
if (trap->ttyp == MAGIC_PORTAL)
break;
trap = trap->ntrap;
}
if (trap) {
target_lev = ledger_no(&trap->dst);
xyloc = MIGR_RANDOM;
}
if (target_lev) {
mon->mstate |= MON_ENDGAME_MIGR;
migrate_mon(mon, target_lev, xyloc);
}
}
}
}
}
/* make monster mtmp next to you (if possible);
@@ -2594,8 +2723,7 @@ struct monst *mtmp;
}
if (!enexto(&mm, u.ux, u.uy, mtmp->data) || !isok(mm.x, mm.y)) {
debugpline1("mnexto: sending %s into limbo", m_monnam(mtmp));
m_into_limbo(mtmp);
deal_with_overcrowding(mtmp);
return;
}
rloc_to(mtmp, mm.x, mm.y);
@@ -2608,6 +2736,19 @@ struct monst *mtmp;
return;
}
void
deal_with_overcrowding(mtmp)
struct monst *mtmp;
{
if (In_endgame(&u.uz)) {
debugpline1("overcrowding: elemental_clog on %s", m_monnam(mtmp));
elemental_clog(mtmp);
} else {
debugpline1("overcrowding: sending %s into limbo", m_monnam(mtmp));
m_into_limbo(mtmp);
}
}
/* like mnexto() but requires destination to be directly accessible */
void
maybe_mnexto(mtmp)
@@ -2662,6 +2803,7 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
remove_monster(x, y);
othermon->mx = othermon->my = 0; /* 'othermon' is not on the map */
othermon->mstate |= MON_OFFMAP;
}
newx = x;
@@ -2671,8 +2813,16 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
* Migrating_mons that need to be placed will cause
* no end of trouble.
*/
if (!enexto(&mm, newx, newy, mtmp->data) || !isok(mm.x, mm.y))
if (!enexto(&mm, newx, newy, mtmp->data) || !isok(mm.x, mm.y)) {
if (othermon) {
/* othermon already had its mx, my set to 0 above
* and this would shortly cause a sanity check to fail
* if we just return 0 here. The caller only possesses
* awareness of mtmp, not othermon. */
deal_with_overcrowding(othermon);
}
return 0;
}
newx = mm.x;
newy = mm.y;
}
@@ -2680,10 +2830,8 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
if (move_other && othermon) {
res = 2; /* moving another monster out of the way */
if (!mnearto(othermon, x, y, FALSE)) { /* no 'move_other' this time */
debugpline1("mnearto: sending %s into limbo", m_monnam(othermon));
m_into_limbo(othermon);
}
if (!mnearto(othermon, x, y, FALSE)) /* no 'move_other' this time */
deal_with_overcrowding(othermon);
}
return res;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 steed.c $NHDT-Date: 1545441042 2018/12/22 01:10:42 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.62 $ */
/* NetHack 3.6 steed.c $NHDT-Date: 1559422254 2019/06/01 20:50:54 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.64 $ */
/* Copyright (c) Kevin Hugo, 1998-1999. */
/* NetHack may be freely redistributed. See license for details. */
@@ -742,23 +742,35 @@ place_monster(mon, x, y)
struct monst *mon;
int x, y;
{
char buf[QBUFSZ];
buf[0] = '\0';
/* normal map bounds are <1..COLNO-1,0..ROWNO-1> but sometimes
vault guards (either living or dead) are parked at <0,0> */
if (!isok(x, y) && (x != 0 || y != 0 || !mon->isgd)) {
impossible("trying to place monster at <%d,%d>", x, y);
describe_level(buf);
impossible("trying to place monster at <%d,%d> mstate:%lx on %s",
x, y, mon->mstate, buf);
x = y = 0;
}
if (mon == u.usteed
/* special case is for convoluted vault guard handling */
|| (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
impossible("placing %s onto map?",
(mon == u.usteed) ? "steed" : "defunct monster");
describe_level(buf);
impossible("placing %s onto map, mstate:%lx, on %s?",
(mon == u.usteed) ? "steed" : "defunct monster",
mon->mstate, buf);
return;
}
if (g.level.monsters[x][y])
impossible("placing monster over another at <%d,%d>?", x, y);
if (g.level.monsters[x][y]) {
describe_level(buf);
impossible("placing monster over another at <%d,%d>, mstates:%lx %lx on %s?",
x, y, g.level.monsters[x][y]->mstate, mon->mstate, buf);
}
mon->mx = x, mon->my = y;
g.level.monsters[x][y] = mon;
mon->mstate &= ~(MON_OFFMAP | MON_MIGRATING | MON_LIMBO | MON_BUBBLEMOVE
| MON_ENDGAME_FREE | MON_ENDGAME_MIGR);
}
/*steed.c*/