]> granicus.if.org Git - nethack/commitdiff
Moving clouds on the plane of air
authorPasi Kallinen <paxed@alt.org>
Tue, 31 Mar 2015 08:46:41 +0000 (11:46 +0300)
committerPasi Kallinen <paxed@alt.org>
Tue, 31 Mar 2015 08:46:46 +0000 (11:46 +0300)
Reusing the plane of water air bubbles code

dat/endgame.des
src/allmain.c
src/do.c
src/mkmaze.c

index 4758ff5184027072358ceac527c975ac8243a7bf..1f811ad6142142415db9822c60a035489c90f1d7 100644 (file)
@@ -139,26 +139,26 @@ GEOMETRY:center,center
 # This map has no visible outer boundary, and
 # is all "air".
 MAP
-AAAAAAAAAAAAAAAAAAAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAACCCCCCAAAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAACCAACCCCCAAAAAACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAACCACCCCCCCAAAAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAACCCCAAACCAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAACCCCAAAAAACCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAACCCCCCCAAAACCACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAACCCCAAAAAAACCACAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCAACCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCAAACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACACCCCCAAACCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCCAAAACCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACCCCCCCCAAACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCAACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAACACCCCCCCCCCACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCAAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAACCAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 ENDMAP
 # Use up and down regions to partition the level into three parts;
 # teleportation can't cross from one part into another.
index 45c3190378cd59a2760f12a0d3056d7b2000c2a7..5f5ab44c78ccc02db464384b91898307e385e603 100644 (file)
@@ -292,7 +292,7 @@ boolean resuming;
                    }
                    restore_attrib();
                    /* underwater and waterlevel vision are done here */
-                   if (Is_waterlevel(&u.uz))
+                   if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
                        movebubbles();
                    else if (Underwater)
                        under_water(0);
index c690ad4faffde67d9f8d5a367cc40270200f7071..eae360425174e8e5873321a3cf5f89e1bd44eb1e 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -1286,7 +1286,7 @@ boolean at_stairs, falling, portal;
        }
 
        /* initial movement of bubbles just before vision_recalc */
-       if (Is_waterlevel(&u.uz))
+       if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
                movebubbles();
 
        if (level_info[new_ledger].flags & FORGOTTEN) {
index 87a3a870b2b46461c92d816e3093dea0f17322b9..c0036d1704724712e4100ae42771ffa81f6697fa 100644 (file)
@@ -344,7 +344,8 @@ fixup_special()
        was_waterlevel = FALSE;
        u.uinwater = 0;
        unsetup_waterlevel();
-    } else if (Is_waterlevel(&u.uz)) {
+    }
+    if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz)) {
        level.flags.hero_memory = 0;
        was_waterlevel = TRUE;
        /* water level is an odd beast - it has to be set up
@@ -922,98 +923,110 @@ movebubbles()
        struct trap *btrap;
        static const struct rm water_pos =
                { cmap_to_glyph(S_water), WATER, 0, 0, 0, 0, 0, 0, 0 };
+       static const struct rm air_pos =
+               { cmap_to_glyph(S_cloud), AIR,   0, 0, 0, 1, 0, 0, 0 };
 
        /* set up the portal the first time bubbles are moved */
        if (!wportal) set_wportal();
 
        vision_recalc(2);
-       /* keep attached ball&chain separate from bubble objects */
-       if (Punished) unplacebc();
 
-       /*
-        * Pick up everything inside of a bubble then fill all bubble
-        * locations.
-        */
+       if (Is_waterlevel(&u.uz)) {
 
-       for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) {
-           if (b->cons) panic("movebubbles: cons != null");
-           for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++)
-               for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++)
-                   if (b->bm[j + 2] & (1 << i)) {
-                       if (!isok(x,y)) {
-                           impossible("movebubbles: bad pos (%d,%d)", x,y);
-                           continue;
-                       }
+           /* keep attached ball&chain separate from bubble objects */
+           if (Punished) unplacebc();
 
-                       /* pick up objects, monsters, hero, and traps */
-                       if (OBJ_AT(x,y)) {
-                           struct obj *olist = (struct obj *) 0, *otmp;
-                           struct container *cons = (struct container *)
-                               alloc(sizeof(struct container));
-
-                           while ((otmp = level.objects[x][y]) != 0) {
-                               remove_object(otmp);
-                               otmp->ox = otmp->oy = 0;
-                               otmp->nexthere = olist;
-                               olist = otmp;
+           /*
+            * Pick up everything inside of a bubble then fill all bubble
+            * locations.
+            */
+
+           for (b = up ? bbubbles : ebubbles; b; b = up ? b->next : b->prev) {
+               if (b->cons) panic("movebubbles: cons != null");
+               for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++)
+                   for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++)
+                       if (b->bm[j + 2] & (1 << i)) {
+                           if (!isok(x,y)) {
+                               impossible("movebubbles: bad pos (%d,%d)", x,y);
+                               continue;
                            }
 
-                           cons->x = x;
-                           cons->y = y;
-                           cons->what = CONS_OBJ;
-                           cons->list = (genericptr_t) olist;
-                           cons->next = b->cons;
-                           b->cons = cons;
-                       }
-                       if (MON_AT(x,y)) {
-                           struct monst *mon = m_at(x,y);
-                           struct container *cons = (struct container *)
-                               alloc(sizeof(struct container));
-
-                           cons->x = x;
-                           cons->y = y;
-                           cons->what = CONS_MON;
-                           cons->list = (genericptr_t) mon;
-
-                           cons->next = b->cons;
-                           b->cons = cons;
-
-                           if(mon->wormno)
-                               remove_worm(mon);
-                           else
-                               remove_monster(x, y);
-
-                           newsym(x,y);        /* clean up old position */
-                           mon->mx = mon->my = 0;
-                       }
-                       if (!u.uswallow && x == u.ux && y == u.uy) {
-                           struct container *cons = (struct container *)
-                               alloc(sizeof(struct container));
+                           /* pick up objects, monsters, hero, and traps */
+                           if (OBJ_AT(x,y)) {
+                               struct obj *olist = (struct obj *) 0, *otmp;
+                               struct container *cons = (struct container *)
+                                   alloc(sizeof(struct container));
+
+                               while ((otmp = level.objects[x][y]) != 0) {
+                                   remove_object(otmp);
+                                   otmp->ox = otmp->oy = 0;
+                                   otmp->nexthere = olist;
+                                   olist = otmp;
+                               }
+
+                               cons->x = x;
+                               cons->y = y;
+                               cons->what = CONS_OBJ;
+                               cons->list = (genericptr_t) olist;
+                               cons->next = b->cons;
+                               b->cons = cons;
+                           }
+                           if (MON_AT(x,y)) {
+                               struct monst *mon = m_at(x,y);
+                               struct container *cons = (struct container *)
+                                   alloc(sizeof(struct container));
+
+                               cons->x = x;
+                               cons->y = y;
+                               cons->what = CONS_MON;
+                               cons->list = (genericptr_t) mon;
+
+                               cons->next = b->cons;
+                               b->cons = cons;
+
+                               if(mon->wormno)
+                                   remove_worm(mon);
+                               else
+                                   remove_monster(x, y);
+
+                               newsym(x,y);    /* clean up old position */
+                               mon->mx = mon->my = 0;
+                           }
+                           if (!u.uswallow && x == u.ux && y == u.uy) {
+                               struct container *cons = (struct container *)
+                                   alloc(sizeof(struct container));
 
-                           cons->x = x;
-                           cons->y = y;
-                           cons->what = CONS_HERO;
-                           cons->list = (genericptr_t) 0;
+                               cons->x = x;
+                               cons->y = y;
+                               cons->what = CONS_HERO;
+                               cons->list = (genericptr_t) 0;
 
-                           cons->next = b->cons;
-                           b->cons = cons;
-                       }
-                       if ((btrap = t_at(x,y)) != 0) {
-                           struct container *cons = (struct container *)
-                               alloc(sizeof(struct container));
+                               cons->next = b->cons;
+                               b->cons = cons;
+                           }
+                           if ((btrap = t_at(x,y)) != 0) {
+                               struct container *cons = (struct container *)
+                                   alloc(sizeof(struct container));
 
-                           cons->x = x;
-                           cons->y = y;
-                           cons->what = CONS_TRAP;
-                           cons->list = (genericptr_t) btrap;
+                               cons->x = x;
+                               cons->y = y;
+                               cons->what = CONS_TRAP;
+                               cons->list = (genericptr_t) btrap;
 
-                           cons->next = b->cons;
-                           b->cons = cons;
-                       }
+                               cons->next = b->cons;
+                               b->cons = cons;
+                           }
 
-                       levl[x][y] = water_pos;
-                       block_point(x,y);
-                   }
+                           levl[x][y] = water_pos;
+                           block_point(x,y);
+                       }
+           }
+       } else if (Is_airlevel(&u.uz)) {
+           for (x = 0; x < COLNO; x++)
+               for (y = 0; y < ROWNO; y++) {
+                   levl[x][y] = air_pos;
+                   unblock_point(x,y);
+               }
        }
 
        /*
@@ -1032,7 +1045,7 @@ movebubbles()
        }
 
        /* put attached ball&chain back */
-       if (Punished) placebc();
+       if (Is_waterlevel(&u.uz) && Punished) placebc();
        vision_full_recalc = 1;
 }
 
@@ -1076,7 +1089,7 @@ int fd, mode;
 {
        register struct bubble *b;
 
-       if (!Is_waterlevel(&u.uz)) return;
+       if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz)) return;
 
        if (perform_bwrite(mode)) {
            int n = 0;
@@ -1101,7 +1114,7 @@ register int fd;
        register int i;
        int n;
 
-       if (!Is_waterlevel(&u.uz)) return;
+       if (!Is_waterlevel(&u.uz) && !Is_airlevel(&u.uz)) return;
 
        set_wportal();
        mread(fd,(genericptr_t)&n,sizeof(int));
@@ -1177,6 +1190,7 @@ setup_waterlevel()
        register int x, y;
        register int xskip, yskip;
        register int water_glyph = cmap_to_glyph(S_water);
+       register int air_glyph = cmap_to_glyph(S_air);
 
        /* ouch, hardcoded... */
 
@@ -1189,12 +1203,18 @@ setup_waterlevel()
 
        for (x = xmin; x <= xmax; x++)
                for (y = ymin; y <= ymax; y++)
-                       levl[x][y].glyph = water_glyph;
+                 levl[x][y].glyph = Is_waterlevel(&u.uz) ? water_glyph : air_glyph;
 
        /* make bubbles */
 
-       xskip = 10 + rn2(10);
-       yskip = 4 + rn2(4);
+       if (Is_waterlevel(&u.uz)) {
+         xskip = 10 + rn2(10);
+         yskip = 4 + rn2(4);
+       } else {
+         xskip = 6 + rn2(4);
+         yskip = 3 + rn2(3);
+       }
+
        for (x = bxmin; x <= bxmax; x += xskip)
                for (y = bymin; y <= bymax; y += yskip)
                        mk_bubble(x,y,rn2(7));
@@ -1280,67 +1300,76 @@ register boolean ini;
        register int x, y, i, j, colli = 0;
        struct container *cons, *ctemp;
 
-       /* move bubble */
-       if (dx < -1 || dx > 1 || dy < -1 || dy > 1) {
-           /* pline("mv_bubble: dx = %d, dy = %d", dx, dy); */
-           dx = sgn(dx);
-           dy = sgn(dy);
-       }
-
-       /*
-        * collision with level borders?
-        *      1 = horizontal border, 2 = vertical, 3 = corner
-        */
-       if (b->x <= bxmin) colli |= 2;
-       if (b->y <= bymin) colli |= 1;
-       if ((int) (b->x + b->bm[0] - 1) >= bxmax) colli |= 2;
-       if ((int) (b->y + b->bm[1] - 1) >= bymax) colli |= 1;
-
-       if (b->x < bxmin) {
-           pline("bubble xmin: x = %d, xmin = %d", b->x, bxmin);
-           b->x = bxmin;
-       }
-       if (b->y < bymin) {
-           pline("bubble ymin: y = %d, ymin = %d", b->y, bymin);
-           b->y = bymin;
-       }
-       if ((int) (b->x + b->bm[0] - 1) > bxmax) {
-           pline("bubble xmax: x = %d, xmax = %d",
-                       b->x + b->bm[0] - 1, bxmax);
-           b->x = bxmax - b->bm[0] + 1;
-       }
-       if ((int) (b->y + b->bm[1] - 1) > bymax) {
-           pline("bubble ymax: y = %d, ymax = %d",
-                       b->y + b->bm[1] - 1, bymax);
-           b->y = bymax - b->bm[1] + 1;
-       }
+       /* clouds move slowly */
+       if (!Is_airlevel(&u.uz) || !rn2(6)) {
+           /* move bubble */
+           if (dx < -1 || dx > 1 || dy < -1 || dy > 1) {
+               /* pline("mv_bubble: dx = %d, dy = %d", dx, dy); */
+               dx = sgn(dx);
+               dy = sgn(dy);
+           }
 
-       /* bounce if we're trying to move off the border */
-       if (b->x == bxmin && dx < 0) dx = -dx;
-       if (b->x + b->bm[0] - 1 == bxmax && dx > 0) dx = -dx;
-       if (b->y == bymin && dy < 0) dy = -dy;
-       if (b->y + b->bm[1] - 1 == bymax && dy > 0) dy = -dy;
+           /*
+            * collision with level borders?
+            *  1 = horizontal border, 2 = vertical, 3 = corner
+            */
+           if (b->x <= bxmin) colli |= 2;
+           if (b->y <= bymin) colli |= 1;
+           if ((int) (b->x + b->bm[0] - 1) >= bxmax) colli |= 2;
+           if ((int) (b->y + b->bm[1] - 1) >= bymax) colli |= 1;
+
+           if (b->x < bxmin) {
+               pline("bubble xmin: x = %d, xmin = %d", b->x, bxmin);
+               b->x = bxmin;
+           }
+           if (b->y < bymin) {
+               pline("bubble ymin: y = %d, ymin = %d", b->y, bymin);
+               b->y = bymin;
+           }
+           if ((int) (b->x + b->bm[0] - 1) > bxmax) {
+               pline("bubble xmax: x = %d, xmax = %d",
+                     b->x + b->bm[0] - 1, bxmax);
+               b->x = bxmax - b->bm[0] + 1;
+           }
+           if ((int) (b->y + b->bm[1] - 1) > bymax) {
+               pline("bubble ymax: y = %d, ymax = %d",
+                     b->y + b->bm[1] - 1, bymax);
+               b->y = bymax - b->bm[1] + 1;
+           }
 
-       b->x += dx;
-       b->y += dy;
+           /* bounce if we're trying to move off the border */
+           if (b->x == bxmin && dx < 0) dx = -dx;
+           if (b->x + b->bm[0] - 1 == bxmax && dx > 0) dx = -dx;
+           if (b->y == bymin && dy < 0) dy = -dy;
+           if (b->y + b->bm[1] - 1 == bymax && dy > 0) dy = -dy;
 
-       /* void positions inside bubble */
+           b->x += dx;
+           b->y += dy;
+       }
 
+       /* draw the bubbles */
        for (i = 0, x = b->x; i < (int) b->bm[0]; i++, x++)
            for (j = 0, y = b->y; j < (int) b->bm[1]; j++, y++)
                if (b->bm[j + 2] & (1 << i)) {
+                 if (Is_waterlevel(&u.uz)) {
                    levl[x][y].typ = AIR;
                    levl[x][y].lit = 1;
                    unblock_point(x,y);
+                 } else if (Is_airlevel(&u.uz)) {
+                   levl[x][y].typ = CLOUD;
+                   levl[x][y].lit = 1;
+                   block_point(x,y);
+                 }
                }
 
-       /* replace contents of bubble */
-       for (cons = b->cons; cons; cons = ctemp) {
-           ctemp = cons->next;
-           cons->x += dx;
-           cons->y += dy;
+       if (Is_waterlevel(&u.uz)) {
+           /* replace contents of bubble */
+           for (cons = b->cons; cons; cons = ctemp) {
+               ctemp = cons->next;
+               cons->x += dx;
+               cons->y += dy;
 
-           switch(cons->what) {
+               switch(cons->what) {
                case CONS_OBJ: {
                    struct obj *olist, *otmp;
 
@@ -1381,13 +1410,13 @@ register boolean ini;
                default:
                    impossible("mv_bubble: unknown bubble contents");
                    break;
+               }
+               free((genericptr_t)cons);
            }
-           free((genericptr_t)cons);
+           b->cons = 0;
        }
-       b->cons = 0;
 
        /* boing? */
-
        switch (colli) {
            case 1: b->dy = -b->dy;     break;
            case 3: b->dy = -b->dy;     /* fall through */