diff -wur -N nethack-linux/dat/advcal.des nethack-adventskalender/dat/advcal.des --- nethack-linux/dat/advcal.des 1970-01-01 01:00:00.000000000 +0100 +++ nethack-adventskalender/dat/advcal.des 2008-10-19 16:55:42.000000000 +0200 @@ -0,0 +1,233 @@ +# SCCS Id: @(#)advcal.des 3.4 2008/08/12 +# Copyright (c) 2008 Patric Mueller +# NetHack may be freely redistributed. See license for details. +# + +MAZE:"advcal",' ' +FLAGS:noteleport +GEOMETRY:center,center +MAP +........................................................................... +...---...---...---...---...---...---...---...---...---...---...---...---... +...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|... +...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-... +........................................................................... +........................................................................... +...........................T............................................... +........................................................................... +............................................................T.............. +......T.................................................................... +........................................................................... +........................................................................... +........................................................................... +........................................................................... +.....................T..................................T.................. +........................................................................... +........................................................................... +...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-...-+-... +...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|...|.|... +...---...---...---...---...---...---...---...---...---...---...---...---... +........................................................................... +ENDMAP + +# Dungeon Description +REGION:(00,00,74,20),lit,"ordinary" +# Non diggable walls +NON_DIGGABLE:(00,00,74,20) +NON_PASSWALL:(00,00,74,20) +# Doors +DOOR:locked,(04,03) +DOOR:locked,(10,03) +DOOR:locked,(16,03) +DOOR:locked,(22,03) +DOOR:locked,(28,03) +DOOR:locked,(34,03) +DOOR:locked,(40,03) +DOOR:locked,(46,03) +DOOR:locked,(52,03) +DOOR:locked,(58,03) +DOOR:locked,(64,03) +DOOR:locked,(70,03) +DOOR:locked,(04,17) +DOOR:locked,(10,17) +DOOR:locked,(16,17) +DOOR:locked,(22,17) +DOOR:locked,(28,17) +DOOR:locked,(34,17) +DOOR:locked,(40,17) +DOOR:locked,(46,17) +DOOR:locked,(52,17) +DOOR:locked,(58,17) +DOOR:locked,(64,17) +DOOR:locked,(70,17) +## 64 gems in christmas colors +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random +OBJECT:'*',"worthless piece of violet glass",random + +OBJECT:'*',"worthless piece of green glass",random +OBJECT:'*',"worthless piece of green glass",random +OBJECT:'*',"worthless piece of green glass",random +OBJECT:'*',"worthless piece of green glass",random +OBJECT:'*',"worthless piece of green glass",random +OBJECT:'*',"worthless piece of green glass",random +OBJECT:'*',"worthless piece of green glass",random + +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random +OBJECT:'*',"worthless piece of red glass",random + +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random +OBJECT:'*',"worthless piece of white glass",random + +OBJECT:'*',"worthless piece of yellow glass",random +OBJECT:'*',"worthless piece of yellow glass",random +OBJECT:'*',"worthless piece of yellow glass",random +OBJECT:'*',"worthless piece of yellow glass",random +OBJECT:'*',"worthless piece of yellowish brown glass",random +OBJECT:'*',"worthless piece of yellowish brown glass",random +OBJECT:'*',"worthless piece of yellowish brown glass",random +OBJECT:'*',"worthless piece of yellowish brown glass",random +OBJECT:'*',"worthless piece of blue glass",random +OBJECT:'*',"worthless piece of blue glass",random +OBJECT:'*',"worthless piece of blue glass",random +OBJECT:'*',"worthless piece of blue glass",random +OBJECT:'*',"worthless piece of orange glass",random +OBJECT:'*',"worthless piece of orange glass",random +OBJECT:'*',"worthless piece of orange glass",random +OBJECT:'*',"worthless piece of orange glass",random + +OBJECT[40%]:'*',"jade",random +OBJECT[40%]:'*',"agate",random +OBJECT[40%]:'*',"fluorite",random +OBJECT[40%]:'*',"jasper",random +OBJECT[40%]:'*',"amethyst",random +OBJECT[40%]:'*',"garnet",random +OBJECT[40%]:'*',"chrysoberyl",random +OBJECT[40%]:'*',"opal",random diff -wur -N nethack-linux/dat/dungeon.def nethack-adventskalender/dat/dungeon.def --- nethack-linux/dat/dungeon.def 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/dat/dungeon.def 2008-08-07 11:10:37.000000000 +0200 @@ -17,6 +17,7 @@ DUNGEON: "The Dungeons of Doom" "D" (25, 5) ALIGNMENT: unaligned BRANCH: "The Gnomish Mines" @ (2, 3) +BRANCH: "Advent Calendar" @ (1, 5) portal %REINCARNATION LEVEL: "rogue" "R" @ (15, 4) LEVEL: "oracle" "O" @ (5, 5) LEVALIGN: neutral @@ -106,7 +107,15 @@ DESCRIPTION: mazelike ALIGNMENT: unaligned LEVEL: "knox" "K" @ (-1, 0) + +# +# The Advent Calendar # +DUNGEON: "Advent Calendar" "none" (1, 0) +DESCRIPTION: mazelike +ALIGNMENT: unaligned +LEVEL: "advcal" "none" @ (-1, 0) + # Vlad's Tower # # It has been removed from Gehennom, and it is surrounded by stone. diff -wur -N nethack-linux/include/config.h nethack-adventskalender/include/config.h --- nethack-linux/include/config.h 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/include/config.h 2008-11-13 21:53:42.000000000 +0100 @@ -351,6 +351,8 @@ /*#define GOLDOBJ */ /* Gold is kept on obj chains - Helge Hafting */ /*#define AUTOPICKUP_EXCEPTIONS */ /* exceptions to autopickup */ +#define ADVENT_CALENDAR + /* End of Section 5 */ #include "global.h" /* Define everything else according to choices above */ diff -wur -N nethack-linux/include/decl.h nethack-adventskalender/include/decl.h --- nethack-linux/include/decl.h 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/include/decl.h 2008-08-07 11:10:37.000000000 +0200 @@ -72,6 +72,9 @@ xchar d_mines_dnum, d_quest_dnum; d_level d_qstart_level, d_qlocate_level, d_nemesis_level; d_level d_knox_level; +#ifdef ADVENT_CALENDAR + d_level d_advcal_level; +#endif } dungeon_topology; /* macros for accesing the dungeon levels by their old names */ #define oracle_level (dungeon_topology.d_oracle_level) @@ -104,6 +107,9 @@ #define qlocate_level (dungeon_topology.d_qlocate_level) #define nemesis_level (dungeon_topology.d_nemesis_level) #define knox_level (dungeon_topology.d_knox_level) +#ifdef ADVENT_CALENDAR +# define advcal_level (dungeon_topology.d_advcal_level) +#endif E NEARDATA stairway dnstair, upstair; /* stairs up and down */ #define xdnstair (dnstair.sx) diff -wur -N nethack-linux/include/dungeon.h nethack-adventskalender/include/dungeon.h --- nethack-linux/include/dungeon.h 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/include/dungeon.h 2008-08-07 11:10:37.000000000 +0200 @@ -121,6 +121,9 @@ #define Is_qlocate(x) (on_level(x, &qlocate_level)) #define Is_nemesis(x) (on_level(x, &nemesis_level)) #define Is_knox(x) (on_level(x, &knox_level)) +#ifdef ADVENT_CALENDAR +#define Is_advent_calendar(x) (on_level(x, &advcal_level)) +#endif #define In_sokoban(x) ((x)->dnum == sokoban_dnum) #define Inhell In_hell(&u.uz) /* now gehennom */ diff -wur -N nethack-linux/include/extern.h nethack-adventskalender/include/extern.h --- nethack-linux/include/extern.h 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/include/extern.h 2008-11-13 23:15:03.000000000 +0100 @@ -741,6 +741,8 @@ E boolean FDECL(fuzzymatch, (const char *,const char *,const char *,BOOLEAN_P)); E void NDECL(setrandom); E int NDECL(getyear); +E int NDECL(getmonth); +E int NDECL(getmday); #if 0 E char *FDECL(yymmdd, (time_t)); #endif @@ -865,6 +867,7 @@ E boolean FDECL(doorlock, (struct obj *,int,int)); E int NDECL(doopen); E int NDECL(doclose); +E int FDECL(artifact_door, (int,int)); #ifdef MAC /* These declarations are here because the main code calls them. */ @@ -1010,6 +1013,9 @@ E void FDECL(mktrap, (int,int,struct mkroom *,coord*)); E void FDECL(mkstairs, (XCHAR_P,XCHAR_P,CHAR_P,struct mkroom *)); E void NDECL(mkinvokearea); +#ifdef ADVENT_CALENDAR +E boolean NDECL(mk_advcal_portal); +#endif /* ### mkmap.c ### */ @@ -1034,6 +1040,10 @@ E void FDECL(restore_waterlevel, (int)); E const char *FDECL(waterbody_name, (XCHAR_P,XCHAR_P)); +#ifdef ADVENT_CALENDAR +E void FDECL(fill_advent_calendar, (boolean)); +#endif + /* ### mkobj.c ### */ E struct obj *FDECL(mkobj_at, (CHAR_P,int,int,BOOLEAN_P)); diff -wur -N nethack-linux/src/dig.c nethack-adventskalender/src/dig.c --- nethack-linux/src/dig.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/dig.c 2008-11-13 21:28:50.000000000 +0100 @@ -173,6 +173,11 @@ if(verbose) pline_The("ladder resists your effort."); } else if(verbose) pline_The("stairs are too hard to %s.", verb); return(FALSE); + /* ALI - Artifact doors */ + } else if (IS_DOOR(levl[x][y].typ) && artifact_door(x, y)) { + if(verbose) pline_The("%s here is too hard to dig in.", + surface(x,y)); + return(FALSE); } else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) { if(verbose) pline_The("throne is too hard to break apart."); return(FALSE); @@ -232,9 +237,12 @@ pline("This tree seems to be petrified."); return(0); } + /* ALI - Artifact doors */ if (IS_ROCK(lev->typ) && !may_dig(dpx,dpy) && - dig_typ(uwep, dpx, dpy) == DIGTYP_ROCK) { - pline("This wall is too hard to %s.", verb); + dig_typ(uwep, dpx, dpy) == DIGTYP_ROCK || + IS_DOOR(lev->typ) && artifact_door(dpx, dpy)) { + pline("This %s is too hard to %s.", + IS_DOOR(lev->typ) ? "door" : "wall", verb); return(0); } } @@ -656,6 +664,8 @@ boolean nohole = !Can_dig_down(&u.uz); if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) || + /* ALI - artifact doors */ + IS_DOOR(levl[u.ux][u.uy].typ) && artifact_door(u.ux, u.uy) || (IS_ROCK(lev->typ) && lev->typ != SDOOR && (lev->wall_info & W_NONDIGGABLE) != 0)) { pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy)); @@ -1207,6 +1217,12 @@ tmp_at(zx,zy); delay_output(); /* wait a little bit */ if (closed_door(zx, zy) || room->typ == SDOOR) { + /* ALI - Artifact doors */ + if (artifact_door(zx, zy)) { + if (cansee(zx, zy)) + pline_The("door glows then fades."); + break; + } if (*in_rooms(zx,zy,SHOPBASE)) { add_damage(zx, zy, 400L); shopdoor = TRUE; diff -wur -N nethack-linux/src/do.c nethack-adventskalender/src/do.c --- nethack-linux/src/do.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/do.c 2008-11-13 21:56:15.000000000 +0100 @@ -1335,6 +1335,16 @@ } } +#ifdef ADVENT_CALENDAR + if ((getmonth()==12) && (getmday() < 25)) { + if (mk_advcal_portal()) + You("smell chocolate!"); + } + if (Is_advent_calendar(&u.uz)) { + fill_advent_calendar(FALSE); + } +#endif + /* once Croesus is dead, his alarm doesn't work any more */ if (Is_knox(&u.uz) && (new || !mvitals[PM_CROESUS].died)) { You("penetrated a high security area!"); diff -wur -N nethack-linux/src/dokick.c nethack-adventskalender/src/dokick.c --- nethack-linux/src/dokick.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/dokick.c 2008-11-13 21:26:57.000000000 +0100 @@ -1041,6 +1041,9 @@ /* not enough leverage to kick open doors while levitating */ if(Levitation) goto ouch; + /* Ali - artifact doors */ + if (artifact_door(x, y)) goto ouch; + exercise(A_DEX, TRUE); /* door is known to be CLOSED or LOCKED */ if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) { diff -wur -N nethack-linux/src/dungeon.c nethack-adventskalender/src/dungeon.c --- nethack-linux/src/dungeon.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/dungeon.c 2008-11-13 21:56:55.000000000 +0100 @@ -609,6 +609,7 @@ const char *lev_name; d_level *lev_spec; } level_map[] = { + { "advcal", &advcal_level }, { "air", &air_level }, { "asmodeus", &asmodeus_level }, { "astral", &astral_level }, @@ -870,6 +871,22 @@ if (br) br->end1.dnum = n_dgns; /* adjust the branch's position on the list */ insert_branch(br, TRUE); +#ifdef ADVENT_CALENDAR + } else if (lev_map->lev_spec == &advcal_level) { + branch *br; + /* + * Kludge to allow floating Knox entrance. We + * specify a floating entrance by the fact that + * its entrance (end1) has a bogus dnum, namely + * n_dgns. + */ + for (br = branches; br; br = br->next) + if (on_level(&br->end2, &advcal_level)) break; + + if (br) br->end1.dnum = n_dgns; + /* adjust the branch's position on the list */ + insert_branch(br, TRUE); +#endif } } } @@ -1646,7 +1663,11 @@ Sprintf(eos(buf), " (tune %s)", tune); if (bymenu) { /* If other floating branches are added, this will need to change */ +#ifdef ADVENT_CALENDAR + if ((i != advcal_level.dnum) && (i != knox_level.dnum)) { +#else if (i != knox_level.dnum) { +#endif lchoices.lev[lchoices.idx] = slev->dlevel.dlevel; lchoices.dgn[lchoices.idx] = i; } else { diff -wur -N nethack-linux/src/hack.c nethack-adventskalender/src/hack.c --- nethack-linux/src/hack.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/hack.c 2008-11-13 21:31:41.000000000 +0100 @@ -584,6 +584,21 @@ } else if (IS_DOOR(tmpr->typ)) { if (closed_door(x,y)) { if (Blind && mode == DO_MOVE) feel_location(x,y); + /* ALI - artifact doors */ + if (artifact_door(x, y)) { + if (mode == DO_MOVE) { + if (amorphous(youmonst.data)) + You("try to ooze under the door, but the gap is too small."); + else if (tunnels(youmonst.data) && !needspick(youmonst.data)) + You("hurt your teeth on the re-enforced door."); + else if (x == u.ux || y == u.uy) { + if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { pline("Ouch! You bump into a heavy door."); + exercise(A_DEX, FALSE); + } else pline("That door is closed."); + } + } + return FALSE; + } else if (Passes_walls) ; /* do nothing */ else if (can_ooze(&youmonst)) { diff -wur -N nethack-linux/src/hacklib.c nethack-adventskalender/src/hacklib.c --- nethack-linux/src/hacklib.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/hacklib.c 2008-10-19 16:09:59.000000000 +0200 @@ -37,6 +37,8 @@ boolean fuzzymatch (const char *,const char *,const char *,boolean) void setrandom (void) int getyear (void) + int getmonth (void) + int getmday (void) char * yymmdd (time_t) long yyyymmdd (time_t) int phase_of_the_moon (void) @@ -508,6 +510,21 @@ return(1900 + getlt()->tm_year); } +/* Returns current month (1-12, 1 = January) */ +int +getmonth() +{ + return(1 + getlt()->tm_mon); +} + +/* Returns current day of month (1-31) */ +int +getmday() +{ + return(getlt()->tm_mday); +} + + #if 0 /* This routine is no longer used since in 2000 it will yield "100mmdd". */ char * diff -wur -N nethack-linux/src/lock.c nethack-adventskalender/src/lock.c --- nethack-linux/src/lock.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/lock.c 2008-11-13 23:24:59.000000000 +0100 @@ -228,6 +228,7 @@ { int picktyp, c, ch; coord cc; + int key; struct rm *door; struct obj *otmp; char qbuf[QBUFSZ]; @@ -400,6 +401,8 @@ return(0); } #endif + /* ALI - Artifact doors */ + key = artifact_door(cc.x, cc.y); Sprintf(qbuf,"%sock it?", (door->doormask & D_LOCKED) ? "Unl" : "L" ); @@ -423,6 +426,20 @@ } xlock.door = door; xlock.box = 0; + + /* ALI - Artifact doors */ +#ifdef ADVENT_CALENDAR + if (key) { +#else + xlock.key = pick->oartifact; + if (key && xlock.key != key) { +#endif + if (picktyp == SKELETON_KEY) { + Your("key doesn't seem to fit."); + return(0); + } + else ch = -1; /* -1 == 0% chance */ + } } } flags.move = 0; @@ -744,6 +761,7 @@ const char *msg = (const char *)0; const char *dustcloud = "A cloud of dust"; const char *quickly_dissipates = "quickly dissipates"; + int key = artifact_door(x, y); /* ALI - Artifact doors */ if (door->typ == SDOOR) { switch (otmp->otyp) { @@ -751,8 +769,12 @@ case SPE_KNOCK: case WAN_STRIKING: case SPE_FORCE_BOLT: + if (key) /* Artifact doors are revealed only */ + cvt_sdoor_to_door(door); + else { door->typ = DOOR; door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); + } newsym(x,y); if (cansee(x,y)) pline("A door appears in the wall!"); if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK) @@ -800,12 +822,21 @@ switch (door->doormask & ~D_TRAPPED) { case D_CLOSED: + if (key) + msg = "The door closes!"; + else msg = "The door locks!"; break; case D_ISOPEN: + if (key) + msg = "The door swings shut!"; + else msg = "The door swings shut, and locks!"; break; case D_BROKEN: + if (key) + msg = "The broken door reassembles!"; + else msg = "The broken door reassembles and locks!"; break; case D_NODOOR: @@ -817,19 +848,22 @@ break; } block_point(x, y); + if (key) + door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); + else door->doormask = D_LOCKED | (door->doormask & D_TRAPPED); newsym(x,y); break; case WAN_OPENING: case SPE_KNOCK: - if (door->doormask & D_LOCKED) { + if (!key && door->doormask & D_LOCKED) { msg = "The door unlocks!"; door->doormask = D_CLOSED | (door->doormask & D_TRAPPED); } else res = FALSE; break; case WAN_STRIKING: case SPE_FORCE_BOLT: - if (door->doormask & (D_LOCKED | D_CLOSED)) { + if (!key && door->doormask & (D_LOCKED | D_CLOSED)) { if (door->doormask & D_TRAPPED) { if (MON_AT(x, y)) (void) mb_trapped(m_at(x,y)); @@ -916,6 +950,34 @@ pline("%s %s!", An(thing), disposition); } +/* ALI - Kevin Hugo's artifact doors. + * Return the artifact which unlocks the door at (x, y), or + * zero if it is an ordinary door. + * Note: Not all doors are listed in the doors array (eg., doors + * dynamically converted from secret doors). Since only trapped + * and artifact doors are needed this isn't a problem. If we ever + * implement trapped secret doors we will have to extend this. + */ + +int +artifact_door(x, y) +int x, y; +{ + int i; + +#ifdef ADVENT_CALENDAR + /* on the advent calendar level all doors are indestructible */ + if (Is_advent_calendar(&u.uz)) return A_NONE; +#endif +/* + for(i = 0; i < doorindex; i++) { + if (x == doors[i].x && y == doors[i].y) + return doors[i].arti_key; + } +*/ + return 0; +} + #endif /* OVLB */ /*lock.c*/ diff -wur -N nethack-linux/src/mklev.c nethack-adventskalender/src/mklev.c --- nethack-linux/src/mklev.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/mklev.c 2008-11-13 23:36:33.000000000 +0100 @@ -1589,4 +1589,58 @@ place_branch(br, x, y); } +#ifdef ADVENT_CALENDAR +/* + * The portal to the Advent Calender is special. + * It does not only lead to a floating branch like knox portal. + * It also may appear upon reentering a existing level if it is the + * right time of the year. + */ +boolean +mk_advcal_portal() +{ + extern int n_dgns; /* from dungeon.c */ + d_level *source; + branch *br; + + /* made_branch remains unchanged when entering a already created + * level. This leads to the branch inserted in the dungeon level + * list but no portal created, the branch is unreachable. + * + * Technically this is a bug but nobody anticipated a branch + * that could be inserted after level creation. + */ + if (made_branch) return FALSE; + + br = dungeon_branch("Advent Calendar"); + if (on_level(&advcal_level, &br->end1)) { + source = &br->end2; + } else { + /* disallow branch on a level with one branch already */ + if(Is_branchlev(&u.uz)) + return FALSE; + source = &br->end1; + } + + /* Already set. */ + if (source->dnum < n_dgns) return FALSE; + + if (! (u.uz.dnum == oracle_level.dnum /* in main dungeon */ + && !at_dgn_entrance("The Quest") /* but not Quest's entry */ + && depth(&u.uz) < depth(&medusa_level))) /* and above Medusa */ + return FALSE; + + /* Adjust source to be current level and re-insert branch. */ + *source = u.uz; + insert_branch(br, TRUE); + +#ifdef DEBUG + pline("Made advent calendar portal."); +#endif + place_branch(br, 0, 0); + + return TRUE; +} +#endif + /*mklev.c*/ diff -wur -N nethack-linux/src/mkmaze.c nethack-adventskalender/src/mkmaze.c --- nethack-linux/src/mkmaze.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/mkmaze.c 2008-11-13 22:51:32.000000000 +0100 @@ -473,6 +473,10 @@ mtmp2 = mtmp->nmon; if(mtmp->isshk) mongone(mtmp); } +#ifdef ADVENT_CALENDAR + } else if (Is_advent_calendar(&u.uz)) { + fill_advent_calendar(TRUE); +#endif } if(lev_message) { @@ -492,6 +496,71 @@ num_lregions = 0; } +#ifdef ADVENT_CALENDAR +void +fill_advent_calendar(init) +boolean init; +{ + int door_nr=1; + char buf[4]; + int x,y; + int in_x,in_y,out_x,out_y; + + for(x = 1; x < COLNO; x++) { + for(y = 1; y < ROWNO; y++) { + if (door_nr < 25 && isok(x,y) && IS_DOOR(levl[x][y].typ)) { + if (y < 10) { + out_x = x; out_y = y+1; in_x = x; in_y = y-1; + } else { + out_x = x; out_y = y-1; in_x = x; in_y = y+1; + } + if (init) { + sprintf(buf, "%d", door_nr); + /* place number in front of the door */ + make_engr_at(out_x, out_y, buf, 0L, MARK); + if (door_nr == 24) { + int object = CANDY_BAR; + /* Christmas present! */ + switch(rn2(15)) { + case 0: object = BAG_OF_HOLDING; break; + case 1: object = OILSKIN_SACK; break; + case 2: object = FIRE_HORN; break; + case 3: object = FROST_HORN; break; + case 4: object = MAGIC_FLUTE; break; + case 5: object = MAGIC_HARP; break; + case 6: object = DRUM_OF_EARTHQUAKE; break; + case 7: object = MAGIC_WHISTLE; break; + case 8: object = MAGIC_LAMP; break; + case 9: object = UNICORN_HORN; break; + case 10: object = BAG_OF_TRICKS; break; + case 11: object = EXPENSIVE_CAMERA; break; + case 12: object = HORN_OF_PLENTY; break; + case 13: object = STETHOSCOPE; break; + case 14: object = TINNING_KIT; break; + } + mksobj_at(object, in_x, in_y, TRUE, TRUE); + } else if (rn2(4)) { + mksobj_at((rn2(4)) ? CANDY_BAR : FORTUNE_COOKIE, in_x, in_y, FALSE, FALSE); + } else { + mkobj_at((rn2(4)) ? RING_CLASS : TOOL_CLASS, in_x, in_y, FALSE); + } + } + if (levl[x][y].doormask & D_LOCKED && getmonth() == 12) { + if (getmday() == 24 && door_nr == 24) { + You_hear("a little bell ringing!"); + levl[x][y].doormask = D_CLOSED; + } else if (getmday() == door_nr) { + You_hear("a door unlocking!"); + levl[x][y].doormask = D_CLOSED; + } + } + door_nr++; + } + } + } +} +#endif + void makemaz(s) register const char *s; diff -wur -N nethack-linux/src/music.c nethack-adventskalender/src/music.c --- nethack-linux/src/music.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/music.c 2008-11-13 21:22:02.000000000 +0100 @@ -332,6 +332,8 @@ } else newsym(x,y); break; case DOOR : /* Make the door collapse */ + /* ALI - artifact doors */ + if (artifact_door(x, y)) break; if (levl[x][y].doormask == D_NODOOR) goto do_pit; if (cansee(x,y)) pline_The("door collapses."); diff -wur -N nethack-linux/src/trap.c nethack-adventskalender/src/trap.c --- nethack-linux/src/trap.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/trap.c 2008-11-13 21:25:28.000000000 +0100 @@ -1288,7 +1288,9 @@ (struct obj *)0); del_engr_at(trap->tx, trap->ty); wake_nearto(trap->tx, trap->ty, 400); - if (IS_DOOR(levl[trap->tx][trap->ty].typ)) + /* ALI - artifact doors */ + if (IS_DOOR(levl[trap->tx][trap->ty].typ) && + !artifact_door(trap->tx, trap->ty)) levl[trap->tx][trap->ty].doormask = D_BROKEN; /* TODO: destroy drawbridge if present */ /* caller may subsequently fill pit, e.g. with a boulder */ diff -wur -N nethack-linux/src/zap.c nethack-adventskalender/src/zap.c --- nethack-linux/src/zap.c 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/src/zap.c 2008-11-13 21:24:11.000000000 +0100 @@ -3675,6 +3675,9 @@ int new_doormask = -1; const char *see_txt = 0, *sense_txt = 0, *hear_txt = 0; rangemod = -1000; + /* ALI - Artifact doors */ + if (artifact_door(x, y)) + goto def_case; switch(abstype) { case ZT_FIRE: new_doormask = D_NODOOR; diff -wur -N nethack-linux/sys/unix/Makefile.dat nethack-adventskalender/sys/unix/Makefile.dat --- nethack-linux/sys/unix/Makefile.dat 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/sys/unix/Makefile.dat 2008-10-19 16:39:16.000000000 +0200 @@ -102,6 +102,7 @@ spec_levs: ../util/lev_comp \ bigroom.des castle.des endgame.des gehennom.des knox.des medusa.des \ mines.des oracle.des sokoban.des tower.des yendor.des + ../util/lev_comp advcal.des ../util/lev_comp bigroom.des ../util/lev_comp castle.des ../util/lev_comp endgame.des diff -wur -N nethack-linux/sys/unix/Makefile.top nethack-adventskalender/sys/unix/Makefile.top --- nethack-linux/sys/unix/Makefile.top 2008-05-26 19:47:02.000000000 +0200 +++ nethack-adventskalender/sys/unix/Makefile.top 2008-10-19 16:30:40.000000000 +0200 @@ -77,6 +77,7 @@ juiblex.lev knox.lev medusa-?.lev minend-?.lev minefill.lev \ minetn-?.lev oracle.lev orcus.lev sanctum.lev soko?-?.lev \ tower?.lev valley.lev wizard?.lev \ + advcal.lev \ astral.lev air.lev earth.lev fire.lev water.lev QUEST_LEVS = ???-goal.lev ???-fil?.lev ???-loca.lev ???-strt.lev