fix issue #1046 - unseen monster reading scroll
Reported by copperwater "on behalf of Maud": when hero hears an unseen monster read a not-yet-discovered scroll of create monster and doesn't see any new monster appear, the player is given a chance to call the scroll something. When hearing an unseen monster read a not-yet-discovered scroll of teleportation, the label is revealed but no such 'call it' opportunity is offered, so the player could deduce which of the two scroll types it was for either case. Provide an opportunity to supply a 'called' name for scrolls of teleportation when heard being read, same as with create monster. Surprisingly complicated to achieve. Eliminated a couple of goto's in the process. Fixes #1046
This commit is contained in:
@@ -1199,6 +1199,10 @@ applying a cream pie (always) or lump of royal jelly (sometimes) would use up
|
|||||||
the object and then access its memory after that had been freed
|
the object and then access its memory after that had been freed
|
||||||
keep track of hero's pending movement points across save and restore
|
keep track of hero's pending movement points across save and restore
|
||||||
give feedback if hero sees a monster become hidden under an object or water
|
give feedback if hero sees a monster become hidden under an object or water
|
||||||
|
hero might hear unseen monster read scroll of create monster or scroll of
|
||||||
|
teleportation; when it was create monster, player was given a chance
|
||||||
|
to call it something but not when it was teleportation, allowing the
|
||||||
|
player to deduce which type of scroll it actually was
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||||
|
|||||||
90
src/muse.c
90
src/muse.c
@@ -21,6 +21,7 @@ static void mreadmsg(struct monst *, struct obj *);
|
|||||||
static void mquaffmsg(struct monst *, struct obj *);
|
static void mquaffmsg(struct monst *, struct obj *);
|
||||||
static boolean m_use_healing(struct monst *);
|
static boolean m_use_healing(struct monst *);
|
||||||
static boolean m_sees_sleepy_soldier(struct monst *);
|
static boolean m_sees_sleepy_soldier(struct monst *);
|
||||||
|
static void m_tele(struct monst *, boolean, boolean, int);
|
||||||
static boolean linedup_chk_corpse(coordxy, coordxy);
|
static boolean linedup_chk_corpse(coordxy, coordxy);
|
||||||
static void m_use_undead_turning(struct monst *, struct obj *);
|
static void m_use_undead_turning(struct monst *, struct obj *);
|
||||||
static boolean hero_behind_chokepoint(struct monst *);
|
static boolean hero_behind_chokepoint(struct monst *);
|
||||||
@@ -364,6 +365,29 @@ m_sees_sleepy_soldier(struct monst *mtmp)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
m_tele(
|
||||||
|
struct monst *mtmp, /* monst that might be teleported */
|
||||||
|
boolean vismon, /* can see it */
|
||||||
|
boolean oseen, /* have seen the object that triggered this */
|
||||||
|
int how) /* type of that object */
|
||||||
|
{
|
||||||
|
if (tele_restrict(mtmp)) { /* mysterious force... */
|
||||||
|
if (vismon && how) /* mentions 'teleport' */
|
||||||
|
makeknown(how);
|
||||||
|
/* monster learns that teleportation isn't useful here */
|
||||||
|
if (noteleport_level(mtmp))
|
||||||
|
mon_learns_traps(mtmp, TELEP_TRAP);
|
||||||
|
} else if ((mon_has_amulet(mtmp) || On_W_tower_level(&u.uz)) && !rn2(3)) {
|
||||||
|
if (vismon)
|
||||||
|
pline("%s seems disoriented for a moment.", Monnam(mtmp));
|
||||||
|
} else {
|
||||||
|
if (oseen && how)
|
||||||
|
makeknown(how);
|
||||||
|
(void) rloc(mtmp, RLOC_MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Select a defensive item/action for a monster. Returns TRUE iff one is
|
/* Select a defensive item/action for a monster. Returns TRUE iff one is
|
||||||
found. */
|
found. */
|
||||||
boolean
|
boolean
|
||||||
@@ -683,7 +707,7 @@ find_defensive(struct monst *mtmp, boolean tryescape)
|
|||||||
int
|
int
|
||||||
use_defensive(struct monst *mtmp)
|
use_defensive(struct monst *mtmp)
|
||||||
{
|
{
|
||||||
int i, fleetim, how = 0;
|
int i, fleetim;
|
||||||
struct obj *otmp = gm.m.defensive;
|
struct obj *otmp = gm.m.defensive;
|
||||||
boolean vis, vismon, oseen;
|
boolean vis, vismon, oseen;
|
||||||
const char *Mnam;
|
const char *Mnam;
|
||||||
@@ -734,24 +758,7 @@ use_defensive(struct monst *mtmp)
|
|||||||
return 2;
|
return 2;
|
||||||
m_flee(mtmp);
|
m_flee(mtmp);
|
||||||
mzapwand(mtmp, otmp, TRUE);
|
mzapwand(mtmp, otmp, TRUE);
|
||||||
how = WAN_TELEPORTATION;
|
m_tele(mtmp, vismon, oseen, WAN_TELEPORTATION);
|
||||||
mon_tele:
|
|
||||||
if (tele_restrict(mtmp)) { /* mysterious force... */
|
|
||||||
if (vismon && how) /* mentions 'teleport' */
|
|
||||||
makeknown(how);
|
|
||||||
/* monster learns that teleportation isn't useful here */
|
|
||||||
if (noteleport_level(mtmp))
|
|
||||||
mon_learns_traps(mtmp, TELEP_TRAP);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if ((mon_has_amulet(mtmp) || On_W_tower_level(&u.uz)) && !rn2(3)) {
|
|
||||||
if (vismon)
|
|
||||||
pline("%s seems disoriented for a moment.", Monnam(mtmp));
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if (oseen && how)
|
|
||||||
makeknown(how);
|
|
||||||
(void) rloc(mtmp, RLOC_MSG);
|
|
||||||
return 2;
|
return 2;
|
||||||
case MUSE_WAN_TELEPORTATION:
|
case MUSE_WAN_TELEPORTATION:
|
||||||
gz.zap_oseen = oseen;
|
gz.zap_oseen = oseen;
|
||||||
@@ -769,32 +776,42 @@ use_defensive(struct monst *mtmp)
|
|||||||
if (mtmp->isshk || mtmp->isgd || mtmp->ispriest)
|
if (mtmp->isshk || mtmp->isgd || mtmp->ispriest)
|
||||||
return 2;
|
return 2;
|
||||||
m_flee(mtmp);
|
m_flee(mtmp);
|
||||||
mreadmsg(mtmp, otmp);
|
/* we want to be able to access otmp after the teleport but it
|
||||||
m_useup(mtmp, otmp); /* otmp might be free'ed */
|
might get destroyed if still in mtmp's inventory (maybe mtmp
|
||||||
how = SCR_TELEPORTATION;
|
lands in lava or on a fire trap) so take it out in advance */
|
||||||
|
if (otmp->quan > 1L)
|
||||||
|
otmp = splitobj(otmp, 1L);
|
||||||
|
extract_from_minvent(mtmp, otmp, FALSE, FALSE);
|
||||||
|
/* 'last_msg' will be changed to PLNMSG_UNKNOWN if any messages
|
||||||
|
are issued by mreadmsg(), 'if (vismon) pline()', or m_tele() */
|
||||||
|
iflags.last_msg = PLNMSG_enum;
|
||||||
|
mreadmsg(mtmp, otmp); /* sets otmp->dknown if !Blind or !Deaf */
|
||||||
if (obj_is_cursed || mtmp->mconf) {
|
if (obj_is_cursed || mtmp->mconf) {
|
||||||
int nlev;
|
int nlev;
|
||||||
d_level flev;
|
d_level flev;
|
||||||
|
|
||||||
|
nlev = random_teleport_level();
|
||||||
if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
|
if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
|
||||||
if (vismon)
|
if (vismon)
|
||||||
pline("%s seems very disoriented for a moment.",
|
pline("%s seems very disoriented for a moment.",
|
||||||
Monnam(mtmp));
|
Monnam(mtmp));
|
||||||
return 2;
|
} else if (nlev == depth(&u.uz)) {
|
||||||
}
|
|
||||||
nlev = random_teleport_level();
|
|
||||||
if (nlev == depth(&u.uz)) {
|
|
||||||
if (vismon)
|
if (vismon)
|
||||||
pline("%s shudders for a moment.", Monnam(mtmp));
|
pline("%s shudders for a moment.", Monnam(mtmp));
|
||||||
return 2;
|
} else {
|
||||||
|
get_level(&flev, nlev);
|
||||||
|
migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
|
||||||
|
(coord *) 0);
|
||||||
}
|
}
|
||||||
get_level(&flev, nlev);
|
} else {
|
||||||
migrate_to_level(mtmp, ledger_no(&flev), MIGR_RANDOM,
|
m_tele(mtmp, vismon, oseen, SCR_TELEPORTATION);
|
||||||
(coord *) 0);
|
}
|
||||||
if (oseen)
|
/* m_tele() handles makeknown(); trycall() will be a no-op when
|
||||||
makeknown(SCR_TELEPORTATION);
|
otmp->otyp is already discovered */
|
||||||
} else
|
if (otmp->dknown && iflags.last_msg != PLNMSG_enum)
|
||||||
goto mon_tele;
|
trycall(otmp);
|
||||||
|
/* already removed from mtmp->minvent so not 'm_useup(mtmp, otmp)' */
|
||||||
|
obfree(otmp, (struct obj *) 0);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
case MUSE_WAN_DIGGING: {
|
case MUSE_WAN_DIGGING: {
|
||||||
@@ -1047,8 +1064,9 @@ use_defensive(struct monst *mtmp)
|
|||||||
if (mtmp->wormno)
|
if (mtmp->wormno)
|
||||||
worm_move(mtmp);
|
worm_move(mtmp);
|
||||||
newsym(gt.trapx, gt.trapy);
|
newsym(gt.trapx, gt.trapy);
|
||||||
|
/* 0: 'no object' rather than STRANGE_OBJECT; FALSE: obj not seen */
|
||||||
goto mon_tele;
|
m_tele(mtmp, vismon, FALSE, 0);
|
||||||
|
return 2;
|
||||||
case MUSE_POT_HEALING:
|
case MUSE_POT_HEALING:
|
||||||
mquaffmsg(mtmp, otmp);
|
mquaffmsg(mtmp, otmp);
|
||||||
i = d(6 + 2 * bcsign(otmp), 4);
|
i = d(6 + 2 * bcsign(otmp), 4);
|
||||||
|
|||||||
Reference in New Issue
Block a user