oracle bones (trunk only)
Noticed while working on #overview/#annotate revisions, one of which
will key off the oracle's welcome message. On a bones level, the oracle
could be outside her room, or the room's one time welcome message could be
used up, or both. During bones creation, discard her if she's on the wrong
level (probably not possible, aside from wizard mode ^G), try to put her
back into her room if she's outside it on the right level, and restore the
room's type (if she's still in it, or has been successfully moved back into
it) so that next hero who loads the bones will get her welcome message the
first time that room is entered.
Other special rooms could be fixed up too, provided that they're
sufficiently intact (stealthy hero might enter and get the one-time message
then run away and die elsewhere on the level; at present, next hero won't
get the room's entry message) but this doesn't attempt to deal with that.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
/* NetHack 3.5 mkroom.h $Date$ $Revision$ */
|
||||
/* SCCS Id: @(#)mkroom.h 3.5 2005/03/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -11,6 +10,7 @@
|
||||
struct mkroom {
|
||||
schar lx,hx,ly,hy; /* usually xchar, but hx may be -1 */
|
||||
schar rtype; /* type of room (zoo, throne, etc...) */
|
||||
schar orig_rtype; /* same as rtype, but not zeroed later */
|
||||
schar rlit; /* is the room lit ? */
|
||||
schar doorct; /* door count */
|
||||
schar fdoor; /* index for the first door of the room */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||
* and save files.
|
||||
*/
|
||||
#define EDITLEVEL 51
|
||||
#define EDITLEVEL 52
|
||||
|
||||
#define COPYRIGHT_BANNER_A \
|
||||
"NetHack, Copyright 1985-2012"
|
||||
|
||||
55
src/bones.c
55
src/bones.c
@@ -13,6 +13,7 @@ extern long bytes_counted;
|
||||
STATIC_DCL boolean FDECL(no_bones_level, (d_level *));
|
||||
STATIC_DCL void FDECL(goodfruit, (int));
|
||||
STATIC_DCL void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
|
||||
STATIC_DCL boolean FDECL(fixuporacle, (struct monst *));
|
||||
|
||||
STATIC_OVL boolean
|
||||
no_bones_level(lev)
|
||||
@@ -240,6 +241,55 @@ int x, y;
|
||||
if (cont) cont->owt = weight(cont);
|
||||
}
|
||||
|
||||
/* possibly restore oracle's room and/or put her back inside it; returns
|
||||
False if she's on the wrong level and should be removed, True otherwise */
|
||||
STATIC_OVL boolean
|
||||
fixuporacle(oracle)
|
||||
struct monst *oracle;
|
||||
{
|
||||
coord cc;
|
||||
int ridx, o_ridx;
|
||||
|
||||
/* oracle doesn't move, but knight's joust or monk's staggering blow
|
||||
could push her onto a hole in the floor; at present, traps don't
|
||||
activate in such situation hence she won't fall to another level;
|
||||
however, that could change so be prepared to cope with such things */
|
||||
if (!Is_oracle_level(&u.uz))
|
||||
return FALSE;
|
||||
|
||||
oracle->mpeaceful = 1;
|
||||
o_ridx = levl[oracle->mx][oracle->my].roomno - ROOMOFFSET;
|
||||
if (o_ridx >= 0 && rooms[o_ridx].rtype == DELPHI)
|
||||
return TRUE; /* no fixup needed */
|
||||
|
||||
/*
|
||||
* The Oracle isn't in DELPHI room. Either hero entered her chamber
|
||||
* and got the one-time welcome message, converting it into an
|
||||
* ordinary room, or she got teleported out, or both. Try to put
|
||||
* her back inside her room, if necessary, and restore its type.
|
||||
*/
|
||||
|
||||
/* find original delphi chamber; should always succeed */
|
||||
for (ridx = 0; ridx < SIZE(rooms); ++ridx)
|
||||
if (rooms[ridx].orig_rtype == DELPHI) break;
|
||||
|
||||
if (o_ridx != ridx && ridx < SIZE(rooms)) {
|
||||
/* room found and she's not not in it, so try to move her there */
|
||||
cc.x = (rooms[ridx].lx + rooms[ridx].hx) / 2;
|
||||
cc.y = (rooms[ridx].ly + rooms[ridx].hy) / 2;
|
||||
if (enexto(&cc, cc.x, cc.y, oracle->data)) {
|
||||
rloc_to(oracle, cc.x, cc.y);
|
||||
o_ridx = levl[oracle->mx][oracle->my].roomno - ROOMOFFSET;
|
||||
}
|
||||
/* [if her room is already full, she might end up outside;
|
||||
that's ok, next hero just won't get any welcome message,
|
||||
same as used to happen before this fixup was introduced] */
|
||||
}
|
||||
if (ridx == o_ridx) /* if she's in her room, mark it as such */
|
||||
rooms[ridx].rtype = DELPHI;
|
||||
return TRUE; /* keep oracle in new bones file */
|
||||
}
|
||||
|
||||
/* check whether bones are feasible */
|
||||
boolean
|
||||
can_make_bones()
|
||||
@@ -317,7 +367,8 @@ struct obj *corpse;
|
||||
mptr = mtmp->data;
|
||||
if (mtmp->iswiz || mptr == &mons[PM_MEDUSA] ||
|
||||
mptr->msound == MS_NEMESIS || mptr->msound == MS_LEADER ||
|
||||
mptr == &mons[PM_VLAD_THE_IMPALER])
|
||||
mptr == &mons[PM_VLAD_THE_IMPALER] ||
|
||||
(mptr == &mons[PM_ORACLE] && !fixuporacle(mtmp)))
|
||||
mongone(mtmp);
|
||||
}
|
||||
#ifdef STEED
|
||||
@@ -403,7 +454,7 @@ struct obj *corpse;
|
||||
u.ux = u.uy = 0;
|
||||
|
||||
/* Clear all memory from the level. */
|
||||
for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
|
||||
for (x = 1; x < COLNO; x++) for (y = 0; y<ROWNO; y++) {
|
||||
levl[x][y].seenv = 0;
|
||||
levl[x][y].waslit = 0;
|
||||
levl[x][y].glyph = cmap_to_glyph(S_stone);
|
||||
|
||||
@@ -931,11 +931,13 @@ void
|
||||
mklev()
|
||||
{
|
||||
struct mkroom *croom;
|
||||
int ridx;
|
||||
|
||||
#ifdef DUNGEON_OVERVIEW
|
||||
init_mapseen(&u.uz);
|
||||
#endif
|
||||
if(getbones()) return;
|
||||
|
||||
in_mklev = TRUE;
|
||||
makelevel();
|
||||
bound_digging();
|
||||
@@ -955,6 +957,10 @@ mklev()
|
||||
#endif
|
||||
}
|
||||
set_wall_state();
|
||||
/* for many room types, rooms[].rtype is zeroed once the room has been
|
||||
entered; rooms[].orig_rtype always retains original rtype value */
|
||||
for (ridx = 0; ridx < SIZE(rooms); ridx++)
|
||||
rooms[ridx].orig_rtype = rooms[ridx].rtype;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user