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:
+26
-5
@@ -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.
|
heavy. It is rumored that some statues are not what they seem.
|
||||||
.pg
|
.pg
|
||||||
Boulders occasionally block your path.
|
Boulders occasionally block your path.
|
||||||
You can push one forward when nothing blocks \fIits\fP path, or you can
|
You can push one forward (by attempting to walk onto its spot)
|
||||||
smash it into a pile of small rocks with breaking magic or a pick-exe.
|
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
|
Very large humanoids (giants and their ilk) have been known to pick up
|
||||||
boulders and use them as missile weapons.
|
boulders and use them as missile weapons.
|
||||||
.pg
|
.pg
|
||||||
@@ -2820,9 +2821,24 @@ in which you might accomplish them.
|
|||||||
.PS "Mines'\~End\~"
|
.PS "Mines'\~End\~"
|
||||||
.\}
|
.\}
|
||||||
.fi
|
.fi
|
||||||
.\" Use separate if-else because other achievements will be inserted here.
|
.PL Shop
|
||||||
.ie \n(fF \{\
|
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
|
.PL Sokoban
|
||||||
|
Entered Sokoban.
|
||||||
|
.PL "Big\~Room"
|
||||||
|
Entered the Big Room.
|
||||||
|
.ie \n(fF \{\
|
||||||
|
.PL "Soko-Prize"
|
||||||
Explored to the top of Sokoban
|
Explored to the top of Sokoban
|
||||||
.br
|
.br
|
||||||
and found a special item there.
|
and found a special item there.
|
||||||
@@ -2832,7 +2848,7 @@ Explored to the bottom of the Gnomish Mines
|
|||||||
and found a special item there.
|
and found a special item there.
|
||||||
.\}
|
.\}
|
||||||
.el \{\
|
.el \{\
|
||||||
.PL Sokoban
|
.PL "Soko-Prize"
|
||||||
Explored to the top of Sokoban and found a special item there.
|
Explored to the top of Sokoban and found a special item there.
|
||||||
.PL "Mines'\~End"
|
.PL "Mines'\~End"
|
||||||
Explored to the bottom of the Gnomish Mines and found a special item there.
|
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
|
.ED
|
||||||
.lp "Notes: "
|
.lp "Notes: "
|
||||||
.pg
|
.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
|
The \(lqspecial items\(rq hidden in \fIMines'\~End\fP and \fISokoban\fP
|
||||||
are not unique but are considered to be prizes or rewards
|
are not unique but are considered to be prizes or rewards
|
||||||
for exploring those levels since doing so is not necessary to complete
|
for exploring those levels since doing so is not necessary to complete
|
||||||
|
|||||||
+20
-3
@@ -2855,8 +2855,9 @@ heavy. It is rumored that some statues are not what they seem.
|
|||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
Boulders occasionally block your path.
|
Boulders occasionally block your path.
|
||||||
You can push one forward when nothing blocks {\it its\/} path, or you can
|
You can push one forward (by attempting to walk onto its spot)
|
||||||
smash it into a pile of small rocks with breaking magic or a pick-exe.
|
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
|
Very large humanoids (giants and their ilk) have been known to pick up
|
||||||
boulders and use them as missile weapons.
|
boulders and use them as missile weapons.
|
||||||
|
|
||||||
@@ -3058,8 +3059,24 @@ in which you might accomplish them.
|
|||||||
\settowidth{\achwidth}{\tt Mines'~End~}
|
\settowidth{\achwidth}{\tt Mines'~End~}
|
||||||
\addtolength{\achwidth}{\labelsep}
|
\addtolength{\achwidth}{\labelsep}
|
||||||
\blist{\leftmargin \achwidth \topsep 1mm \itemsep 0mm}
|
\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}]
|
\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.
|
Explored to the top of Sokoban and found a special item there.
|
||||||
\item[{\tt Mines'~End}]
|
\item[{\tt Mines'~End}]
|
||||||
Explored to the bottom of the Gnomish Mines and found a special item there.
|
Explored to the bottom of the Gnomish Mines and found a special item there.
|
||||||
|
|||||||
+4
-2
@@ -106,8 +106,10 @@ struct novel_tracking { /* for choosing random passage when reading novel */
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct achievement_tracking {
|
struct achievement_tracking {
|
||||||
unsigned mines_prize_oid, soko_prize_oid; /* obj->o_id */
|
unsigned mines_prize_oid, /* luckstone->o_id */
|
||||||
/* short mines_prize_type, soko_prize_typ1, soko_prize_typ2; */
|
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 {
|
struct context_info {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
* Incrementing EDITLEVEL can be used to force invalidation of old bones
|
||||||
* and save files.
|
* and save files.
|
||||||
*/
|
*/
|
||||||
#define EDITLEVEL 15
|
#define EDITLEVEL 16
|
||||||
|
|
||||||
#define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
|
#define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
|
||||||
#define COPYRIGHT_BANNER_B \
|
#define COPYRIGHT_BANNER_B \
|
||||||
|
|||||||
+57
-7
@@ -54,26 +54,76 @@ struct u_event {
|
|||||||
Bitfield(ascended, 1); /* has offered the Amulet */
|
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
|
* Achievements: milestones reached during the current game.
|
||||||
the number doesn't matter--they're recorded in the order achieved */
|
* 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 {
|
enum achivements {
|
||||||
ACH_BELL = 1, /* acquired Bell of Opening */
|
ACH_BELL = 1, /* acquired Bell of Opening */
|
||||||
ACH_HELL = 2, /* entered Gehennom */
|
ACH_HELL = 2, /* entered Gehennom */
|
||||||
ACH_CNDL = 3, /* acquired Candelabrum of Invocation */
|
ACH_CNDL = 3, /* acquired Candelabrum of Invocation */
|
||||||
ACH_BOOK = 4, /* acquired Book of the Dead */
|
ACH_BOOK = 4, /* acquired Book of the Dead */
|
||||||
ACH_INVK = 5, /* performed invocation to gain access to Sanctum */
|
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_ENDG = 7, /* entered end game */
|
||||||
ACH_ASTR = 8, /* entered Astral Plane */
|
ACH_ASTR = 8, /* entered Astral Plane */
|
||||||
ACH_UWIN = 9, /* ascended */
|
ACH_UWIN = 9, /* ascended */
|
||||||
ACH_LUCK = 10, /* acquired Mines' End luckstone */
|
ACH_MINE_PRIZE = 10, /* acquired Mines' End luckstone */
|
||||||
ACH_SOKO = 11, /* acquired Sokoban bag of holding or amu of reflection */
|
ACH_SOKO_PRIZE = 11, /* acquired Sokoban bag or amulet */
|
||||||
ACH_MEDU = 12, /* killed Medusa */
|
ACH_MEDU = 12, /* killed Medusa */
|
||||||
ACH_BLND = 13, /* hero was always blond, no, blind */
|
ACH_BLND = 13, /* hero was always blond, no, blind */
|
||||||
ACH_NUDE = 14, /* hero never wore armor */
|
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 {
|
struct u_realtime {
|
||||||
long realtime; /* accumulated playing time in seconds */
|
long realtime; /* accumulated playing time in seconds */
|
||||||
|
|||||||
@@ -792,12 +792,12 @@ boolean pre, wiztower;
|
|||||||
static const char Unachieve[] = "%s achievement revoked.";
|
static const char Unachieve[] = "%s achievement revoked.";
|
||||||
|
|
||||||
if (Is_mineend_level(&u.uz)) {
|
if (Is_mineend_level(&u.uz)) {
|
||||||
if (remove_achievement(ACH_LUCK))
|
if (remove_achievement(ACH_MINE_PRIZE))
|
||||||
pline(Unachieve, "Mine's end");
|
pline(Unachieve, "Mine's-end");
|
||||||
g.context.achieveo.mines_prize_oid = 0;
|
g.context.achieveo.mines_prize_oid = 0;
|
||||||
} else if (Is_sokoend_level(&u.uz)) {
|
} else if (Is_sokoend_level(&u.uz)) {
|
||||||
if (remove_achievement(ACH_SOKO))
|
if (remove_achievement(ACH_SOKO_PRIZE))
|
||||||
pline(Unachieve, "Sokoban end");
|
pline(Unachieve, "Sokoban-end");
|
||||||
g.context.achieveo.soko_prize_oid = 0;
|
g.context.achieveo.soko_prize_oid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1624,12 +1624,6 @@ boolean at_stairs, falling, portal;
|
|||||||
/* special levels can have a custom arrival message */
|
/* special levels can have a custom arrival message */
|
||||||
deliver_splev_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. */
|
/* Check whether we just entered Gehennom. */
|
||||||
if (!In_hell(&u.uz0) && Inhell) {
|
if (!In_hell(&u.uz0) && Inhell) {
|
||||||
if (Is_valley(&u.uz)) {
|
if (Is_valley(&u.uz)) {
|
||||||
@@ -1701,9 +1695,18 @@ boolean at_stairs, falling, portal;
|
|||||||
mtmp->msleeping = 0;
|
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 {
|
} 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.");
|
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 */
|
/* main dungeon message from your quest leader */
|
||||||
if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest")
|
if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest")
|
||||||
&& !(u.uevent.qcompleted || u.uevent.qexpelled
|
&& !(u.uevent.qcompleted || u.uevent.qexpelled
|
||||||
@@ -1727,6 +1730,11 @@ boolean at_stairs, falling, portal;
|
|||||||
if ((annotation = get_annotation(&u.uz)) != 0)
|
if ((annotation = get_annotation(&u.uz)) != 0)
|
||||||
You("remember this level as %s.", annotation);
|
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 */
|
/* assume this will always return TRUE when changing level */
|
||||||
(void) in_out_region(u.ux, u.uy);
|
(void) in_out_region(u.ux, u.uy);
|
||||||
(void) pickup(1);
|
(void) pickup(1);
|
||||||
|
|||||||
+10
-3
@@ -2198,7 +2198,7 @@ boolean pick;
|
|||||||
check_special_room(FALSE);
|
check_special_room(FALSE);
|
||||||
if (IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
|
if (IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
|
||||||
dosinkfall();
|
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;
|
boolean pit;
|
||||||
|
|
||||||
/* if levitation is due to time out at the end of this
|
/* 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 */
|
/* possibly deliver a one-time room entry message */
|
||||||
void
|
void
|
||||||
check_special_room(newlev)
|
check_special_room(newlev)
|
||||||
register boolean newlev;
|
boolean newlev;
|
||||||
{
|
{
|
||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@@ -2475,6 +2475,12 @@ register boolean newlev;
|
|||||||
if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */
|
if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */
|
||||||
return; /* no entrance messages necessary */
|
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? */
|
/* Did we just enter a shop? */
|
||||||
if (*u.ushops_entered)
|
if (*u.ushops_entered)
|
||||||
u_entered_shop(u.ushops_entered);
|
u_entered_shop(u.ushops_entered);
|
||||||
@@ -2504,6 +2510,7 @@ register boolean newlev;
|
|||||||
case MORGUE:
|
case MORGUE:
|
||||||
if (midnight()) {
|
if (midnight()) {
|
||||||
const char *run = locomotion(g.youmonst.data, "Run");
|
const char *run = locomotion(g.youmonst.data, "Run");
|
||||||
|
|
||||||
pline("%s away! %s away!", run, run);
|
pline("%s away! %s away!", run, run);
|
||||||
} else
|
} else
|
||||||
You("have an uncanny feeling...");
|
You("have an uncanny feeling...");
|
||||||
@@ -2528,6 +2535,7 @@ register boolean newlev;
|
|||||||
break;
|
break;
|
||||||
case DELPHI: {
|
case DELPHI: {
|
||||||
struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno);
|
struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno);
|
||||||
|
|
||||||
if (oracle) {
|
if (oracle) {
|
||||||
if (!oracle->mpeaceful)
|
if (!oracle->mpeaceful)
|
||||||
verbalize("You're in Delphi, %s.", g.plname);
|
verbalize("You're in Delphi, %s.", g.plname);
|
||||||
@@ -2586,7 +2594,6 @@ register boolean newlev;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+31
-8
@@ -1755,14 +1755,38 @@ int final; /* used "behind the curtain" by enl_foo() macros */
|
|||||||
case ACH_NUDE:
|
case ACH_NUDE:
|
||||||
enl_msg(You_, "have gone", "went", " without any armor", "");
|
enl_msg(You_, "have gone", "went", " without any armor", "");
|
||||||
break;
|
break;
|
||||||
case ACH_LUCK:
|
case ACH_MINE:
|
||||||
enl_msg(You_, "have ", "", "completed the Gnomish Mines", "");
|
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;
|
break;
|
||||||
case ACH_SOKO:
|
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;
|
break;
|
||||||
case ACH_MEDU:
|
case ACH_MEDU:
|
||||||
enl_msg(You_, "have ", "", "defeated Medusa", "");
|
you_have_X("defeated Medusa");
|
||||||
break;
|
break;
|
||||||
case ACH_BELL:
|
case ACH_BELL:
|
||||||
/* alternate phrasing for present vs past and also for
|
/* 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", "");
|
" the Book of the Dead", "");
|
||||||
break;
|
break;
|
||||||
case ACH_INVK:
|
case ACH_INVK:
|
||||||
enl_msg(You_, "have ", "",
|
you_have_X("gained access to Moloch's Sanctum");
|
||||||
"gained access to Moloch's Sanctum", "");
|
|
||||||
break;
|
break;
|
||||||
case ACH_AMUL:
|
case ACH_AMUL:
|
||||||
/* alternate wording for ascended (always past tense) since
|
/* 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
|
be redundant and ascending makes both be redundant, but
|
||||||
we display all that apply */
|
we display all that apply */
|
||||||
case ACH_ENDG:
|
case ACH_ENDG:
|
||||||
enl_msg(You_, "have ", "", "reached the Elemental Planes", "");
|
you_have_X("reached the Elemental Planes");
|
||||||
break;
|
break;
|
||||||
case ACH_ASTR:
|
case ACH_ASTR:
|
||||||
enl_msg(You_, "have ", "", "reached the Astral Plane", "");
|
you_have_X("reached the Astral Plane");
|
||||||
break;
|
break;
|
||||||
case ACH_UWIN:
|
case ACH_UWIN:
|
||||||
/* the ultimate achievement... */
|
/* the ultimate achievement... */
|
||||||
|
|||||||
+2
-2
@@ -839,11 +839,11 @@ struct obj *obj;
|
|||||||
/* "special achievements"; revealed in end of game disclosure and
|
/* "special achievements"; revealed in end of game disclosure and
|
||||||
dumplog, originally just recorded in XLOGFILE */
|
dumplog, originally just recorded in XLOGFILE */
|
||||||
if (is_mines_prize(obj)) {
|
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 */
|
g.context.achieveo.mines_prize_oid = 0; /* done with luckstone o_id */
|
||||||
obj->nomerge = 0;
|
obj->nomerge = 0;
|
||||||
} else if (is_soko_prize(obj)) {
|
} 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 */
|
g.context.achieveo.soko_prize_oid = 0; /* done with bag/amulet o_id */
|
||||||
obj->nomerge = 0;
|
obj->nomerge = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,6 +402,7 @@ int roomno;
|
|||||||
|
|
||||||
if ((priest = findpriest((char) roomno)) != 0) {
|
if ((priest = findpriest((char) roomno)) != 0) {
|
||||||
/* tended */
|
/* tended */
|
||||||
|
record_achievement(ACH_TMPL);
|
||||||
|
|
||||||
epri_p = EPRI(priest);
|
epri_p = EPRI(priest);
|
||||||
shrined = has_shrine(priest);
|
shrined = has_shrine(priest);
|
||||||
|
|||||||
@@ -525,6 +525,8 @@ struct monst *oracl;
|
|||||||
}
|
}
|
||||||
money2mon(oracl, (long) u_pay);
|
money2mon(oracl, (long) u_pay);
|
||||||
g.context.botl = 1;
|
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 */
|
add_xpts = 0; /* first oracle of each type gives experience points */
|
||||||
if (u_pay == minor_cost) {
|
if (u_pay == minor_cost) {
|
||||||
outrumor(1, BY_ORACLE);
|
outrumor(1, BY_ORACLE);
|
||||||
|
|||||||
@@ -564,6 +564,7 @@ char *enterstring;
|
|||||||
u.ushops[0] = '\0';
|
u.ushops[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
record_achievement(ACH_SHOP);
|
||||||
|
|
||||||
eshkp->bill_p = &(eshkp->bill[0]);
|
eshkp->bill_p = &(eshkp->bill[0]);
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -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
|
/* handle the sequence: start reading, get interrupted, have
|
||||||
g.context.spbook.book become erased somehow, resume reading it */
|
g.context.spbook.book become erased somehow, resume reading it */
|
||||||
&& booktype != SPE_BLANK_PAPER) {
|
&& booktype != SPE_BLANK_PAPER) {
|
||||||
@@ -490,6 +491,7 @@ register struct obj *spellbook;
|
|||||||
check_unpaid(spellbook);
|
check_unpaid(spellbook);
|
||||||
makeknown(booktype);
|
makeknown(booktype);
|
||||||
if (!u.uevent.read_tribute) {
|
if (!u.uevent.read_tribute) {
|
||||||
|
record_achievement(ACH_NOVL);
|
||||||
/* give bonus of 20 xp and 4*20+0 pts */
|
/* give bonus of 20 xp and 4*20+0 pts */
|
||||||
more_experienced(20, 0);
|
more_experienced(20, 0);
|
||||||
newexplevel();
|
newexplevel();
|
||||||
|
|||||||
+18
-45
@@ -70,7 +70,7 @@ static void FDECL(writeentry, (FILE *, struct toptenentry *));
|
|||||||
static void FDECL(writexlentry, (FILE *, struct toptenentry *, int));
|
static void FDECL(writexlentry, (FILE *, struct toptenentry *, int));
|
||||||
static long NDECL(encodexlogflags);
|
static long NDECL(encodexlogflags);
|
||||||
static long NDECL(encodeconduct);
|
static long NDECL(encodeconduct);
|
||||||
static long NDECL(encodeachieve);
|
static long FDECL(encodeachieve, (BOOLEAN_P));
|
||||||
#endif
|
#endif
|
||||||
static void FDECL(free_ttlist, (struct toptenentry *));
|
static void FDECL(free_ttlist, (struct toptenentry *));
|
||||||
static int FDECL(classmon, (char *, BOOLEAN_P));
|
static int FDECL(classmon, (char *, BOOLEAN_P));
|
||||||
@@ -365,7 +365,8 @@ int how;
|
|||||||
Fprintf(rfile, "%cwhile=%s", XLOG_SEP,
|
Fprintf(rfile, "%cwhile=%s", XLOG_SEP,
|
||||||
g.multi_reason ? g.multi_reason : "helpless");
|
g.multi_reason ? g.multi_reason : "helpless");
|
||||||
Fprintf(rfile, "%cconduct=0x%lx%cturns=%ld%cachieve=0x%lx", XLOG_SEP,
|
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,
|
Fprintf(rfile, "%crealtime=%ld%cstarttime=%ld%cendtime=%ld", XLOG_SEP,
|
||||||
(long) urealtime.realtime, XLOG_SEP,
|
(long) urealtime.realtime, XLOG_SEP,
|
||||||
(long) ubirthday, XLOG_SEP, (long) urealtime.finish_time);
|
(long) ubirthday, XLOG_SEP, (long) urealtime.finish_time);
|
||||||
@@ -426,54 +427,26 @@ encodeconduct()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static long
|
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;
|
long r = 0L;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other potential achievements to track (some already recorded
|
* 32: portable limit for 'long'.
|
||||||
* for other purposes such as automatic level annotations or
|
* Force 32 even on configurations that are using 64 bit longs.
|
||||||
* quest progress):
|
*
|
||||||
* entered mines branch,
|
* We use signed long and limit ourselves to 31 bits since tools
|
||||||
* chatted with the Oracle,
|
* that post-process xlogfile might not be able to cope with
|
||||||
* read a Discworld novel,
|
* 'unsigned long'.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
ilimit = min(N_ACH, 32 - 1); /* 32: portable limit for 'long' */
|
offset = secondlong ? (32 - 1) : 0;
|
||||||
for (i = 0; i < ilimit && u.uachieved[i]; ++i)
|
for (i = 0; u.uachieved[i]; ++i) {
|
||||||
r |= 1L << (u.uachieved[i] - 1);
|
achidx = u.uachieved[i] - offset;
|
||||||
|
if (achidx > 0 && achidx < 32) /* value 1..31 sets bit 0..30 */
|
||||||
|
r |= 1L << (achidx - 1);
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user