]> granicus.if.org Git - nethack/commitdiff
dungeon ceiling (trunk only)
authornethack.rankin <nethack.rankin>
Tue, 4 Oct 2011 01:13:59 +0000 (01:13 +0000)
committernethack.rankin <nethack.rankin>
Tue, 4 Oct 2011 01:13:59 +0000 (01:13 +0000)
     The ceiling on the Plane of Water is always "water above", not "sky"
when inside air bubbles and "water's surface" when outside.  Also, support
throwing things upwards on the planes of air and water and when underwater
instead of silently dropping the missile in such cases.

     This is mainly groundwork for a tangential bit of a forthcoming
levitation fix.

include/extern.h
src/dothrow.c
src/dungeon.c
src/engrave.c

index c7fd206e80302349f6c1b42098f828bf862be3fc..3ad7c4d272d80088b34aa68455335cda76537eff 100644 (file)
@@ -559,6 +559,7 @@ E boolean FDECL(Is_botlevel, (d_level *));
 E boolean FDECL(Can_fall_thru, (d_level *));
 E boolean FDECL(Can_dig_down, (d_level *));
 E boolean FDECL(Can_rise_up, (int,int,d_level *));
+E boolean FDECL(has_ceiling, (d_level *));
 E boolean FDECL(In_quest, (d_level *));
 E boolean FDECL(In_mines, (d_level *));
 E branch *FDECL(dungeon_branch, (const char *));
index 7f6c63c997db53c0ce9742d6dea5cb5143f6eb67..dadb66603b20de38e122d7cb908d30ab19ee89eb 100644 (file)
@@ -792,24 +792,26 @@ toss_up(obj, hitsroof)
 struct obj *obj;
 boolean hitsroof;
 {
-    const char *almost;
+    const char *action;
     boolean petrifier = ((obj->otyp == EGG || obj->otyp == CORPSE) &&
                         touch_petrifies(&mons[obj->corpsenm]));
     /* note: obj->quan == 1 */
 
-    if (hitsroof) {
+    if (!has_ceiling(&u.uz)) {
+       action = "flies up into"; /* into "the sky" or "the water above" */
+    } else if (hitsroof) {
        if (breaktest(obj)) {
                pline("%s hits the %s.", Doname2(obj), ceiling(u.ux, u.uy));
                breakmsg(obj, !Blind);
                breakobj(obj, u.ux, u.uy, TRUE, TRUE);
                return FALSE;
        }
-       almost = "";
+       action = "hits";
     } else {
-       almost = " almost";
+       action = "almost hits";  
     }
-    pline("%s%s hits the %s, then falls back on top of your %s.",
-         Doname2(obj), almost, ceiling(u.ux,u.uy), body_part(HEAD));
+    pline("%s %s the %s, then falls back on top of your %s.",
+         Doname2(obj), action, ceiling(u.ux,u.uy), body_part(HEAD));
 
     /* object now hits you */
 
@@ -998,9 +1000,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
                (void) encumber_msg();
                setuwep(obj);
                u.twoweap = twoweap;
-           } else if (u.dz < 0 && !Is_airlevel(&u.uz) &&
-                   !Underwater && !Is_waterlevel(&u.uz)) {
-               (void) toss_up(obj, rn2(5));
+           } else if (u.dz < 0) {
+               (void) toss_up(obj, rn2(5) && !Underwater);
 #ifdef STEED
            } else if (u.dz > 0 && u.usteed &&
                obj->oclass == POTION_CLASS && rn2(6)) {
index b1e4ad9550c18ffbc4d0dbf5ef8dcd09398b9d31..98dc0e72f20c06f95cbb88473319e38d61b65de2 100644 (file)
@@ -1271,6 +1271,14 @@ d_level *lev;
                 sstairs.sx && sstairs.up));
 }
 
+boolean
+has_ceiling(lev)
+d_level *lev;
+{
+       /* [what about level 1 of the quest?] */
+    return (!Is_airlevel(lev) && !Is_waterlevel(lev));
+}
+
 /*
  * It is expected that the second argument of get_level is a depth value,
  * either supplied by the user (teleport control) or randomly generated.
index 704e6fa5501f8bcfd4752d6338a190ce4b3eea31..ee66ec300bbe23ea4d7a5cc1f524a83334ccae20 100644 (file)
@@ -214,6 +214,9 @@ register int x, y;
            what = "temple's ceiling";
        else if (*in_rooms(x,y,SHOPBASE))
            what = "shop's ceiling";
+       else if (Is_waterlevel(&u.uz))
+           /* water plane has no surface; its air bubbles aren't below sky */
+           what = "water above";
        else if (IS_AIR(lev->typ))
            what = "sky";
        else if (Underwater)