]> granicus.if.org Git - nethack/commitdiff
more mimic-as-boulder (trunk only)
authornethack.rankin <nethack.rankin>
Wed, 5 Jan 2011 01:28:36 +0000 (01:28 +0000)
committernethack.rankin <nethack.rankin>
Wed, 5 Jan 2011 01:28:36 +0000 (01:28 +0000)
     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.

doc/fixes35.0
src/lock.c
src/sp_lev.c

index 9ea39a681bd794c67336270a70cb6ad0338b43f8..4da0d05b9464569b6b2fe9f6e6829d822439c137 100644 (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
index 60fb4e8c1940b32e64ee74d31918dae445191b80..0fce4639c200f2c1237e2f44d23e7837093e64be 100644 (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)
index 11236f8c904f99482da82f0591b7610eef31a2e8..0d89bfc3130b54baf5e1ca472d1e99db34eb3e48 100644 (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;