fix #H1798 - limbless shopkeepers shouldn't take possessions (trunk only)

From a bug report, a shopkeeper who's been
polymorphed into a limbless creature shouldn't be able to come take your
possessions when you die since you can't pick up items when in that shape.
Rather than add new special case handling for shopkeepers, prevent them
from taking on shapes that render them unable to behave like shopkeepers
so that they can continue to catch thrown pick-axes and assorted other
things that would otherwise need a lot of extra checking introduced.
Ditto for temple priests, vault guards, and quest leaders.  Restriction
also applies to wizard mode use of #monpolycontrol, the only place where
players can actually notice this.

     It could--perhaps should--restrict them even further, forcing forms
that retain speech capability, but I didn't go that far.
This commit is contained in:
nethack.rankin
2009-01-24 22:59:53 +00:00
parent b12d8522c5
commit 1a6289a5ec
2 changed files with 40 additions and 3 deletions

View File

@@ -301,6 +301,7 @@ message sequencing for fatal explosions was confusing if feedback was given
when dipping something in holy/unholy water, only learn its new bless/curse
state if hero sees it glow
describe lit Sunsword as shining rather than glowing
prevent poly'd shopkeepers from taking on forms that can't handle objects
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mon.c 3.5 2008/10/20 */
/* SCCS Id: @(#)mon.c 3.5 2009/01/24 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -22,6 +22,8 @@ STATIC_DCL int NDECL(pick_animal);
STATIC_DCL void FDECL(kill_eggs, (struct obj *));
STATIC_DCL void FDECL(dealloc_mextra, (struct mextra *));
STATIC_DCL int FDECL(pickvampshape, (struct monst *));
STATIC_DCL boolean FDECL(isspecmon, (struct monst *));
STATIC_DCL boolean FDECL(validspecmon, (struct monst *,int));
#ifdef WIZARD
STATIC_DCL boolean FDECL(validvamp, (struct monst *,int *,int));
#endif
@@ -2583,6 +2585,32 @@ struct monst *mon;
return mndx;
}
/* nonshapechangers who warrant special polymorph handling */
STATIC_OVL boolean
isspecmon(mon)
struct monst *mon;
{
return (mon->isshk || mon->ispriest || mon->isgd ||
mon->m_id == quest_status.leader_m_id);
}
/* restrict certain special monsters (shopkeepers, aligned priests,
vault guards) to forms that allow them to behave sensibly (catching
gold, speaking?) so that they don't need too much extra code */
STATIC_OVL boolean
validspecmon(mon, mndx)
struct monst *mon;
int mndx;
{
if (isspecmon(mon) && mndx >= LOW_PM) {
struct permonst *ptr = &mons[mndx];
if (notake(ptr) || nohands(ptr) || !has_head(ptr)) return FALSE;
/* [should we check ptr->msound here too?] */
}
return TRUE; /* potential new form is ok (or still NON_PM) */
}
#ifdef WIZARD
/* prevent wizard mode user from specifying invalid vampshifter shape */
static boolean
@@ -2590,7 +2618,8 @@ validvamp(mon, mndx_p, monclass)
struct monst *mon;
int *mndx_p, monclass;
{
if (!is_vampshifter(mon)) return TRUE; /* simplify caller's usage */
/* simplify caller's usage */
if (!is_vampshifter(mon)) return validspecmon(mon, *mndx_p);
if (*mndx_p == PM_VAMPIRE || *mndx_p == PM_VAMPIRE_LORD ||
*mndx_p == PM_VLAD_THE_IMPALER) {
@@ -2696,13 +2725,20 @@ struct monst *mon;
if (mndx >= LOW_PM && validvamp(mon, &mndx, monclass)) break;
pline("It can't become that.");
mndx = NON_PM;
} while (--tryct > 0);
if (!tryct) pline(thats_enough_tries);
if (is_vampshifter(mon) && !validvamp(mon, &mndx, monclass))
mndx = pickvampshape(mon); /* don't resort to arbitrary */
}
#endif /*WIZARD*/
if (mndx == NON_PM) mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
if (mndx == NON_PM) {
tryct = 50;
do {
mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
} while (--tryct > 0 && !validspecmon(mon, mndx));
}
return mndx;
}