diff --git a/include/extern.h b/include/extern.h index 4ad7d6a59..b5e8d46e5 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1580633720 2020/02/02 08:55:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.787 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1581322657 2020/02/10 08:17:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.795 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -994,7 +994,9 @@ E void FDECL(youhiding, (BOOLEAN_P, int)); E char *FDECL(trap_predicament, (char *, int, BOOLEAN_P)); E int NDECL(doconduct); E void FDECL(show_conduct, (int)); -E int NDECL(count_uachieve); +E void FDECL(record_achievement, (XCHAR_P)); +E boolean FDECL(remove_achievement, (XCHAR_P)); +E int NDECL(count_achievements); E int NDECL(dovanquished); E void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P)); E int NDECL(num_genocides); diff --git a/include/patchlevel.h b/include/patchlevel.h index f0be24851..acc3b457e 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 patchlevel.h $NHDT-Date: 1580437691 2020/01/31 02:28:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.155 $ */ +/* NetHack 3.7 patchlevel.h $NHDT-Date: 1581322658 2020/02/10 08:17:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.156 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,7 +14,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 13 +#define EDITLEVEL 14 #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020" #define COPYRIGHT_BANNER_B \ diff --git a/include/you.h b/include/you.h index 611fcf3b1..f017f0e0c 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 you.h $NHDT-Date: 1574648937 2019/11/25 02:28:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 3.6 you.h $NHDT-Date: 1581322658 2020/02/10 08:17:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -54,17 +54,25 @@ struct u_event { Bitfield(ascended, 1); /* has offered the Amulet */ }; -struct u_achieve { - Bitfield(amulet, 1); /* touched Amulet */ - Bitfield(bell, 1); /* touched Bell */ - Bitfield(book, 1); /* touched Book */ - Bitfield(menorah, 1); /* touched Candelabrum */ - Bitfield(enter_gehennom,1); /* entered Gehennom (or Valley) by any means */ - Bitfield(ascended, 1); /* not quite the same as u.uevent.ascended */ - Bitfield(mines_luckstone, 1); /* got a luckstone at end of mines */ - Bitfield(finish_sokoban, 1); /* obtained the sokoban prize */ - - Bitfield(killed_medusa, 1); +/* numerical order of these matters because they've been encoded in a + bitmask in xlogfile; reordering would break decoding that; during play + the number doesn't matter--they're recorded in the order achieved */ +enum achivements { + ACH_BELL = 1, /* acquired Bell of Opening */ + ACH_HELL = 2, /* entered Gehennom */ + ACH_CNDL = 3, /* acquired Candelabrum of Invocation */ + ACH_BOOK = 4, /* acquired Book of the Dead */ + ACH_INVK = 5, /* performed invocation to gain access to Sanctum */ + ACH_AMUL = 6, /* acuired The Amulet */ + ACH_ENDG = 7, /* entered end game */ + ACH_ASTR = 8, /* entered Astral Plane */ + ACH_UWIN = 9, /* ascended */ + ACH_LUCK = 10, /* acquired Mines' End luckstone */ + ACH_SOKO = 11, /* acquired Sokoban bag of holding or amu of reflection */ + ACH_MEDU = 12, /* killed Medusa */ + ACH_BLND = 13, /* hero was always blond, no, blind */ + ACH_NUDE = 14, /* hero never wore armor */ + N_ACH }; struct u_realtime { @@ -346,7 +354,6 @@ struct you { /* 1 free bit! */ unsigned udg_cnt; /* how long you have been demigod */ - struct u_achieve uachieve; /* achievements */ struct u_event uevent; /* certain events have happened */ struct u_have uhave; /* you're carrying special objects */ struct u_conduct uconduct; /* KMH, conduct */ @@ -399,7 +406,7 @@ struct you { struct skills weapon_skills[P_NUM_SKILLS]; boolean twoweap; /* KMH -- Using two-weapon combat */ short mcham; /* vampire mndx if shapeshifted to bat/cloud */ - + xchar uachieved[N_ACH]; /* list of achievements in the order attained */ }; /* end of `struct you' */ #define Upolyd (u.umonnum != u.umonster) diff --git a/src/cmd.c b/src/cmd.c index 4264e1e28..94d5e245b 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1579914040 2020/01/25 01:00:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.394 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1581322659 2020/02/10 08:17:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.398 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -792,16 +792,12 @@ boolean pre, wiztower; static const char Unachieve[] = "%s achievement revoked."; if (Is_mineend_level(&u.uz)) { - if (u.uachieve.mines_luckstone) { + if (remove_achievement(ACH_LUCK)) pline(Unachieve, "Mine's end"); - u.uachieve.mines_luckstone = 0; - } g.context.achieveo.mines_prize_oid = 0; } else if (Is_sokoend_level(&u.uz)) { - if (u.uachieve.finish_sokoban) { + if (remove_achievement(ACH_SOKO)) pline(Unachieve, "Sokoban end"); - u.uachieve.finish_sokoban = 0; - } g.context.achieveo.soko_prize_oid = 0; } } diff --git a/src/do.c b/src/do.c index 2a58939f2..70d51f8da 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1580608377 2020/02/02 01:52:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.222 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1581322660 2020/02/10 08:17:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.224 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1039,8 +1039,7 @@ dodown() pline("Unspeakable cruelty and harm lurk down there."); if (yn("Are you sure you want to enter?") != 'y') return 0; - else - pline("So be it."); + pline("So be it."); u.uevent.gehennom_entered = 1; /* don't ask again */ } @@ -1642,7 +1641,8 @@ boolean at_stairs, falling, portal; You_hear("groans and moans everywhere."); } else pline("It is hot here. You smell smoke..."); - u.uachieve.enter_gehennom = 1; + + record_achievement(ACH_HELL); /* reached Gehennom */ } /* in case we've managed to bypass the Valley's stairway down */ if (Inhell && !Is_valley(&u.uz)) @@ -1677,10 +1677,14 @@ boolean at_stairs, falling, portal; /* special location arrival messages/events */ if (In_endgame(&u.uz)) { - if (new &&on_level(&u.uz, &astral_level)) + if (newdungeon) + record_achievement(ACH_ENDG); /* reached endgame */ + if (new && on_level(&u.uz, &astral_level)) { final_level(); /* guardian angel,&c */ - else if (newdungeon && u.uhave.amulet) + record_achievement(ACH_ASTR); /* reached Astral level */ + } else if (newdungeon && u.uhave.amulet) { resurrect(); /* force confrontation with Wizard */ + } } else if (In_quest(&u.uz)) { onquest(); /* might be reaching locate|goal level */ } else if (In_V_tower(&u.uz)) { diff --git a/src/end.c b/src/end.c index f10e0f424..cc328e6eb 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 end.c $NHDT-Date: 1575245059 2019/12/02 00:04:19 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.181 $ */ +/* NetHack 3.6 end.c $NHDT-Date: 1581322661 2020/02/10 08:17:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.206 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -812,7 +812,7 @@ boolean taken; if (!done_stopprint) { if (should_query_disclose_option('c', &defquery)) { - int acnt = count_uachieve(); + int acnt = count_achievements(); Sprintf(qbuf, "Do you want to see your conduct%s%s?", (acnt > 0) ? " and achievement" : "", @@ -1222,6 +1222,17 @@ int how; iflags.at_night = night(); iflags.at_midnight = midnight(); + /* final achievement tracking; only show blind and nudist if some + tangible progress has been made; always show ascension last */ + if (u.uachieved[0] || !flags.beginner) { + if (u.uroleplay.blind) + record_achievement(ACH_BLND); /* blind the whole game */ + if (u.uroleplay.nudist) + record_achievement(ACH_NUDE); /* never wore armor */ + } + if (how == ASCENDED) + record_achievement(ACH_UWIN); + dump_open_log(endtime); /* Sometimes you die on the first move. Life's not fair. * On those rare occasions you get hosed immediately, go out @@ -1592,6 +1603,7 @@ int how; * score list?" */ if (have_windows && !iflags.toptenwin) exit_nhwindows((char *) 0), have_windows = FALSE; + /* update 'logfile' and 'xlogfile', if enabled, and maybe 'record' */ topten(how, endtime); if (have_windows) exit_nhwindows((char *) 0); diff --git a/src/insight.c b/src/insight.c index 62ee93607..153f4df07 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1580577249 2020/02/01 17:14:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1581322662 2020/02/10 08:17:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1698,51 +1698,17 @@ int final; g.en_win = WIN_ERR; } -/* uses to decide whether there are any achievements to display */ -int -count_uachieve() -{ - int acnt = 0; - - /* these tests must be kept in sync with show_achievements() */ - if (u.uroleplay.blind) - ++acnt; - if (u.uroleplay.nudist) - ++acnt; - if (u.uachieve.mines_luckstone) - ++acnt; - if (u.uachieve.finish_sokoban) - ++acnt; - if (u.uachieve.killed_medusa) - ++acnt; - if (u.uachieve.bell) - ++acnt; - if (u.uachieve.enter_gehennom) - ++acnt; - if (u.uachieve.menorah) - ++acnt; - if (u.uachieve.book) - ++acnt; - if (u.uevent.invoked) - ++acnt; - if (u.uachieve.amulet) - ++acnt; - if (In_endgame(&u.uz)) - ++acnt; - if (Is_astralevel(&u.uz)) - ++acnt; - if (u.uachieve.ascended) - ++acnt; - - return acnt; -} +/* + * Achievements (see 'enum achievements' in you.h). + */ static void show_achievements(final) -int final; +int final; /* used "behind the curtain" by enl_foo() macros */ { - int acnt; + int i, achidx, acnt; char title[BUFSZ]; + boolean ach_amulet = FALSE; winid awin = WIN_ERR; /* unfortunately we can't show the achievements (at least not all of @@ -1754,7 +1720,7 @@ int final; /* first, figure whether any achievements have been accomplished so that we don't show the header for them if the resulting list below it would be empty */ - if ((acnt = count_uachieve()) == 0) + if ((acnt = count_achievements()) == 0) return; if (g.en_win != WIN_ERR) { @@ -1765,67 +1731,105 @@ int final; } Sprintf(title, "Achievement%s:", plur(acnt)); putstr(awin, 0, title); - /* after 'blind' and 'nudist', which are the easiest if you die but - the hardest if you ascend, they're arranged in approximate order - of difficulty */ - if (u.uroleplay.blind) - enl_msg(You_, "are exploring", "explored", - " without being able to see", ""); - if (u.uroleplay.nudist) - enl_msg(You_, "have gone", "went", " without any armor", ""); - if (u.uachieve.mines_luckstone) - enl_msg(You_, "have ", "", "completed the Gnomish Mines", ""); - if (u.uachieve.finish_sokoban) - enl_msg(You_, "have ", "", "completed Sokoban", ""); - if (u.uachieve.killed_medusa) - enl_msg(You_, "have ", "", "defeated Medusa", ""); - if (u.uachieve.bell) { - /* alternate phrasing for present vs past and also for possessing - the item vs once held it */ - enl_msg(You_, - u.uhave.bell ? "have" : "have handled", - u.uhave.bell ? "had" : "handled", - " the Bell of Opening", ""); - } - /* wording is clumsy but the game is inconsistent about "entering - Gehennom"; the Valley is part of Gehennom but the message about - entering Gehennom is given when descending from the Valley to the - level below and that's also when the flag about entering gets set */ - if (u.uachieve.enter_gehennom) - enl_msg(You_, "have ", "", "passed the Valley of the Dead", ""); - if (u.uachieve.menorah) { - enl_msg(You_, - u.uhave.menorah ? "have" : "have handled", - u.uhave.menorah ? "had" : "handled", - " the Candelabrum of Invocation", ""); - } - if (u.uachieve.book) { - enl_msg(You_, - u.uhave.book ? "have" : "have handled", - u.uhave.book ? "had" : "handled", - " the Book of the Dead", ""); - } - if (u.uevent.invoked) - enl_msg(You_, "have ", "", "gained access to Moloch's Sanctum", ""); - if (u.uachieve.amulet) { - /* extra alternate wording for past tense because ascension - requires giving up the Amulet */ - enl_msg(You_, - u.uhave.amulet ? "have" : "have obtained", - u.uachieve.ascended ? "delivered" - : u.uhave.amulet ? "had" : "had obtained", - " the Amulet of Yendor", ""); + /* display achievements in the order in which they were recorded; + lone exception is to defer the Amulet (by taking it out of list) + if we just ascended; it warrants alternate wording when given + away during ascension, but the Amulet achievement is always + attained before entering endgame and the alternate wording looks + strange if shown before "reached endgame" and "reached Astral" */ + if (remove_achievement(ACH_UWIN)) { /* UWIN == Ascended! */ + ach_amulet = remove_achievement(ACH_AMUL); + record_achievement(ACH_UWIN); /* put back; always last when present */ + acnt = count_achievements(); } + for (i = 0; i < acnt; ++i) { + achidx = u.uachieved[i]; - /* reaching Astral makes feedback about reaching the Planes be redundant - and asceding makes both be redundant, but we display all that apply */ - if (In_endgame(&u.uz)) - enl_msg(You_, "have ", "", "reached the Elemental Planes", ""); - if (Is_astralevel(&u.uz)) - enl_msg(You_, "have ", "", "reached the Astral Plane", ""); - if (u.uachieve.ascended) - enlght_out(" You ascended!"); + switch (achidx) { + case ACH_BLND: + enl_msg(You_, "are exploring", "explored", + " without being able to see", ""); + break; + case ACH_NUDE: + enl_msg(You_, "have gone", "went", " without any armor", ""); + break; + case ACH_LUCK: + enl_msg(You_, "have ", "", "completed the Gnomish Mines", ""); + break; + case ACH_SOKO: + enl_msg(You_, "have ", "", "completed Sokoban", ""); + break; + case ACH_MEDU: + enl_msg(You_, "have ", "", "defeated Medusa", ""); + break; + case ACH_BELL: + /* alternate phrasing for present vs past and also for + possessing the item vs once held it */ + enl_msg(You_, + u.uhave.bell ? "have" : "have handled", + u.uhave.bell ? "had" : "handled", + " the Bell of Opening", ""); + break; + case ACH_HELL: + enl_msg(You_, "have ", "", "entered Gehennom", ""); + break; + case ACH_CNDL: + enl_msg(You_, + u.uhave.menorah ? "have" : "have handled", + u.uhave.menorah ? "had" : "handled", + " the Candelabrum of Invocation", ""); + break; + case ACH_BOOK: + enl_msg(You_, + u.uhave.book ? "have" : "have handled", + u.uhave.book ? "had" : "handled", + " the Book of the Dead", ""); + break; + case ACH_INVK: + enl_msg(You_, "have ", "", + "gained access to Moloch's Sanctum", ""); + break; + case ACH_AMUL: + /* note: we won't get here if ACH_UWIN is going to be shown */ + enl_msg(You_, + u.uhave.amulet ? "have" : "have obtained", + u.uhave.amulet ? "had" : "had obtained", + " the Amulet of Yendor", ""); + break; + + /* reaching Astral makes feedback about reaching the Planes + be redundant and ascending makes both be redundant, but + we display all that apply */ + case ACH_ENDG: + enl_msg(You_, "have ", "", "reached the Elemental Planes", ""); + break; + case ACH_ASTR: + enl_msg(You_, "have ", "", "reached the Astral Plane", ""); + break; + case ACH_UWIN: + /* if we took Amulet achievement out of the list, show it now; + always uses past tense here since game ends upon ascension */ + if (ach_amulet) + enl_msg(You_, "?", "delivered", " the Amulet of Yendor", ""); + /* the ultimate achievement... */ + enlght_out(" You ascended!"); + break; + default: + /* title[] has served its purpose, reuse it as a scratch buffer */ + Sprintf(title, " [Unexpected achievement #%d.]", achidx); + enlght_out(title); + break; + } /* switch */ + } /* for */ +#ifdef XLOGFILE + /* if we removed the Amulet achievement because of ascension, put it + back for encoding in the achievements field of xlogfile; it will + change position from the original ordering but that doesn't matter + to the bitmask which is going to be constructed and logged */ + if (ach_amulet) + record_achievement(ACH_AMUL); +#endif if (awin != g.en_win) { display_nhwindow(awin, TRUE); @@ -1833,6 +1837,65 @@ int final; } } +/* record an achievement (add at end of list unless already present) */ +void +record_achievement(achidx) +xchar achidx; +{ + int i; + + /* valid achievements range from 1 to N_ACH-1 */ + if (achidx < 1 || achidx >= N_ACH) { + impossible("Achievement #%d is out of range.", achidx); + return; + } + + /* the list has an extra slot so there is always at least one 0 at + its end (more than one unless all N_ACH-1 possible achievements + have been recorded); find first empty slot or achievement #achidx; + an attempt to duplicate an achievement can happen if any of Bell, + Candelabrum, Book, or Amulet is dropped then picked up again */ + for (i = 0; u.uachieved[i]; ++i) + if (u.uachieved[i] == achidx) + return; /* already recorded, don't duplicate it */ + u.uachieved[i] = achidx; + return; +} + +/* discard a recorded achievement; return True if removed, False otherwise */ +boolean +remove_achievement(achidx) +xchar achidx; +{ + int i; + + for (i = 0; u.uachieved[i]; ++i) + if (u.uachieved[i] == achidx) + break; /* stop when found */ + if (!u.uachieved[i]) /* not found */ + return FALSE; + /* list is 0 terminated so any beyond the removed one move up a slot */ + do { + u.uachieved[i] = u.uachieved[i + 1]; + } while (u.uachieved[++i]); + return TRUE; +} + +/* used to decide whether there are any achievements to display */ +int +count_achievements() +{ + int i, acnt = 0; + + for (i = 0; u.uachieved[i]; ++i) + ++acnt; + return acnt; +} + +/* + * Vanquished monsters. + */ + static const char *vanqorders[NUM_VANQ_ORDER_MODES] = { "traditional: by monster level, by internal monster index", "by monster toughness, by internal monster index", diff --git a/src/invent.c b/src/invent.c index 084cd472e..51568945e 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1580476196 2020/01/31 13:09:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1581322662 2020/02/10 08:17:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.290 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -810,22 +810,22 @@ struct obj *obj; if (u.uhave.amulet) impossible("already have amulet?"); u.uhave.amulet = 1; - u.uachieve.amulet = 1; + record_achievement(ACH_AMUL); } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) { if (u.uhave.menorah) impossible("already have candelabrum?"); u.uhave.menorah = 1; - u.uachieve.menorah = 1; + record_achievement(ACH_CNDL); } else if (obj->otyp == BELL_OF_OPENING) { if (u.uhave.bell) impossible("already have silver bell?"); u.uhave.bell = 1; - u.uachieve.bell = 1; + record_achievement(ACH_BELL); } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { if (u.uhave.book) impossible("already have the book?"); u.uhave.book = 1; - u.uachieve.book = 1; + record_achievement(ACH_BOOK); } else if (obj->oartifact) { if (is_quest_artifact(obj)) { if (u.uhave.questart) @@ -839,12 +839,12 @@ struct obj *obj; /* "special achievements"; revealed in end of game disclosure and dumplog, originally just recorded in XLOGFILE */ if (is_mines_prize(obj)) { - u.uachieve.mines_luckstone = 1; - g.context.achieveo.mines_prize_oid = 0; + record_achievement(ACH_LUCK); + g.context.achieveo.mines_prize_oid = 0; /* done with luckstone o_id */ obj->nomerge = 0; } else if (is_soko_prize(obj)) { - u.uachieve.finish_sokoban = 1; - g.context.achieveo.soko_prize_oid = 0; + record_achievement(ACH_SOKO); + g.context.achieveo.soko_prize_oid = 0; /* done with bag/amulet o_id */ obj->nomerge = 0; } } diff --git a/src/mon.c b/src/mon.c index e2d571f5e..d528a911c 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1580044343 2020/01/26 13:12:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.320 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1581322664 2020/02/10 08:17:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.321 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2065,7 +2065,7 @@ register struct monst *mtmp; if (mtmp->data->msound == MS_NEMESIS) nemdead(); if (mtmp->data == &mons[PM_MEDUSA]) - u.uachieve.killed_medusa = 1; + record_achievement(ACH_MEDU); if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) unmap_object(mtmp->mx, mtmp->my); m_detach(mtmp, mptr); diff --git a/src/pray.c b/src/pray.c index 3d4045141..b098311d4 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pray.c $NHDT-Date: 1579401997 2020/01/19 02:46:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ +/* NetHack 3.6 pray.c $NHDT-Date: 1581322665 2020/02/10 08:17:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1516,7 +1516,6 @@ dosacrifice() /* The final Test. Did you win? */ if (uamul == otmp) Amulet_off(); - u.uevent.ascended = 1; if (carried(otmp)) useup(otmp); /* well, it's gone now */ else @@ -1552,8 +1551,8 @@ dosacrifice() pline(cloud_of_smoke, hcolor(NH_ORANGE)); done(ESCAPED); } else { /* super big win */ + u.uevent.ascended = 1; adjalign(10); - u.uachieve.ascended = 1; pline( "An invisible choir sings, and you are bathed in radiance..."); godvoice(altaralign, "Mortal, thou hast done well!"); @@ -1564,6 +1563,7 @@ dosacrifice() flags.female ? "dess" : ""); done(ASCENDED); } + /*NOTREACHED*/ } } /* real Amulet */ diff --git a/src/spell.c b/src/spell.c index 4b5e03594..11718e3c0 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 spell.c $NHDT-Date: 1546565814 2019/01/04 01:36:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.88 $ */ +/* NetHack 3.6 spell.c $NHDT-Date: 1581322667 2020/02/10 08:17:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ @@ -259,6 +259,7 @@ struct obj *book2; /* successful invocation */ mkinvokearea(); u.uevent.invoked = 1; + record_achievement(ACH_INVK); /* in case you haven't killed the Wizard yet, behave as if you just did */ u.uevent.udemigod = 1; /* wizdead() */ diff --git a/src/topten.c b/src/topten.c index b2c163d69..1581cd4dc 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 topten.c $NHDT-Date: 1579914041 2020/01/25 01:00:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 3.6 topten.c $NHDT-Date: 1581322668 2020/02/10 08:17:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -428,6 +428,7 @@ encodeconduct() static long encodeachieve() { + int i, ilimit; long r = 0L; /* @@ -469,34 +470,9 @@ encodeachieve() * the dungeon overview but both of those things go away as soon as * the program exits. */ - if (u.uachieve.bell) - r |= 1L << 0; - if (u.uachieve.enter_gehennom) - r |= 1L << 1; - if (u.uachieve.menorah) - r |= 1L << 2; - if (u.uachieve.book) - r |= 1L << 3; - if (u.uevent.invoked) - r |= 1L << 4; - if (u.uachieve.amulet) - r |= 1L << 5; - if (In_endgame(&u.uz)) - r |= 1L << 6; - if (Is_astralevel(&u.uz)) - r |= 1L << 7; - if (u.uachieve.ascended) - r |= 1L << 8; - if (u.uachieve.mines_luckstone) - r |= 1L << 9; - if (u.uachieve.finish_sokoban) - r |= 1L << 10; - if (u.uachieve.killed_medusa) - r |= 1L << 11; - if (u.uroleplay.blind) - r |= 1L << 12; - if (u.uroleplay.nudist) - r |= 1L << 13; + ilimit = min(N_ACH, 32 - 1); /* 32: portable limit for 'long' */ + for (i = 0; i < ilimit && u.uachieved[i]; ++i) + r |= 1L << (u.uachieved[i] - 1); return r; }