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);