probing while swallowed (trunk only)

Reported recently by <Someone>:  probing feedback while engulfed
shouldn't claim that the monster is not carrying anything when the hero
is inside of it.  The simple case where it's not carrying anything else
was a trivial one line change; handling inventory plus hero was trickier
and I wouldn't have bothered if I'd realized what it was going to take.
But it's done now; trivial case
        The purple worm is not carrying anything besides you.
and harder case
        The purple worm's possessions:
        Weapons
        a - an uncursed dagger
        Swallowed Creature
        > - human archeologist called wizard
This commit is contained in:
nethack.rankin
2008-03-21 03:12:14 +00:00
parent 5c053b12dd
commit 17f63949bc
7 changed files with 102 additions and 51 deletions

View File

@@ -284,6 +284,7 @@ reprompt if player fails to make a menu choice during inventory identification
seen eels who were stuck in isolated pools would never re-hide
can no longer get both strength and resistance from eating one giant corpse
aborting key/lock pick usage via ESC at direction prompt no longer use a move
when probing from inside an engulfer, "not carrying anything" overlooked hero
Platform- and/or Interface-Specific Fixes

View File

@@ -1614,6 +1614,7 @@ E void NDECL(set_playmode);
/* ### pager.c ### */
E char *FDECL(self_lookat, (char *));
E int NDECL(dowhatis);
E int NDECL(doquickwhatis);
E int NDECL(doidtrap);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)hack.h 3.5 2008/02/15 */
/* SCCS Id: @(#)hack.h 3.5 2008/03/19 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -223,6 +223,7 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */
#define SIGNAL_NOMENU 0x10 /* return -1 rather than 0 if none allowed */
#define SIGNAL_ESCAPE 0x20 /* return -2 rather than 0 for ESC */
#define FEEL_COCKATRICE 0x40 /* engage cockatrice checks and react */
#define INCLUDE_HERO 0x80 /* show hero among engulfer's inventory */
/* Flags to control query_category() */
/* BY_NEXTHERE used by query_category() too, so skip 0x01 */

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)invent.c 3.5 2008/02/15 */
/* SCCS Id: @(#)invent.c 3.5 2008/03/19 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3166,22 +3166,20 @@ char *title;
char tmp[QBUFSZ];
int n;
menu_item *selected = 0;
#ifndef GOLDOBJ
int do_all = (dflags & MINV_ALL) != 0,
do_gold = (do_all && mon->mgold);
incl_hero = (do_all && u.uswallow && mon == u.ustuck),
#ifndef GOLDOBJ
do_gold = (do_all && mon->mgold),
have_inv = (mon->minvent || do_gold),
#else
int do_all = (dflags & MINV_ALL) != 0;
have_inv = (mon->minvent != 0),
#endif
have_any = (have_inv || incl_hero);
Sprintf(tmp,"%s %s:", s_suffix(noit_Monnam(mon)),
do_all ? "possessions" : "armament");
#ifndef GOLDOBJ
if (do_all ? (mon->minvent || mon->mgold)
#else
if (do_all ? (mon->minvent != 0)
#endif
: (mon->misc_worn_check || MON_WEP(mon))) {
if (do_all ? have_any : (mon->misc_worn_check || MON_WEP(mon))) {
/* Fool the 'weapon in hand' routine into
* displaying 'weapon in claw', etc. properly.
*/
@@ -3205,9 +3203,11 @@ char *title;
}
#endif
n = query_objlist(title ? title : tmp, mon->minvent, INVORDER_SORT, &selected,
(dflags & MINV_NOLET) ? PICK_NONE : PICK_ONE,
do_all ? allow_all : worn_wield_only);
n = query_objlist(title ? title : tmp, mon->minvent,
INVORDER_SORT | (incl_hero ? INCLUDE_HERO : 0),
&selected,
(dflags & MINV_NOLET) ? PICK_NONE : PICK_ONE,
do_all ? allow_all : worn_wield_only);
#ifndef GOLDOBJ
if (do_gold) obj_extract_self(&m_gold);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)pager.c 3.5 2008/01/30 */
/* SCCS Id: @(#)pager.c 3.5 2008/03/19 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -49,6 +49,28 @@ append_str(buf, new_str)
return 1;
}
/* shared by monster probing (via query_objlist!) as well as lookat() */
char *
self_lookat(outbuf)
char *outbuf;
{
char race[QBUFSZ];
/* include race with role unless polymorphed */
race[0] = '\0';
if (!Upolyd)
Sprintf(race, "%s ", urace.adj);
Sprintf(outbuf, "%s%s%s called %s",
/* being blinded may hide invisibility from self */
(Invis && (senseself() || !Blind)) ? "invisible " : "",
race, mons[u.umonnum].mname, plname);
#ifdef STEED
if (u.usteed)
Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
#endif
return outbuf;
}
/*
* Return the name of the glyph found at (x,y).
* If not hallucinating and the glyph is a monster, also monster data.
@@ -65,35 +87,15 @@ lookat(x, y, buf, monbuf)
buf[0] = monbuf[0] = 0;
glyph = glyph_at(x,y);
if (u.ux == x && u.uy == y && canspotself()) {
char race[QBUFSZ];
/* fill in buf[] */
(void)self_lookat(buf);
/* if not polymorphed, show both the role and the race */
race[0] = 0;
if (!Upolyd) {
Sprintf(race, "%s ", urace.adj);
}
Sprintf(buf, "%s%s%s called %s",
/* being blinded may hide invisibility from self */
(Invis && (senseself() || !Blind)) ? "invisible " : "",
race,
mons[u.umonnum].mname,
plname);
/* file lookup can't distinguish between "gnomish wizard" monster
and correspondingly named player character, always picking the
former; force it to find the general "wizard" entry instead */
if (Role_if(PM_WIZARD) && Race_if(PM_GNOME) && !Upolyd)
pm = &mons[PM_WIZARD];
#ifdef STEED
if (u.usteed) {
char steedbuf[BUFSZ];
Sprintf(steedbuf, ", mounted on %s", y_monnam(u.usteed));
/* assert((sizeof buf >= strlen(buf)+strlen(steedbuf)+1); */
Strcat(buf, steedbuf);
}
#endif
/* When you see yourself normally, no explanation is appended
(even if you could also see yourself via other means).
Sensing self while blind or swallowed is treated as if it

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)pickup.c 3.5 2008/02/15 */
/* SCCS Id: @(#)pickup.c 3.5 2008/03/19 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -8,6 +8,8 @@
#include "hack.h"
#define CONTAINED_SYM '>' /* from invent.c */
STATIC_DCL void FDECL(simple_look, (struct obj *,BOOLEAN_P));
#ifndef GOLDOBJ
STATIC_DCL boolean FDECL(query_classes, (char *,boolean *,boolean *,
@@ -716,6 +718,7 @@ menu_item **pick_list; /* list of objects and counts to pick up */
* use it.
* USE_INVLET - Use object's invlet.
* INVORDER_SORT - Use hero's pack order.
* INCLUDE_HERO - Showing engulfer's invent; show hero too.
* SIGNAL_NOMENU - Return -1 rather than 0 if nothing passes "allow".
* SIGNAL_ESCAPE - Return -1 rather than 0 if player uses ESC to
* pick nothing.
@@ -731,13 +734,15 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
{
int n;
winid win;
struct obj *curr, *last;
struct obj *curr, *last, fake_hero_object;
char *pack;
anything any;
boolean printed_type_name;
boolean printed_type_name,
sorted = (qflags & INVORDER_SORT) != 0,
engulfer = (qflags & INCLUDE_HERO) != 0;
*pick_list = (menu_item *) 0;
if (!olist) return 0;
if (!olist && !engulfer) return 0;
/* count the number of items allowed */
for (n = 0, last = 0, curr = olist; curr; curr = FOLLOW(curr, qflags))
@@ -746,6 +751,12 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
n++;
}
if (engulfer) {
++n;
/* don't autoselect swallowed hero if it's the only choice */
qflags &= ~AUTOSELECT_SINGLE;
}
if (n == 0) /* nothing to pick here */
return (qflags & SIGNAL_NOMENU) ? -1 : 0;
@@ -776,11 +787,10 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
(void) look_here(0, FALSE);
return 0;
}
if ((!(qflags & INVORDER_SORT) || curr->oclass == *pack)
&& (*allow)(curr)) {
if ((!sorted || curr->oclass == *pack) && (*allow)(curr)) {
/* if sorting, print type name (once only) */
if (qflags & INVORDER_SORT && !printed_type_name) {
if (sorted && !printed_type_name) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
let_to_name(*pack, FALSE), MENU_UNSELECTED);
@@ -789,13 +799,32 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
any.a_obj = curr;
add_menu(win, obj_to_glyph(curr), &any,
qflags & USE_INVLET ? curr->invlet : 0,
(qflags & USE_INVLET) ? curr->invlet : 0,
def_oc_syms[(int)objects[curr->otyp].oc_class].sym,
ATR_NONE, doname(curr), MENU_UNSELECTED);
}
}
pack++;
} while (qflags & INVORDER_SORT && *pack);
} while (sorted && *pack);
if (engulfer) {
char buf[BUFSZ];
any = zeroany;
if (sorted && n > 1) {
Sprintf(buf, "%s Creature",
is_animal(u.ustuck->data) ? "Swallowed" : "Engulfed");
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
buf, MENU_UNSELECTED);
}
fake_hero_object = zeroobj;
fake_hero_object.quan = 1L; /* not strictly necessary... */
any.a_obj = &fake_hero_object;
add_menu(win, mon_to_glyph(&youmonst), &any,
/* fake inventory letter, no group accelerator */
CONTAINED_SYM, 0,
ATR_NONE, self_lookat(buf), MENU_UNSELECTED);
}
end_menu(win, qstr);
n = select_menu(win, how, pick_list);
@@ -803,12 +832,28 @@ boolean FDECL((*allow), (OBJ_P));/* allow function */
if (n > 0) {
menu_item *mi;
int i;
int i, k;
/* fix up counts: -1 means no count used => pick all */
for (i = 0, mi = *pick_list; i < n; i++, mi++)
/* fix up counts: -1 means no count used => pick all;
if fake_hero_object was picked, discard that choice */
for (i = k = 0, mi = *pick_list; i < n; i++, mi++) {
if (mi->item.a_obj == &fake_hero_object) continue;
if (mi->count == -1L || mi->count > mi->item.a_obj->quan)
mi->count = mi->item.a_obj->quan;
if (k < i) (*pick_list)[k] = *mi;
++k;
}
if (!k) {
/* fake_hero was only choice so discard whole list */
free((genericptr_t) *pick_list);
*pick_list = 0;
n = 0;
} else if (k < n) {
/* other stuff plus fake_hero; last slot is now unused */
(*pick_list)[k].item = zeroany;
(*pick_list)[k].count = 0L;
n = k;
}
} else if (n < 0) {
/* -1 is used for SIGNAL_NOMENU, so callers don't expect it
to indicate that the player declined to make a choice */

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)zap.c 3.5 2008/01/19 */
/* SCCS Id: @(#)zap.c 3.5 2008/03/19 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -450,7 +450,8 @@ struct monst *mtmp;
}
(void) display_minventory(mtmp, MINV_ALL|MINV_NOLET, (char *)0);
} else {
pline("%s is not carrying anything.", noit_Monnam(mtmp));
pline("%s is not carrying anything%s.", noit_Monnam(mtmp),
(u.uswallow && mtmp == u.ustuck) ? " besides you" : "");
}
}