more mimic-as-boulder (trunk only)

I started to add handling for doorways containing mimic-as-boulder
to doopen() and doclose() as was done for pick_lock(), but decided that
it was better just to prevent mimics from appearing as boulders at closed
door locations in the first place.  So the most recent pick_lock() change
and its fixes entry go away.

     This also fixes a post-3.4.3 bug.  On the top level of Sokoban I
discovered a boulder over a hole; probing reported it as a mimic with
0 hp.  The special level loading code moves mimic-as-boulder away from
trap spots by using place_monster() to put it on another spot, but it
was missing the corresponding remove_monster() to take it away from the
original location so left a stale pointer on the map.
This commit is contained in:
nethack.rankin
2011-01-05 01:28:36 +00:00
parent e379b245d4
commit 3b6c59c7fc
3 changed files with 34 additions and 21 deletions

View File

@@ -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

View File

@@ -407,17 +407,6 @@ pick_lock(pick)
/* "The door actually was a <mimic>!" */
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)

View File

@@ -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;