From: nethack.rankin Date: Wed, 24 Aug 2011 08:17:33 +0000 (+0000) Subject: fix #H2428 - cockatrice nests filled with giant ant statues (trunk only) X-Git-Tag: MOVE2GIT~187 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4aaf41de1056058651038092d823859b45b0748e;p=nethack fix #H2428 - cockatrice nests filled with giant ant statues (trunk only) From a bug report, if the high scores file is brand new (empty), statues placed in a cockatrice nest (special room) end up all being giant ant statues. Statue creation for that room suppresses object initialization (to prevent the statues from containing spellbooks), so statue type is left as 0 by mkobj(), then when 'record' is empty it never gets overridden with a role value as intended. This forces obj->corpsenm to be initialized as NON_PM instead of 0 by default, then overrides that for corpses, statues, and figurines even when mkobj()'s caller requests that initialization be suppressed. So if 'record' is empty, there will be a sensible fallback statue type. obj->corpsenm is overloaded for leashes ('leashmon', mon->m_id), potions ('fromsink', fountain quaff hack), spellbooks ('spestudied', the number of times the book has been read), and loadstones (corpsenm hack to handle singular vs plural for "you can't let go of that/those" message). If there are any other hidden corpsenm overloads, they may behave strangely now that corpsenm is defaulting to -1 instead of 0.... --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 657a2cabf..2fc5541cb 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -378,6 +378,7 @@ for hero poly'd into a monster form that lacks a weapon attack but has a claw attack, use wielded weapon even when claw attack isn't the very first rename the SLEEPING property and Sleeping attribute to SLEEPY and Sleepy, resp. give alternate message for " turns to flee" when mon can't move +all statues in a cockatrice nest were for giant ant if 'record' was empty Platform- and/or Interface-Specific Fixes diff --git a/src/mkobj.c b/src/mkobj.c index aaf82ba84..4fba48b59 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -619,6 +619,8 @@ boolean artif; #ifdef INVISIBLE_OBJECTS otmp->oinvis = !rn2(1250); #endif + otmp->corpsenm = NON_PM; + if (init) switch (let) { case WEAPON_CLASS: otmp->quan = is_multigen(otmp) ? (long) rn1(6,6) : 1L; @@ -683,11 +685,12 @@ boolean artif; otmp->quan = (long) rnd(2); break; } - if (otmp->otyp == CORPSE || otmp->otyp == MEAT_RING || - otmp->otyp == KELP_FROND) break; - /* fall into next case */ - + if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING && + otmp->otyp != KELP_FROND && !rn2(6)) + otmp->quan = 2L; + break; case GEM_CLASS: + otmp->corpsenm = 0; /* LOADSTONE hack */ if (otmp->otyp == LOADSTONE) curse(otmp); else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6); else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L; @@ -722,6 +725,8 @@ boolean artif; case OILSKIN_SACK: case BAG_OF_HOLDING: mkbox_cnts(otmp); break; + case LEASH: otmp->leashmon = 0; + break; #ifdef TOURIST case EXPENSIVE_CAMERA: #endif @@ -768,6 +773,7 @@ boolean artif; case BALL_CLASS: break; case POTION_CLASS: + otmp->fromsink = 0; if (otmp->otyp == POT_OIL) otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */ /* fall through */ @@ -778,6 +784,7 @@ boolean artif; blessorcurse(otmp, 4); break; case SPBOOK_CLASS: + otmp->spestudied = 0; blessorcurse(otmp, 17); break; case ARMOR_CLASS: @@ -851,12 +858,22 @@ boolean artif; return (struct obj *)0; } - /* Some things must get done (timers) even if init = 0 */ + /* some things must get done (corpsenm, timers) even if init = 0 */ switch (otmp->otyp) { case CORPSE: - case EGG: + if (otmp->corpsenm == NON_PM) { + otmp->corpsenm = undead_to_corpse(rndmonnum()); + if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE|G_GONE)) + otmp->corpsenm = urole.malenum; + } + /*FALLTHRU*/ + case STATUE: case FIGURINE: - set_corpsenm(otmp, otmp->corpsenm); + if (otmp->corpsenm == NON_PM) otmp->corpsenm = rndmonnum(); + /*FALLTHRU*/ + case EGG: + /* case TIN: */ + set_corpsenm(otmp, otmp->corpsenm); break; }