diff --git a/src/mhitm.c b/src/mhitm.c index 10fa8cfc8..2473c1417 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitm.c $NHDT-Date: 1698939796 2023/11/02 15:43:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 3.7 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1209,6 +1209,12 @@ paralyze_monst(struct monst *mon, int amt) int sleep_monst(struct monst *mon, int amt, int how) { + /* reveal mimic unless already asleep or paralyzed (won't be 'busy') */ + if (how >= 0 && !mon->msleeping && !mon->mfrozen + && mon->data->mlet == S_MIMIC && (M_AP_TYPE(mon) == M_AP_FURNITURE + || M_AP_TYPE(mon) == M_AP_OBJECT)) + seemimic(mon); + if (resists_sleep(mon) || defended(mon, AD_SLEE) || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) { shieldeff(mon->mx, mon->my); diff --git a/src/objnam.c b/src/objnam.c index 47c9eca44..334d5b7ed 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1711809641 2024/03/30 14:40:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.427 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.439 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2475,7 +2475,7 @@ static const char wrpsym[] = { WAND_CLASS, RING_CLASS, POTION_CLASS, /* return form of the verb (input plural) if xname(otmp) were the subject */ char * -otense(struct obj* otmp,const char * verb) +otense(struct obj *otmp, const char *verb) { char *buf; diff --git a/src/pager.c b/src/pager.c index 74ceeccbe..079d182a7 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1724094301 2024/08/19 19:05:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.282 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -280,7 +280,10 @@ mhidden_description( /* extracted from lookat(); also used by namefloorobj() */ boolean -object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p) +object_from_map( + int glyph, + coordxy x, coordxy y, + struct obj **obj_p) { boolean fakeobj = FALSE, mimic_obj = FALSE; struct monst *mtmp; @@ -305,8 +308,10 @@ object_from_map(int glyph, coordxy x, coordxy y, struct obj **obj_p) if (!otmp || otmp->otyp != glyphotyp) { /* this used to exclude STRANGE_OBJECT; now caller deals with it */ otmp = mksobj(glyphotyp, FALSE, FALSE); - if (!otmp) - return FALSE; + /* even though we pass False for mksobj()'s 'init' arg, corpse-rot, + egg-hatch, and figurine-transform timers get initialized */ + if (otmp->timed) + obj_stop_timers(otmp); fakeobj = TRUE; if (otmp->oclass == COIN_CLASS) otmp->quan = 2L; /* to force pluralization */ diff --git a/src/uhitm.c b/src/uhitm.c index e0a403ebb..da34794a9 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1713334817 2024/04/17 06:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.444 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.451 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6030,8 +6030,11 @@ DISABLE_WARNING_FORMAT_NONLITERAL void stumble_onto_mimic(struct monst *mtmp) { - const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0; + static char generic[] = "a monster"; + char fmt[QBUFSZ]; + const char *what = NULL; + Strcpy(fmt, "Wait! That's %s!"); if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK) /* must be adjacent; attack via polearm could be from farther away */ && m_next2u(mtmp)) @@ -6045,16 +6048,39 @@ stumble_onto_mimic(struct monst *mtmp) } else { int glyph = levl[u.ux + u.dx][u.uy + u.dy].glyph; - if (glyph_is_cmap(glyph) && (glyph_to_cmap(glyph) == S_hcdoor - || glyph_to_cmap(glyph) == S_vcdoor)) - fmt = "The door actually was %s!"; - else if (glyph_is_object(glyph) && glyph_to_obj(glyph) == GOLD_PIECE) - fmt = "That gold was %s!"; + if (glyph_is_cmap(glyph)) { + Sprintf(fmt, "%s %s actually is %%s!", + is_cmap_stairs(glyph) ? "Those" : "That", + defsyms[mtmp->mappearance].explanation); + /* BUG: this will misclassify a paralyzed mimic as sleeping */ + what = x_monnam(mtmp, ARTICLE_A, "sleeping", 0, FALSE); + } else if (glyph_is_object(glyph)) { + boolean fakeobj; + const char *otmp_name; + struct obj *otmp = NULL; + + fakeobj = object_from_map(glyph, mtmp->mx, mtmp->my, &otmp); + otmp_name = (otmp && otmp->otyp != STRANGE_OBJECT) + ? simpleonames(otmp) : "strange object"; + Sprintf(fmt, "%s %s %s %%s!", + otmp && is_plural(otmp) ? "Those" : "That", + otmp_name, otmp ? otense(otmp, "are") : "is"); + if (fakeobj && otmp) { + otmp->where = OBJ_FREE; /* object_from_map set to OBJ_FLOOR */ + dealloc_obj(otmp); + } + } /* cloned Wiz starts out mimicking some other monster and might make himself invisible before being revealed */ if (mtmp->minvis && !See_invisible) what = generic; + else if (mtmp->data->mlet == S_MIMIC + && (M_AP_TYPE(mtmp) == M_AP_OBJECT + || M_AP_TYPE(mtmp) == M_AP_FURNITURE) + && (mtmp->msleeping || mtmp->mfrozen)) + /* BUG: this will misclassify a paralyzed mimic as sleeping */ + what = x_monnam(mtmp, ARTICLE_A, "sleeping", 0, FALSE); else what = a_monnam(mtmp); } diff --git a/src/zap.c b/src/zap.c index 2748acd77..dede87a0d 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1723946858 2024/08/18 02:07:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.542 $ */ +/* NetHack 3.7 zap.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.551 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -148,7 +148,11 @@ learnwand(struct obj *obj) } } -/* Routines for IMMEDIATE wands and spells. */ +/* + * Routines for IMMEDIATE wands and spells. + * Also RAY or NODIR for wands that are being broken rather than zapped. + */ + /* bhitm: monster mtmp was hit by the effect of wand or spell otmp */ int bhitm(struct monst *mtmp, struct obj *otmp) @@ -350,6 +354,10 @@ bhitm(struct monst *mtmp, struct obj *otmp) } case WAN_LOCKING: case SPE_WIZARD_LOCK: + /* can't use Is_box() here */ + if (disguised_mimic && (is_obj_mappear(mtmp, CHEST) + || is_obj_mappear(mtmp, LARGE_BOX))) + seemimic(mtmp); wake = closeholdingtrap(mtmp, &learn_it); break; case WAN_PROBING: @@ -360,6 +368,9 @@ bhitm(struct monst *mtmp, struct obj *otmp) break; case WAN_OPENING: case SPE_KNOCK: + if (disguised_mimic && (is_obj_mappear(mtmp, CHEST) + || is_obj_mappear(mtmp, LARGE_BOX))) + seemimic(mtmp); wake = FALSE; /* don't want immediate counterattack */ if (mtmp == u.ustuck) { /* zapping either holder/holdee or self [zapyourself()] will @@ -450,7 +461,8 @@ bhitm(struct monst *mtmp, struct obj *otmp) break; case WAN_SLEEP: /* (broken wand) */ /* [wakeup() doesn't rouse victims of temporary sleep, - so it's okay to leave `wake' set to TRUE here] */ + so it's okay to leave `wake' set to TRUE here; + revealing concealed mimic is handled by sleep_monst()] */ reveal_invis = TRUE; if (sleep_monst(mtmp, d(1 + otmp->spe, 12), WAND_CLASS)) slept_monst(mtmp); @@ -458,6 +470,8 @@ bhitm(struct monst *mtmp, struct obj *otmp) learn_it = TRUE; break; case SPE_STONE_TO_FLESH: + /* FIXME: mimics disguished as stone furniture or stone object + should be taken out of concealment. */ if (monsndx(mtmp->data) == PM_STONE_GOLEM) { char *name = Monnam(mtmp); @@ -3491,7 +3505,8 @@ exclam(int force) } void -hit(const char *str, /* zap text or missile name */ +hit( + const char *str, /* zap text or missile name */ struct monst *mtmp, /* target; for missile, might be hero */ const char *force) /* usually either "." or "!" via exclam() */ { @@ -3500,11 +3515,8 @@ hit(const char *str, /* zap text or missile name */ && (cansee(gb.bhitpos.x, gb.bhitpos.y) || canspotmon(mtmp) || engulfing_u(mtmp)))); - if (!verbosely) - pline("%s %s it.", The(str), vtense(str, "hit")); - else - pline("%s %s %s%s", The(str), vtense(str, "hit"), - mon_nam(mtmp), force); + pline("%s %s %s%s", The(str), vtense(str, "hit"), + verbosely ? mon_nam(mtmp) : "it", force); } void @@ -4209,7 +4221,8 @@ zhitm( tmp += destroy_items(mon, AD_COLD, orig_dmg); break; case ZT_SLEEP: - /* possibly resistance and shield effect handled by sleep_monst() */ + /* resistance and shield effect and revealing concealed mimic are + handled by sleep_monst() */ tmp = 0; (void) sleep_monst(mon, d(nd, 25), type == ZT_WAND(ZT_SLEEP) ? WAND_CLASS : '\0'); @@ -4576,8 +4589,9 @@ burn_floor_objects( /* will zap/spell/breath attack score a hit against armor class `ac'? */ staticfn int -zap_hit(int ac, - int type) /* either hero cast spell type or 0 */ +zap_hit( + int ac, + int type) /* either hero cast spell type or 0 */ { int chance = rn2(20); int spell_bonus = type ? spell_hit_bonus(type) : 0;