add some new, easier achievements
Introduce eight achievements that can be attained by more players. Entered Gnomish Mines - self explanatory Entered Mine Town - the town portion, not just the level Entered a shop - any tended shop on any level Entered a temple - likewise for temple Consulted the Oracle - bought at least one major or minor oracle Read a Discworld Novel - read at least one passage Entered Sokoban - like mines Entered the Big Room - not always possible since not always present The novel and bigroom ones aren't always achieveable since novels are only guaranteed if a book or scroll shop gets created and bigroom is only guaranteed in wizard mode. No one ever claimed that every possible achievement can be attained in a single game. (If one for entering the Fort Ludios level--or perhaps entering the Fort itself-- eventually gets add, that won't be possible in every game either.) The mine town one probably needs some tweaking. Two of the town's seven variants have no town boundary (despite a rectangular area of pre-defined map) and at present simply arriving on either of those levels is enough to be credited with the entered-town achievement. Bump EDITLEVEL because u.uachieved[] has increased in size. This time it has been expanded to the maximum that xlogfile's bitmask of achievements can handle, enough for up to 9 more achievements without another EDITLEVEL increment.
This commit is contained in:
@@ -2615,8 +2615,9 @@ Statues and boulders are not particularly useful, and are generally
|
||||
heavy. It is rumored that some statues are not what they seem.
|
||||
.pg
|
||||
Boulders occasionally block your path.
|
||||
You can push one forward when nothing blocks \fIits\fP path, or you can
|
||||
smash it into a pile of small rocks with breaking magic or a pick-exe.
|
||||
You can push one forward (by attempting to walk onto its spot)
|
||||
when nothing blocks \fIits\fP path, or you can
|
||||
smash it into a pile of small rocks with breaking magic or a pick-axe.
|
||||
Very large humanoids (giants and their ilk) have been known to pick up
|
||||
boulders and use them as missile weapons.
|
||||
.pg
|
||||
@@ -2820,9 +2821,24 @@ in which you might accomplish them.
|
||||
.PS "Mines'\~End\~"
|
||||
.\}
|
||||
.fi
|
||||
.\" Use separate if-else because other achievements will be inserted here.
|
||||
.ie \n(fF \{\
|
||||
.PL Shop
|
||||
Entered a shop.
|
||||
.PL Temple
|
||||
Entered a temple.
|
||||
.PL Mines
|
||||
Entered the Gnomish Mines.
|
||||
.PL Town
|
||||
Entered Mine Town.
|
||||
.PL Oracle
|
||||
Consulted the Oracle of Delphi.
|
||||
.PL Novel
|
||||
Read a passage from a Discworld Novel.
|
||||
.PL Sokoban
|
||||
Entered Sokoban.
|
||||
.PL "Big\~Room"
|
||||
Entered the Big Room.
|
||||
.ie \n(fF \{\
|
||||
.PL "Soko-Prize"
|
||||
Explored to the top of Sokoban
|
||||
.br
|
||||
and found a special item there.
|
||||
@@ -2832,7 +2848,7 @@ Explored to the bottom of the Gnomish Mines
|
||||
and found a special item there.
|
||||
.\}
|
||||
.el \{\
|
||||
.PL Sokoban
|
||||
.PL "Soko-Prize"
|
||||
Explored to the top of Sokoban and found a special item there.
|
||||
.PL "Mines'\~End"
|
||||
Explored to the bottom of the Gnomish Mines and found a special item there.
|
||||
@@ -2866,6 +2882,11 @@ Delivered the Amulet to its final destination.
|
||||
.ED
|
||||
.lp "Notes: "
|
||||
.pg
|
||||
There's no guaranteed \fINovel\fP so the achievement to read one might
|
||||
not always be attainable (except perhaps by \fIwishing\fP).
|
||||
Similarly, the \fIBig Room\fP level is not always present.
|
||||
Unlike with the Novel, there's no way to wish for this opportunity.
|
||||
.pg
|
||||
The \(lqspecial items\(rq hidden in \fIMines'\~End\fP and \fISokoban\fP
|
||||
are not unique but are considered to be prizes or rewards
|
||||
for exploring those levels since doing so is not necessary to complete
|
||||
|
||||
@@ -2855,8 +2855,9 @@ heavy. It is rumored that some statues are not what they seem.
|
||||
|
||||
%.pg
|
||||
Boulders occasionally block your path.
|
||||
You can push one forward when nothing blocks {\it its\/} path, or you can
|
||||
smash it into a pile of small rocks with breaking magic or a pick-exe.
|
||||
You can push one forward (by attempting to walk onto its spot)
|
||||
when nothing blocks {\it its\/} path, or you can
|
||||
smash it into a pile of small rocks with breaking magic or a pick-axe.
|
||||
Very large humanoids (giants and their ilk) have been known to pick up
|
||||
boulders and use them as missile weapons.
|
||||
|
||||
@@ -3058,8 +3059,24 @@ in which you might accomplish them.
|
||||
\settowidth{\achwidth}{\tt Mines'~End~}
|
||||
\addtolength{\achwidth}{\labelsep}
|
||||
\blist{\leftmargin \achwidth \topsep 1mm \itemsep 0mm}
|
||||
%.PL Sokoban
|
||||
%.PL Shop
|
||||
\item[{\tt Shop}]
|
||||
Entered a shop.
|
||||
\item[{\tt Temple}]
|
||||
Entered a temple.
|
||||
\item[{\tt Mines}]
|
||||
Entered the Gnomish Mines.
|
||||
\item[{\tt Town}]
|
||||
Entered Mine Town.
|
||||
\item[{\tt Oracle}]
|
||||
Consulted the Oracle of Delphi.
|
||||
\item[{\tt Novel}]
|
||||
Read a passage from a Discworld Novel.
|
||||
\item[{\tt Sokoban}]
|
||||
Entered Sokoban.
|
||||
\item[{\tt "Big~Room"}]
|
||||
Entered the Big Room.
|
||||
\item[{\tt "Soko-Prize"}]
|
||||
Explored to the top of Sokoban and found a special item there.
|
||||
\item[{\tt Mines'~End}]
|
||||
Explored to the bottom of the Gnomish Mines and found a special item there.
|
||||
|
||||
@@ -106,8 +106,10 @@ struct novel_tracking { /* for choosing random passage when reading novel */
|
||||
};
|
||||
|
||||
struct achievement_tracking {
|
||||
unsigned mines_prize_oid, soko_prize_oid; /* obj->o_id */
|
||||
/* short mines_prize_type, soko_prize_typ1, soko_prize_typ2; */
|
||||
unsigned mines_prize_oid, /* luckstone->o_id */
|
||||
soko_prize_oid, /* {bag or amulet}->o_id */
|
||||
castle_prize_old; /* wand->o_id; not yet implemented */
|
||||
boolean minetn_reached; /* avoid redundant checking for town entry */
|
||||
};
|
||||
|
||||
struct context_info {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||
* and save files.
|
||||
*/
|
||||
#define EDITLEVEL 15
|
||||
#define EDITLEVEL 16
|
||||
|
||||
#define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
|
||||
#define COPYRIGHT_BANNER_B \
|
||||
|
||||
@@ -54,26 +54,76 @@ struct u_event {
|
||||
Bitfield(ascended, 1); /* has offered the Amulet */
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
/*
|
||||
* Achievements: milestones reached during the current game.
|
||||
* Numerical order of these matters because they've been encoded in
|
||||
* a bitmask in xlogfile. Reordering would break decoding that.
|
||||
* Aside from that, the number isn't significant--they're recorded
|
||||
* and eventually disclosed in the order achieved.
|
||||
*
|
||||
* Since xlogfile could be post-processed by unknown tools, we should
|
||||
* limit these to 31 total (it's possible that 32-bit signed longs are
|
||||
* the best such tools can offer). Eventually that is likely to need
|
||||
* to change, probably by giving xlogfile an achieve2 field rather
|
||||
* than by assuming that 64-bit longs are viable or by squeezing in a
|
||||
* 32nd entry by switching to unsigned long.
|
||||
*/
|
||||
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_AMUL = 6, /* acquired 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_MINE_PRIZE = 10, /* acquired Mines' End luckstone */
|
||||
ACH_SOKO_PRIZE = 11, /* acquired Sokoban bag or amulet */
|
||||
ACH_MEDU = 12, /* killed Medusa */
|
||||
ACH_BLND = 13, /* hero was always blond, no, blind */
|
||||
ACH_NUDE = 14, /* hero never wore armor */
|
||||
N_ACH
|
||||
/* 1 through 14 were present in 3.6.x; the rest are newer; first,
|
||||
some easier ones so less skilled players can have achievements */
|
||||
ACH_MINE = 15, /* entered Gnomish Mines */
|
||||
ACH_TOWN = 16, /* reached Mine Town */
|
||||
ACH_SHOP = 17, /* entered a shop */
|
||||
ACH_TMPL = 18, /* entered a temple */
|
||||
ACH_ORCL = 19, /* consulted the Oracle */
|
||||
ACH_NOVL = 20, /* read at least one passage from a Discworld novel */
|
||||
ACH_SOKO = 21, /* entered Sokoban */
|
||||
ACH_BGRM = 22, /* entered Bigroom (not guaranteed to be in every dgn) */
|
||||
/* 23..31, 9 available potential achievements; #32 currently off-limits */
|
||||
N_ACH = 32 /* allocate room for 31 plus a slot for 0 terminator */
|
||||
};
|
||||
/*
|
||||
* Other potential achievements to track (this comment briefly resided
|
||||
* in encodeachieve(topten.c) and has been revised since moving here:
|
||||
* [reached experience level N for a few interesting values of N
|
||||
* or perhaps "became a <rank title>" for each new rank reached]
|
||||
* got quest summons,
|
||||
* entered quest branch,
|
||||
* chatted with leader,
|
||||
* entered second or lower quest level (implies leader gave the Ok),
|
||||
* entered last quest level,
|
||||
* defeated nemesis (not same as acquiring Bell or artifact),
|
||||
* completed quest (formally, by bringing artifact to leader),
|
||||
* entered rogue level,
|
||||
* 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?],
|
||||
* entered Vlad's tower branch,
|
||||
* defeated Vlad (not same as acquiring Candelabrum),
|
||||
* entered Wizard's tower area within relevant level,
|
||||
* defeated Wizard,
|
||||
* found vibrating square,
|
||||
* entered sanctum level (maybe not; too close to performed-invocation),
|
||||
* [defeated Famine, defeated Pestilence, defeated Death]
|
||||
*/
|
||||
|
||||
struct u_realtime {
|
||||
long realtime; /* accumulated playing time in seconds */
|
||||
|
||||
@@ -792,12 +792,12 @@ boolean pre, wiztower;
|
||||
static const char Unachieve[] = "%s achievement revoked.";
|
||||
|
||||
if (Is_mineend_level(&u.uz)) {
|
||||
if (remove_achievement(ACH_LUCK))
|
||||
pline(Unachieve, "Mine's end");
|
||||
if (remove_achievement(ACH_MINE_PRIZE))
|
||||
pline(Unachieve, "Mine's-end");
|
||||
g.context.achieveo.mines_prize_oid = 0;
|
||||
} else if (Is_sokoend_level(&u.uz)) {
|
||||
if (remove_achievement(ACH_SOKO))
|
||||
pline(Unachieve, "Sokoban end");
|
||||
if (remove_achievement(ACH_SOKO_PRIZE))
|
||||
pline(Unachieve, "Sokoban-end");
|
||||
g.context.achieveo.soko_prize_oid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
22
src/do.c
22
src/do.c
@@ -1624,12 +1624,6 @@ boolean at_stairs, falling, portal;
|
||||
/* special levels can have a custom arrival message */
|
||||
deliver_splev_message();
|
||||
|
||||
/* give room entrance message, if any */
|
||||
check_special_room(FALSE);
|
||||
|
||||
/* deliver objects traveling with player */
|
||||
obj_delivery(TRUE);
|
||||
|
||||
/* Check whether we just entered Gehennom. */
|
||||
if (!In_hell(&u.uz0) && Inhell) {
|
||||
if (Is_valley(&u.uz)) {
|
||||
@@ -1701,9 +1695,18 @@ boolean at_stairs, falling, portal;
|
||||
mtmp->msleeping = 0;
|
||||
}
|
||||
}
|
||||
} else if (In_mines(&u.uz)) {
|
||||
if (newdungeon)
|
||||
record_achievement(ACH_MINE);
|
||||
} else if (In_sokoban(&u.uz)) {
|
||||
if (newdungeon)
|
||||
record_achievement(ACH_SOKO);
|
||||
} else {
|
||||
if (new && Is_rogue_level(&u.uz))
|
||||
if (new && Is_rogue_level(&u.uz)) {
|
||||
You("enter what seems to be an older, more primitive world.");
|
||||
} else if (new && Is_bigroom(&u.uz)) {
|
||||
record_achievement(ACH_BGRM);
|
||||
}
|
||||
/* main dungeon message from your quest leader */
|
||||
if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest")
|
||||
&& !(u.uevent.qcompleted || u.uevent.qexpelled
|
||||
@@ -1727,6 +1730,11 @@ boolean at_stairs, falling, portal;
|
||||
if ((annotation = get_annotation(&u.uz)) != 0)
|
||||
You("remember this level as %s.", annotation);
|
||||
|
||||
/* give room entrance message, if any */
|
||||
check_special_room(FALSE);
|
||||
/* deliver objects traveling with player */
|
||||
obj_delivery(TRUE);
|
||||
|
||||
/* assume this will always return TRUE when changing level */
|
||||
(void) in_out_region(u.ux, u.uy);
|
||||
(void) pickup(1);
|
||||
|
||||
13
src/hack.c
13
src/hack.c
@@ -2198,7 +2198,7 @@ boolean pick;
|
||||
check_special_room(FALSE);
|
||||
if (IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
|
||||
dosinkfall();
|
||||
if (!g.in_steed_dismounting) { /* if dismounting, we'll check again later */
|
||||
if (!g.in_steed_dismounting) { /* if dismounting, check again later */
|
||||
boolean pit;
|
||||
|
||||
/* if levitation is due to time out at the end of this
|
||||
@@ -2462,7 +2462,7 @@ register boolean newlev;
|
||||
/* possibly deliver a one-time room entry message */
|
||||
void
|
||||
check_special_room(newlev)
|
||||
register boolean newlev;
|
||||
boolean newlev;
|
||||
{
|
||||
register struct monst *mtmp;
|
||||
char *ptr;
|
||||
@@ -2475,6 +2475,12 @@ register boolean newlev;
|
||||
if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */
|
||||
return; /* no entrance messages necessary */
|
||||
|
||||
if (!g.context.achieveo.minetn_reached
|
||||
&& In_mines(&u.uz) && in_town(u.ux, u.uy)) {
|
||||
record_achievement(ACH_TOWN);
|
||||
g.context.achieveo.minetn_reached = TRUE;
|
||||
}
|
||||
|
||||
/* Did we just enter a shop? */
|
||||
if (*u.ushops_entered)
|
||||
u_entered_shop(u.ushops_entered);
|
||||
@@ -2504,6 +2510,7 @@ register boolean newlev;
|
||||
case MORGUE:
|
||||
if (midnight()) {
|
||||
const char *run = locomotion(g.youmonst.data, "Run");
|
||||
|
||||
pline("%s away! %s away!", run, run);
|
||||
} else
|
||||
You("have an uncanny feeling...");
|
||||
@@ -2528,6 +2535,7 @@ register boolean newlev;
|
||||
break;
|
||||
case DELPHI: {
|
||||
struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno);
|
||||
|
||||
if (oracle) {
|
||||
if (!oracle->mpeaceful)
|
||||
verbalize("You're in Delphi, %s.", g.plname);
|
||||
@@ -2586,7 +2594,6 @@ register boolean newlev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1755,14 +1755,38 @@ int final; /* used "behind the curtain" by enl_foo() macros */
|
||||
case ACH_NUDE:
|
||||
enl_msg(You_, "have gone", "went", " without any armor", "");
|
||||
break;
|
||||
case ACH_LUCK:
|
||||
enl_msg(You_, "have ", "", "completed the Gnomish Mines", "");
|
||||
case ACH_MINE:
|
||||
you_have_X("entered the Gnomish Mines");
|
||||
break;
|
||||
case ACH_TOWN:
|
||||
you_have_X("entered Mine Town");
|
||||
break;
|
||||
case ACH_SHOP:
|
||||
you_have_X("entered a shop");
|
||||
break;
|
||||
case ACH_TMPL:
|
||||
you_have_X("entered a temple");
|
||||
break;
|
||||
case ACH_ORCL:
|
||||
you_have_X("consulted the Oracle of Delphi");
|
||||
break;
|
||||
case ACH_NOVL:
|
||||
you_have_X("read from a Discworld novel");
|
||||
break;
|
||||
case ACH_SOKO:
|
||||
enl_msg(You_, "have ", "", "completed Sokoban", "");
|
||||
you_have_X("entered Sokoban");
|
||||
break;
|
||||
case ACH_SOKO_PRIZE: /* hard to reach guaranteed bag or amulet */
|
||||
you_have_X("completed Sokoban");
|
||||
break;
|
||||
case ACH_MINE_PRIZE: /* hidden guaranteed luckstone */
|
||||
you_have_X("completed the Gnomish Mines");
|
||||
break;
|
||||
case ACH_BGRM:
|
||||
you_have_X("entered the Big Room");
|
||||
break;
|
||||
case ACH_MEDU:
|
||||
enl_msg(You_, "have ", "", "defeated Medusa", "");
|
||||
you_have_X("defeated Medusa");
|
||||
break;
|
||||
case ACH_BELL:
|
||||
/* alternate phrasing for present vs past and also for
|
||||
@@ -1788,8 +1812,7 @@ int final; /* used "behind the curtain" by enl_foo() macros */
|
||||
" the Book of the Dead", "");
|
||||
break;
|
||||
case ACH_INVK:
|
||||
enl_msg(You_, "have ", "",
|
||||
"gained access to Moloch's Sanctum", "");
|
||||
you_have_X("gained access to Moloch's Sanctum");
|
||||
break;
|
||||
case ACH_AMUL:
|
||||
/* alternate wording for ascended (always past tense) since
|
||||
@@ -1805,10 +1828,10 @@ int final; /* used "behind the curtain" by enl_foo() macros */
|
||||
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", "");
|
||||
you_have_X("reached the Elemental Planes");
|
||||
break;
|
||||
case ACH_ASTR:
|
||||
enl_msg(You_, "have ", "", "reached the Astral Plane", "");
|
||||
you_have_X("reached the Astral Plane");
|
||||
break;
|
||||
case ACH_UWIN:
|
||||
/* the ultimate achievement... */
|
||||
|
||||
@@ -839,11 +839,11 @@ struct obj *obj;
|
||||
/* "special achievements"; revealed in end of game disclosure and
|
||||
dumplog, originally just recorded in XLOGFILE */
|
||||
if (is_mines_prize(obj)) {
|
||||
record_achievement(ACH_LUCK);
|
||||
record_achievement(ACH_MINE_PRIZE);
|
||||
g.context.achieveo.mines_prize_oid = 0; /* done with luckstone o_id */
|
||||
obj->nomerge = 0;
|
||||
} else if (is_soko_prize(obj)) {
|
||||
record_achievement(ACH_SOKO);
|
||||
record_achievement(ACH_SOKO_PRIZE);
|
||||
g.context.achieveo.soko_prize_oid = 0; /* done with bag/amulet o_id */
|
||||
obj->nomerge = 0;
|
||||
}
|
||||
|
||||
@@ -402,6 +402,7 @@ int roomno;
|
||||
|
||||
if ((priest = findpriest((char) roomno)) != 0) {
|
||||
/* tended */
|
||||
record_achievement(ACH_TMPL);
|
||||
|
||||
epri_p = EPRI(priest);
|
||||
shrined = has_shrine(priest);
|
||||
|
||||
@@ -525,6 +525,8 @@ struct monst *oracl;
|
||||
}
|
||||
money2mon(oracl, (long) u_pay);
|
||||
g.context.botl = 1;
|
||||
if (!u.uevent.major_oracle && !u.uevent.minor_oracle)
|
||||
record_achievement(ACH_ORCL);
|
||||
add_xpts = 0; /* first oracle of each type gives experience points */
|
||||
if (u_pay == minor_cost) {
|
||||
outrumor(1, BY_ORACLE);
|
||||
|
||||
@@ -564,6 +564,7 @@ char *enterstring;
|
||||
u.ushops[0] = '\0';
|
||||
return;
|
||||
}
|
||||
record_achievement(ACH_SHOP);
|
||||
|
||||
eshkp->bill_p = &(eshkp->bill[0]);
|
||||
|
||||
|
||||
@@ -465,7 +465,8 @@ register struct obj *spellbook;
|
||||
}
|
||||
}
|
||||
|
||||
if (g.context.spbook.delay && !confused && spellbook == g.context.spbook.book
|
||||
if (g.context.spbook.delay && !confused
|
||||
&& spellbook == g.context.spbook.book
|
||||
/* handle the sequence: start reading, get interrupted, have
|
||||
g.context.spbook.book become erased somehow, resume reading it */
|
||||
&& booktype != SPE_BLANK_PAPER) {
|
||||
@@ -490,6 +491,7 @@ register struct obj *spellbook;
|
||||
check_unpaid(spellbook);
|
||||
makeknown(booktype);
|
||||
if (!u.uevent.read_tribute) {
|
||||
record_achievement(ACH_NOVL);
|
||||
/* give bonus of 20 xp and 4*20+0 pts */
|
||||
more_experienced(20, 0);
|
||||
newexplevel();
|
||||
|
||||
63
src/topten.c
63
src/topten.c
@@ -70,7 +70,7 @@ static void FDECL(writeentry, (FILE *, struct toptenentry *));
|
||||
static void FDECL(writexlentry, (FILE *, struct toptenentry *, int));
|
||||
static long NDECL(encodexlogflags);
|
||||
static long NDECL(encodeconduct);
|
||||
static long NDECL(encodeachieve);
|
||||
static long FDECL(encodeachieve, (BOOLEAN_P));
|
||||
#endif
|
||||
static void FDECL(free_ttlist, (struct toptenentry *));
|
||||
static int FDECL(classmon, (char *, BOOLEAN_P));
|
||||
@@ -365,7 +365,8 @@ int how;
|
||||
Fprintf(rfile, "%cwhile=%s", XLOG_SEP,
|
||||
g.multi_reason ? g.multi_reason : "helpless");
|
||||
Fprintf(rfile, "%cconduct=0x%lx%cturns=%ld%cachieve=0x%lx", XLOG_SEP,
|
||||
encodeconduct(), XLOG_SEP, g.moves, XLOG_SEP, encodeachieve());
|
||||
encodeconduct(), XLOG_SEP, g.moves, XLOG_SEP,
|
||||
encodeachieve(FALSE));
|
||||
Fprintf(rfile, "%crealtime=%ld%cstarttime=%ld%cendtime=%ld", XLOG_SEP,
|
||||
(long) urealtime.realtime, XLOG_SEP,
|
||||
(long) ubirthday, XLOG_SEP, (long) urealtime.finish_time);
|
||||
@@ -426,54 +427,26 @@ encodeconduct()
|
||||
}
|
||||
|
||||
static long
|
||||
encodeachieve()
|
||||
encodeachieve(secondlong)
|
||||
boolean secondlong; /* False: handle achievements 1..31, True: 32..62 */
|
||||
{
|
||||
int i, ilimit;
|
||||
int i, achidx, offset;
|
||||
long r = 0L;
|
||||
|
||||
/*
|
||||
* Other potential achievements to track (some already recorded
|
||||
* for other purposes such as automatic level annotations or
|
||||
* quest progress):
|
||||
* entered mines branch,
|
||||
* chatted with the Oracle,
|
||||
* read a Discworld novel,
|
||||
* entered Sokoban's first level,
|
||||
* entered Bigroom level,
|
||||
* got quest summons,
|
||||
* entered quest branch,
|
||||
* chatted with leader,
|
||||
* entered second quest level,
|
||||
* entered last quest level,
|
||||
* defeated nemesis (not same as acquiring Bell or artifact),
|
||||
* completed quest (again, not the same as getting the items),
|
||||
* entered rogue level,
|
||||
* entered Fort Ludios level/branch,
|
||||
* entered Medusa level,
|
||||
* entered castle level,
|
||||
* opened castle drawbridge,
|
||||
* obtained castle wand,
|
||||
* entered valley level,
|
||||
* [assorted demon lairs?],
|
||||
* entered Vlad's tower branch,
|
||||
* defeated Vlad (not same as acquiring Candelabrum),
|
||||
* entered Wizard's tower area within relevant level,
|
||||
* defeated Wizard,
|
||||
* found vibrating square,
|
||||
* entered sanctum level,
|
||||
* [defeated Riders],
|
||||
* located the correct high altar (for initial alignment or current
|
||||
* one or both?) on the astral level.
|
||||
* Too many to include them all in a 32-bit mask, but that could
|
||||
* handle a lot of them. Defeated <foo> can be seen via the vanquished
|
||||
* monsters list and many or all of the entered <bar> can be seen via
|
||||
* the dungeon overview but both of those things go away as soon as
|
||||
* the program exits.
|
||||
* 32: portable limit for 'long'.
|
||||
* Force 32 even on configurations that are using 64 bit longs.
|
||||
*
|
||||
* We use signed long and limit ourselves to 31 bits since tools
|
||||
* that post-process xlogfile might not be able to cope with
|
||||
* 'unsigned long'.
|
||||
*/
|
||||
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);
|
||||
|
||||
offset = secondlong ? (32 - 1) : 0;
|
||||
for (i = 0; u.uachieved[i]; ++i) {
|
||||
achidx = u.uachieved[i] - offset;
|
||||
if (achidx > 0 && achidx < 32) /* value 1..31 sets bit 0..30 */
|
||||
r |= 1L << (achidx - 1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user