From: nethack.rankin Date: Wed, 15 Feb 2012 01:55:34 +0000 (+0000) Subject: oracle bones (trunk only) X-Git-Tag: MOVE2GIT~55 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6540843cbfc0cbb59165c4637052454840123e7d;p=nethack 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. --- diff --git a/include/mkroom.h b/include/mkroom.h index 031b08764..993f7028f 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -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 */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 4dc0598a3..2459c53ed 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -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" diff --git a/src/bones.c b/src/bones.c index b762e5a00..2c05124d3 100644 --- a/src/bones.c +++ b/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