diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 8f465807e..204ba151d 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -957,6 +957,9 @@ if #wizmakemap was used to generate a replacement level while any shopkeeper, temple priest, or vault guard from the level was off of it at the time, the monster's eshk, epri, or egd data became invalid and would cause trouble if the monster returned to its 'home' level +similarly, if #wizfliplevel was used to transpose an active level while a + vauld guard was maintaining a temporary corridor or while a monster + with eshk, epri, or egd data was off level, that data became invalid blessed potion of polymorph will prompt user for monster to poly into diff --git a/src/sp_lev.c b/src/sp_lev.c index b4aa4d8d8..da68519d6 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -27,6 +27,8 @@ static void flip_drawbridge_horizontal(struct rm *); static void flip_drawbridge_vertical(struct rm *); static void flip_visuals(int, int, int, int, int); static int flip_encoded_direction_bits(int, int); +static void flip_vault_guard(int, struct monst *, + coordxy, coordxy, coordxy, coordxy); static void sel_set_wall_property(coordxy, coordxy, genericptr_t); static void set_wall_property(coordxy, coordxy, coordxy, coordxy, int); static void count_features(void); @@ -484,7 +486,10 @@ flip_encoded_direction_bits(int flp, int val) /* transpose top with bottom or left with right or both; sometimes called for new special levels, or for any level via the #wizfliplevel command */ void -flip_level(int flp, boolean extras) +flip_level( + int flp, /* mask for orientation(s) to transpose */ + boolean extras) /* False: level creation; True: #wizfliplevel is + * altering an active level so more needs to be done */ { int x, y, i, itmp; coordxy minx, miny, maxx, maxy; @@ -589,8 +594,12 @@ flip_level(int flp, boolean extras) /* monsters */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (mtmp->isgd && mtmp->mx == 0) - continue; + if (mtmp->isgd) { + if (extras) /* flip mtmp->mextra->egd */ + flip_vault_guard(flp, mtmp, minx, miny, maxx, maxy); + if (mtmp->mx == 0) /* not on map so don't flip guard->mx,my */ + continue; + } /* skip the occasional earth elemental outside the flip area */ if (!inFlipArea(mtmp->mx, mtmp->my)) continue; @@ -617,6 +626,20 @@ flip_level(int flp, boolean extras) } #endif } + if (extras) { /* #wizfliplevel rather than level creation */ + for (mtmp = g.migrating_mons; mtmp; mtmp = mtmp->nmon) { + if (mtmp->isgd && on_level(&u.uz, &EGD(mtmp)->gdlevel)) { + flip_vault_guard(flp, mtmp, minx, miny, maxx, maxy); /* egd */ + } else if (mtmp->ispriest + && on_level(&u.uz, &EPRI(mtmp)->shrlevel)) { + Flip_coord(EPRI(mtmp)->shrpos); /* priest's altar */ + } else if (mtmp->isshk + && on_level(&u.uz, &ESHK(mtmp)->shoplevel)) { + Flip_coord(ESHK(mtmp)->shk); /* shk's preferred spot */ + Flip_coord(ESHK(mtmp)->shd); /* shop door */ + } + } + } /* engravings */ for (etmp = head_engr; etmp; etmp = etmp->nxt_engr) { @@ -831,6 +854,42 @@ flip_level(int flp, boolean extras) vision_reset(); } +/* for #wizfliplevel, flip guard's egd data; not needed for level creation */ +static void +flip_vault_guard( + int flp, /* 1: transpose vertically, 2: transpose horizontally, 3: both */ + struct monst *gd, /* the vault guard, has monst->mextra->egd data */ + coordxy minx, coordxy miny, /* needed by FlipX(), FlipY(), */ + coordxy maxx, coordxy maxy) /* and inFlipArea() macros */ +{ + int i; + struct egd *egd = EGD(gd); + + if (inFlipArea(egd->gdx, egd->gdy)) { + if (flp & 1) + egd->gdy = FlipY(egd->gdy); + if (flp & 2) + egd->gdx = FlipX(egd->gdx); + } + if (inFlipArea(egd->ogx, egd->ogy)) { + if (flp & 1) + egd->ogy = FlipY(egd->ogy); + if (flp & 2) + egd->ogx = FlipX(egd->ogx); + } + for (i = egd->fcbeg; i < egd->fcend; ++i) { + coordxy fx = egd->fakecorr[i].fx, fy = egd->fakecorr[i].fy; + + if (inFlipArea(fx, fy)) { + if (flp & 1) + egd->fakecorr[i].fy = FlipY(fy); + if (flp & 2) + egd->fakecorr[i].fx = FlipX(fx); + } + } + return; +} + #undef FlipX #undef FlipY #undef inFlipArea