\#wizfliplevel fixes
Fix wizard mode issues pointed out by the #wizmakemap fix. If a shopkeeper or temple priest is on a different level and its home level gets flipped, monst eshk or epri data became invalid and would cause trouble if the shk or priest ever made it back to home level. If a vault guard is maintaining a temporary corridor and the level gets flipped, the data became invalid. If you used #wizfliplevel while the guard was leading you out, the corridor spots would be flipped along with the rest of the map but the guards's temporary corridor data didn't match. Breaches in the vault walls would be sealed, then the guard would just mill around, never finishing leading the hero out.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
65
src/sp_lev.c
65
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
|
||||
|
||||
Reference in New Issue
Block a user