Rework stairs structure

Use a linked list to store stair and ladder information, instead
of having fixed up/down stairs/ladders and a single "special" (branch)
stair.

Breaks saves and bones.

Adds information to migrating objects and monsters for the dungeon
and level where they are migrating from.
This commit is contained in:
Pasi Kallinen
2020-11-09 18:50:02 +02:00
parent e23f764d11
commit 6ec55a3624
34 changed files with 552 additions and 361 deletions

View File

@@ -19,7 +19,7 @@ static int FDECL(kick_object, (XCHAR_P, XCHAR_P, char *));
static int FDECL(really_kick_object, (XCHAR_P, XCHAR_P));
static char *FDECL(kickstr, (char *, const char *));
static void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long));
static void FDECL(drop_to, (coord *, SCHAR_P));
static void FDECL(drop_to, (coord *, SCHAR_P, XCHAR_P, XCHAR_P));
static const char kick_passes_thru[] = "kick passes harmlessly through";
@@ -1322,10 +1322,13 @@ dokick()
}
static void
drop_to(cc, loc)
drop_to(cc, loc, x,y)
coord *cc;
schar loc;
xchar x,y;
{
stairway *stway = stairway_at(x, y);
/* cover all the MIGR_xxx choices generated by down_gate() */
switch (loc) {
case MIGR_RANDOM: /* trap door or hole */
@@ -1340,12 +1343,14 @@ schar loc;
/*FALLTHRU*/
case MIGR_STAIRS_UP:
case MIGR_LADDER_UP:
cc->x = u.uz.dnum;
cc->y = u.uz.dlevel + 1;
break;
case MIGR_SSTAIRS:
cc->x = g.sstairs.tolev.dnum;
cc->y = g.sstairs.tolev.dlevel;
if (stway) {
cc->x = stway->tolev.dnum;
cc->y = stway->tolev.dlevel;
} else {
cc->x = u.uz.dnum;
cc->y = u.uz.dlevel + 1;
}
break;
default:
case MIGR_NOWHERE:
@@ -1373,7 +1378,7 @@ xchar dlev; /* if !0 send to dlev near player */
return;
toloc = down_gate(x, y);
drop_to(&cc, toloc);
drop_to(&cc, toloc, x, y);
if (!cc.y)
return;
@@ -1502,7 +1507,7 @@ boolean shop_floor_obj;
return FALSE;
if ((toloc = down_gate(x, y)) == MIGR_NOWHERE)
return FALSE;
drop_to(&cc, toloc);
drop_to(&cc, toloc, x, y);
if (!cc.y)
return FALSE;
@@ -1586,6 +1591,7 @@ boolean shop_floor_obj;
otmp->ox = cc.x;
otmp->oy = cc.y;
otmp->owornmask = (long) toloc;
/* boulder from rolling boulder trap, no longer part of the trap */
if (otmp->otyp == BOULDER)
otmp->otrapped = 0;
@@ -1614,6 +1620,9 @@ boolean near_hero;
register int nx, ny;
int where;
boolean nobreak, noscatter;
stairway *stway;
d_level fromdlev;
boolean isladder;
for (otmp = g.migrating_objs; otmp; otmp = otmp2) {
otmp2 = otmp->nobj;
@@ -1633,16 +1642,21 @@ boolean near_hero;
obj_extract_self(otmp);
otmp->owornmask = 0L;
fromdlev.dnum = otmp->omigr_from_dnum;
fromdlev.dlevel = otmp->omigr_from_dlevel;
isladder = FALSE;
switch (where) {
case MIGR_STAIRS_UP:
nx = xupstair, ny = yupstair;
break;
case MIGR_LADDER_UP:
nx = xupladder, ny = yupladder;
break;
isladder = TRUE;
case MIGR_STAIRS_UP:
case MIGR_SSTAIRS:
nx = g.sstairs.sx, ny = g.sstairs.sy;
if ((stway = stairway_find_from(&fromdlev, isladder)) != 0) {
nx = stway->sx;
nx = stway->sy;
}
break;
break;
case MIGR_WITH_HERO:
nx = u.ux, ny = u.uy;
@@ -1652,6 +1666,8 @@ boolean near_hero;
nx = ny = 0;
break;
}
otmp->omigr_from_dnum = 0;
otmp->omigr_from_dlevel = 0;
if (nx > 0) {
place_object(otmp, nx, ny);
if (!nobreak && !IS_SOFT(levl[nx][ny].typ)) {
@@ -1727,6 +1743,8 @@ unsigned long deliverflags;
free_oname(otmp);
}
otmp->migr_species = NON_PM;
otmp->omigr_from_dnum = 0;
otmp->omigr_from_dlevel = 0;
(void) add_to_minv(mtmp, otmp);
cnt++;
if (maxobj && cnt >= maxobj)
@@ -1773,19 +1791,19 @@ down_gate(x, y)
xchar x, y;
{
struct trap *ttmp;
stairway *stway = stairway_at(x, y);
g.gate_str = 0;
/* this matches the player restriction in goto_level() */
if (on_level(&u.uz, &qstart_level) && !ok_to_quest())
return MIGR_NOWHERE;
if ((xdnstair == x && ydnstair == y)
|| (g.sstairs.sx == x && g.sstairs.sy == y && !g.sstairs.up)) {
if (stway && !stway->up && !stway->isladder) {
g.gate_str = "down the stairs";
return (xdnstair == x && ydnstair == y) ? MIGR_STAIRS_UP
: MIGR_SSTAIRS;
return (stway->tolev.dnum == u.uz.dnum) ? MIGR_STAIRS_UP
: MIGR_SSTAIRS;
}
if (xdnladder == x && ydnladder == y) {
if (stway && !stway->up && stway->isladder) {
g.gate_str = "down the ladder";
return MIGR_LADDER_UP;
}