diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 9ea39a681..4da0d05b9 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -70,7 +70,7 @@ when blind and levitating > shouldn't say "stairs" if player has not seen them a slow-moving monster hidden under a rotting corpse was not immediately displayed when the corpse rotted away mimic that ends up on the rogue level should not mimic a closed door -mimic should not mimic a boulder while on a pit or hole location +mimic should not mimic a boulder while on a pit or hole or closed door reviving invisible troll could appear visible until it moves adjust some of the shop repair messages charge for reviving a shop owned corpse or reanimating a shop owned statue @@ -342,8 +342,6 @@ when reading an unknown scroll and learning it, discovery of teleporation was too late if hero happened to land on another scroll of teleportation using an unlocking tool on a closed door which was actually a mimic reported that there was no door to unlock instead of exposing the mimic -using an unlocking tool on a boulder that was a mimic in a Sokoban doorway - successfully unlocked the underlying door without exposing mimic Platform- and/or Interface-Specific Fixes diff --git a/src/lock.c b/src/lock.c index 60fb4e8c1..0fce4639c 100644 --- a/src/lock.c +++ b/src/lock.c @@ -407,17 +407,6 @@ pick_lock(pick) /* "The door actually was a !" */ stumble_onto_mimic(mtmp); return PICKLOCK_LEARNED_SOMETHING; - /* mimic-as-boulder on last Sokoban level */ - } else if (mtmp && mtmp->m_ap_type == M_AP_OBJECT && - mtmp->mappearance == BOULDER) { - if (Blind) /* by touch */ - /* "Wait! That's a monster!" */ - stumble_onto_mimic(mtmp); - else if (IS_DOOR(door->typ)) - pline("That door is blocked."); - else - You("see no door there."); - return PICKLOCK_LEARNED_SOMETHING; } if(!IS_DOOR(door->typ)) { if (is_drawbridge_wall(cc.x,cc.y) >= 0) diff --git a/src/sp_lev.c b/src/sp_lev.c index 11236f8c9..0d89bfc31 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,5 +1,4 @@ /* NetHack 3.5 sp_lev.c $Date$ $Revision$ */ -/* SCCS Id: @(#)sp_lev.c 3.5 2007/08/01 */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -30,6 +29,7 @@ STATIC_DCL void FDECL(get_room_loc, (schar *, schar *, struct mkroom *)); STATIC_DCL void FDECL(get_free_room_loc, (schar *, schar *, struct mkroom *)); STATIC_DCL void FDECL(create_trap, (trap *, struct mkroom *)); STATIC_DCL int FDECL(noncoalignment, (ALIGNTYP_P)); +STATIC_DCL boolean FDECL(m_bad_boulder_spot, (int,int)); STATIC_DCL void FDECL(create_monster, (monster *, struct mkroom *)); STATIC_DCL void FDECL(create_object, (object *, struct mkroom *)); STATIC_DCL void FDECL(create_engraving, (engraving *,struct mkroom *)); @@ -744,6 +744,26 @@ aligntyp alignment; return(k ? -alignment : 0); } +/* attempt to screen out locations where a mimic-as-boulder shouldn't occur */ +STATIC_OVL boolean +m_bad_boulder_spot(x, y) +int x, y; +{ + struct rm *lev; + + /* avoid trap locations */ + if (t_at(x, y)) return TRUE; + /* try to avoid locations which already have a boulder (this won't + actually work; we get called before objects have been placed...) */ + if (sobj_at(BOULDER, x, y)) return TRUE; + /* avoid closed doors */ + lev = &levl[x][y]; + if (IS_DOOR(lev->typ) && (lev->doormask & (D_CLOSED | D_LOCKED)) != 0) + return TRUE; + /* spot is ok */ + return FALSE; +} + STATIC_OVL void create_monster(m,croom) monster *m; @@ -817,6 +837,7 @@ struct mkroom *croom; else mtmp = makemon(pm, x, y, NO_MM_FLAGS); if (mtmp) { + x = mtmp->mx, y = mtmp->my; /* sanity precaution */ /* handle specific attributes for some special monsters */ if (m->name.str) mtmp = christen_monst(mtmp, m->name.str); @@ -862,21 +883,26 @@ struct mkroom *croom; mtmp->m_ap_type = M_AP_OBJECT; mtmp->mappearance = i; /* try to avoid placing mimic boulder on a trap */ - if (i == BOULDER && m->x < 0 && t_at(x, y)) { - int k; + if (i == BOULDER && m->x < 0 && + m_bad_boulder_spot(x, y)) { + int retrylimit = 10; - for (k = 0; k < 10 && t_at(x, y); ++k) { + remove_monster(x, y); + do { x = m->x; y = m->y; if (croom) get_room_loc(&x, &y, croom); - else { + else get_location(&x, &y, DRY); - } if (MON_AT(x,y) && enexto(&cc, x, y, pm)) x = cc.x, y = cc.y; - } + } while (m_bad_boulder_spot(x, y) && + --retrylimit > 0); place_monster(mtmp, x, y); + /* if we didn't find a good spot + then mimic something else */ + if (!retrylimit) set_mimic_sym(mtmp); } } break;