From 906818f5cbab69438778cf2f101eb539927ebb0a Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 19 Mar 2018 17:59:24 -0700 Subject: [PATCH] wishing for containers Noticed while investigating the broken chest whose lock was already broken: wishing for locked, unlocked, or broken chest (or large box) was treated as asking for something unknown. Add support for those three prefixes, although they only have meaning for chest and box. If more that one is specified in the same wish, whichever one comes last overrides the others. Also, "empty" was already an accepted prefix (for tins); honor it for containers too. Lastly, wishing for "box" failed. Give a large box instead. I went back and forth about whether to do the same for "small box" and ended up not including it, but turns out that small/medium/large prefix for globs ends up making "small box" and "medium box" match "box" which has now become a synonym for "large box". I'm not sure whether that is a bonus or a bug; small box is clearly not the same thing as large box, but getting the only available box when asking for any box seems better than claiming not to understand the request. --- doc/fixes36.1 | 2 ++ src/objnam.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 5fb21cb77..f48947ce9 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -530,6 +530,8 @@ open at yourself is the same as #loot when #force reports that a chest's lock is already broken or already unlocked, force it to be described as "a chest", even when its lock state is already known, rather than as "a broken chest" or "an unlocked chest" +honor wish for "locked", "unlocked", or "broken" chest or box +honor wish for "empty" container including statue, bag-o-tricks, horn-o-plenty Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/objnam.c b/src/objnam.c index 120aaef55..5eb969e42 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1521377345 2018/03/18 12:49:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.194 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1521507553 2018/03/20 00:59:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.199 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2670,6 +2670,8 @@ struct alt_spellings { { "grapnel", GRAPPLING_HOOK }, { "grapple", GRAPPLING_HOOK }, { "protection from shape shifters", RIN_PROTECTION_FROM_SHAPE_CHAN }, + /* if we ever add other sizes, move this to o_ranges[] with "bag" */ + { "box", LARGE_BOX }, /* normally we wouldn't have to worry about unnecessary , but " stone" will get stripped off, preventing a wishymatch; that actually lets "flint stone" be a match, so we also accept bogus "flintstone" */ @@ -2763,7 +2765,7 @@ struct obj *no_wish; register struct obj *otmp; int cnt, spe, spesgn, typ, very, rechrg; int blessed, uncursed, iscursed, ispoisoned, isgreased; - int eroded, eroded2, erodeproof; + int eroded, eroded2, erodeproof, locked, unlocked, broken; int halfeaten, mntmp, contents; int islit, unlabeled, ishistoric, isdiluted, trapped; int tmp, tinv, tvariety; @@ -2789,9 +2791,11 @@ struct obj *no_wish; char *un, *dn, *actualn, *origbp = bp; const char *name = 0; - cnt = spe = spesgn = typ = very = rechrg = blessed = uncursed = iscursed = - ispoisoned = isgreased = eroded = eroded2 = erodeproof = halfeaten = - islit = unlabeled = ishistoric = isdiluted = trapped = 0; + cnt = spe = spesgn = typ = 0; + very = rechrg = blessed = uncursed = iscursed = ispoisoned = + isgreased = eroded = eroded2 = erodeproof = halfeaten = + islit = unlabeled = ishistoric = isdiluted = trapped = + locked = unlocked = broken = 0; tvariety = RANDOM_TIN; mntmp = NON_PM; #define UNDEFINED 0 @@ -2879,6 +2883,13 @@ struct obj *no_wish; trapped = 1; } else if (!strncmpi(bp, "untrapped ", l = 10)) { trapped = 2; /* not trapped */ + /* locked, unlocked, broken: box/chest lock states */ + } else if (!strncmpi(bp, "locked ", l = 7)) { + locked = 1, unlocked = broken = 0; + } else if (!strncmpi(bp, "unlocked ", l = 9)) { + unlocked = 1, locked = broken = 0; + } else if (!strncmpi(bp, "broken ", l = 7)) { + broken = 1, locked = unlocked = 0; } else if (!strncmpi(bp, "greased ", l = 8)) { isgreased = 1; } else if (!strncmpi(bp, "very ", l = 5)) { @@ -3284,7 +3295,10 @@ retry: ; /* avoid false hit on "* glass" */ } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) { register char *g = bp; - if (strstri(g, "broken")) + + /* treat "broken glass" as a non-existent item; since "broken" is + also a chest/box prefix it might have been stripped off above */ + if (broken || strstri(g, "broken")) return (struct obj *) 0; if (!strncmpi(g, "worthless ", 10)) g += 10; @@ -3804,6 +3818,28 @@ typfnd: if (Is_box(otmp) || typ == TIN) otmp->otrapped = (trapped == 1); } + /* empty for containers rather than for tins */ + if (contents == EMPTY) { + if (otmp->otyp == BAG_OF_TRICKS || otmp->otyp == HORN_OF_PLENTY) { + if (otmp->spe > 0) + otmp->spe = 0; + } else if (Has_contents(otmp)) { + /* this assumes that artifacts can't be randomly generated + inside containers */ + delete_contents(otmp); + otmp->owt = weight(otmp); + } + } + /* set locked/unlocked/broken */ + if (Is_box(otmp)) { + if (locked) { + otmp->olocked = 1, otmp->obroken = 0; + } else if (unlocked) { + otmp->olocked = 0, otmp->obroken = 0; + } else if (broken) { + otmp->olocked = 0, otmp->obroken = 1; + } + } if (isgreased) otmp->greased = 1;