From: PatR Date: Sun, 27 Feb 2022 09:55:25 +0000 (-0800) Subject: new achievement: drawbridge tune X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a3b52bf6a37f42fec4101ccde58bbca2228b4e37;p=nethack new achievement: drawbridge tune Use up the last available bit for achievements: "You learned the tune to open and close the castle's drawbridge." (More can still be added but xlogfile will need another field to track a second set of 31 in order to keep its achievement bitmask(s) within portable size.) As achievements go, it's not very exciting, but players who normally destroy the drawbridge have to choose whether to earn an achievement first since once it's gone, there's no way to find out the tune (either via prayer reward or successful Mastermind). I'm guessing that most will probably decide to ignore this achievement since it has no effect on the outcome of the game. However, that might not be true for future tournament play. There's no need to bump EDITLEVEL for this; room for recording one additional achievement is already allocated. --- diff --git a/include/you.h b/include/you.h index a563a4063..b088fedb3 100644 --- a/include/you.h +++ b/include/you.h @@ -98,7 +98,7 @@ enum achivements { so that disclosing them can use the gender which applied at the time */ ACH_RNK1 = 23, ACH_RNK2 = 24, ACH_RNK3 = 25, ACH_RNK4 = 26, ACH_RNK5 = 27, ACH_RNK6 = 28, ACH_RNK7 = 29, ACH_RNK8 = 30, - /* foo=31, 1 available potential achievement; #32 currently off-limits */ + ACH_TUNE = 31, /* discovered the castle drawbridge's open/close tune */ N_ACH = 32 /* allocate room for 31 plus a slot for 0 terminator */ }; /* @@ -117,7 +117,6 @@ enum achivements { * entered Fort Ludios level/branch (not guaranteed to be achieveable), * entered Medusa level, * entered castle level, - * opened castle drawbridge, * obtained castle wand (handle similarly to mines and sokoban prizes), * passed Valley level (entered-Gehennom already covers Valley itself), * [assorted demon lairs?], diff --git a/src/insight.c b/src/insight.c index 10bd74dd2..9624fb834 100644 --- a/src/insight.c +++ b/src/insight.c @@ -2183,6 +2183,10 @@ show_achievements( case ACH_MEDU: you_have_X("defeated Medusa"); break; + case ACH_TUNE: + you_have_X( + "learned the tune to open and close the Castle's drawbridge"); + break; case ACH_BELL: /* alternate phrasing for present vs past and also for possessing the item vs once held it */ diff --git a/src/music.c b/src/music.c index f471210c8..9cd41d124 100644 --- a/src/music.c +++ b/src/music.c @@ -744,17 +744,20 @@ do_play_instrument(struct obj* instr) if (!strcmp(buf, g.tune)) { /* Search for the drawbridge */ for (y = u.uy - 1; y <= u.uy + 1; y++) - for (x = u.ux - 1; x <= u.ux + 1; x++) - if (isok(x, y)) - if (find_drawbridge(&x, &y)) { - /* tune now fully known */ - u.uevent.uheard_tune = 2; - if (levl[x][y].typ == DRAWBRIDGE_DOWN) - close_drawbridge(x, y); - else - open_drawbridge(x, y); - return ECMD_TIME; - } + for (x = u.ux - 1; x <= u.ux + 1; x++) { + if (!isok(x, y)) + continue; + if (find_drawbridge(&x, &y)) { + /* tune now fully known */ + u.uevent.uheard_tune = 2; + record_achievement(ACH_TUNE); + if (levl[x][y].typ == DRAWBRIDGE_DOWN) + close_drawbridge(x, y); + else + open_drawbridge(x, y); + return ECMD_TIME; + } + } } else if (!Deaf) { if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1; @@ -804,8 +807,10 @@ do_play_instrument(struct obj* instr) /* could only get `gears == 5' by playing five correct notes followed by excess; otherwise, tune would have matched above */ - if (gears == 5) + if (gears == 5) { u.uevent.uheard_tune = 2; + record_achievement(ACH_TUNE); + } } } } diff --git a/src/pray.c b/src/pray.c index d12b848cb..44f0c6e50 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1068,7 +1068,7 @@ pleased(aligntyp g_align) if (!u.uevent.uopened_dbridge && !u.uevent.gehennom_entered) { if (u.uevent.uheard_tune < 1) { godvoice(g_align, (char *) 0); - verbalize("Hark, %s!", g.youmonst.data->mlet == S_HUMAN + verbalize("Hark, %s!", (g.youmonst.data->mlet == S_HUMAN) ? "mortal" : "creature"); verbalize( @@ -1079,6 +1079,7 @@ pleased(aligntyp g_align) You_hear("a divine music..."); pline("It sounds like: \"%s\".", g.tune); u.uevent.uheard_tune++; + record_achievement(ACH_TUNE); break; } } diff --git a/src/topten.c b/src/topten.c index 62ae49a4e..f15aeb349 100644 --- a/src/topten.c +++ b/src/topten.c @@ -72,8 +72,8 @@ static long encodexlogflags(void); static long encodeconduct(void); static long encodeachieve(boolean); static void add_achieveX(char *, const char *, boolean); -static char *encode_extended_achievements(void); -static char *encode_extended_conducts(void); +static char *encode_extended_achievements(char *); +static char *encode_extended_conducts(char *); #endif static void free_ttlist(struct toptenentry *); static int classmon(char *); @@ -339,6 +339,7 @@ writexlentry(FILE* rfile, struct toptenentry* tt, int how) #define Fprintf (void) fprintf #define XLOG_SEP '\t' /* xlogfile field separator. */ char buf[BUFSZ], tmpbuf[DTHSZ + 1]; + char achbuf[N_ACH * 40]; Sprintf(buf, "version=%d.%d.%d", tt->ver_major, tt->ver_minor, tt->patchlevel); @@ -364,8 +365,10 @@ writexlentry(FILE* rfile, struct toptenentry* tt, int how) Fprintf(rfile, "%cconduct=0x%lx%cturns=%ld%cachieve=0x%lx", XLOG_SEP, encodeconduct(), XLOG_SEP, g.moves, XLOG_SEP, encodeachieve(FALSE)); - Fprintf(rfile, "%cachieveX=%s", XLOG_SEP, encode_extended_achievements()); - Fprintf(rfile, "%cconductX=%s", XLOG_SEP, encode_extended_conducts()); + Fprintf(rfile, "%cachieveX=%s", XLOG_SEP, + encode_extended_achievements(achbuf)); + Fprintf(rfile, "%cconductX=%s", XLOG_SEP, + encode_extended_conducts(buf)); /* reuse 'buf[]' */ Fprintf(rfile, "%crealtime=%ld%cstarttime=%ld%cendtime=%ld", XLOG_SEP, urealtime.realtime, XLOG_SEP, timet_to_seconds(ubirthday), XLOG_SEP, @@ -466,7 +469,7 @@ encodeachieve( /* add the achievement or conduct comma-separated to string */ static void -add_achieveX(char* buf, const char* achievement, boolean condition) +add_achieveX(char *buf, const char *achievement, boolean condition) { if (condition) { if (buf[0] != '\0') { @@ -477,9 +480,8 @@ add_achieveX(char* buf, const char* achievement, boolean condition) } static char * -encode_extended_achievements(void) +encode_extended_achievements(char *buf) { - static char buf[N_ACH * 40]; char rnkbuf[40]; const char *achievement = NULL; int i, achidx, absidx; @@ -549,6 +551,9 @@ encode_extended_achievements(void) case ACH_BGRM: achievement = "entered_bigroom"; break; + case ACH_TUNE: + achievement = "learned_castle_drawbridge_tune"; + break; /* rank 0 is the starting condition, not an achievement; 8 is Xp 30 */ case ACH_RNK1: case ACH_RNK2: case ACH_RNK3: case ACH_RNK4: case ACH_RNK5: case ACH_RNK6: case ACH_RNK7: case ACH_RNK8: @@ -568,10 +573,8 @@ encode_extended_achievements(void) } static char * -encode_extended_conducts(void) +encode_extended_conducts(char *buf) { - static char buf[BUFSZ]; - buf[0] = '\0'; add_achieveX(buf, "foodless", !u.uconduct.food); add_achieveX(buf, "vegan", !u.uconduct.unvegan);