Skip to content

Commit 2ca337e

Browse files
committed
Revival routine for Draugr race.
This commit adds the amount of times someone playing as Draugr race can revive each game. That amount is one to three times, chosen randomly every game. Draugr are guaranteed one revival, it's up to the RNG if they receive any more than that. The amount is purposely withheld from the player; this is to prevent the player from getting a false sense of invulnerability. Revival has a cost, reducing strength and constitution by one point. Unlike being revived from an amulet of life saving, Draugr will reclaim max hit points, even if above 150 max hp - they can't use an actual amulet of life saving, so this seemed fair. Some caveats: just as with an amulet of life saving, revival will not work if the player genocides themselves, or encounter a condition where they are drowning or falling, and don't have a safe space to land on. Specific to Draugr, being decapitated means no revival - same for monster zombies who lose their head to Vorpal Blade.
1 parent 92d4e03 commit 2ca337e

File tree

7 files changed

+39
-19
lines changed

7 files changed

+39
-19
lines changed

doc/evilhack-changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -3423,4 +3423,5 @@ The following changes to date are:
34233423
- New conduct: never acquired magic resistance
34243424
- New conduct: never acquired reflection
34253425
- New race: Draugr
3426+
- Revival routine for Draugr race
34263427

include/hack.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,13 @@ enum game_end_types {
158158
CRUSHING = 7,
159159
STONING = 8,
160160
TURNED_SLIME = 9,
161-
GENOCIDED = 10,
162-
PANICKED = 11,
163-
TRICKED = 12,
164-
QUIT = 13,
165-
ESCAPED = 14,
166-
ASCENDED = 15
161+
DECAPITATED = 10,
162+
GENOCIDED = 11,
163+
PANICKED = 12,
164+
TRICKED = 13,
165+
QUIT = 14,
166+
ESCAPED = 15,
167+
ASCENDED = 16
167168
};
168169

169170
typedef struct strbuf {

include/you.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ struct you {
439439
long ugallop; /* turns steed will run after being kicked */
440440
int urideturns; /* time spent riding, for skill advancement */
441441
int umortality; /* how many times you died */
442-
int ugrave_arise; /* you die and become something aside from a ghost */
442+
int ugrave_arise; /* you die and become something aside from a ghost */
443443
int weapon_slots; /* unused skill slots */
444444
int skills_advanced; /* # of advances made so far */
445445
xchar skill_record[P_SKILL_LIMIT]; /* skill advancements */

src/artifact.c

+3
Original file line numberDiff line numberDiff line change
@@ -2850,6 +2850,9 @@ int dieroll; /* needed for Magicbane and vorpal blades */
28502850
*dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER;
28512851
pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc, "you");
28522852
otmp->dknown = TRUE;
2853+
killer.format = NO_KILLER_PREFIX;
2854+
Sprintf(killer.name, "decapitated by %s", xname(otmp));
2855+
done(DECAPITATED);
28532856
/* Should amulets fall off? */
28542857
return TRUE;
28552858
}

src/end.c

+22-9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#define FIRST_AMULET AMULET_OF_ESP
2525
#define LAST_AMULET AMULET_OF_YENDOR
2626

27+
#define DRAUGR_REVIVE rnd(3)
28+
2729
extern const int matprices[];
2830

2931
struct valuable_data {
@@ -313,8 +315,8 @@ static NEARDATA const char *deaths[] = {
313315
/* the array of death */
314316
"died", "choked", "poisoned", "starvation", "drowning", "burning",
315317
"dissolving under the heat and pressure", "crushed", "turned to stone",
316-
"turned into slime", "genocided", "panic", "trickery", "quit",
317-
"escaped", "ascended"
318+
"turned into slime", "decapitated", "genocided", "panic", "trickery",
319+
"quit", "escaped", "ascended"
318320
};
319321

320322
static NEARDATA const char *ends[] = {
@@ -323,9 +325,9 @@ static NEARDATA const char *ends[] = {
323325
"starved", "drowned", "burned",
324326
"dissolved in the lava",
325327
"were crushed", "turned to stone",
326-
"turned into slime", "were genocided",
327-
"panicked", "were tricked", "quit",
328-
"escaped", "ascended"
328+
"turned into slime", "were decapitated",
329+
"were genocided", "panicked", "were tricked",
330+
"quit", "escaped", "ascended"
329331
};
330332

331333
static boolean Schroedingers_cat = FALSE;
@@ -1039,7 +1041,7 @@ int how;
10391041
uhpmin = max(2 * u.ulevel, 10);
10401042
if (u.uhpmax < uhpmin)
10411043
u.uhpmax = uhpmin;
1042-
u.uhp = min(u.uhpmax, 150);
1044+
u.uhp = min(u.uhpmax, (HLifesaved ? u.uhpmax : 150));
10431045

10441046
if (Upolyd) /* Unchanging, or death which bypasses losing hit points */
10451047
u.mh = min(u.mhmax, 150);
@@ -1348,11 +1350,18 @@ int how;
13481350
}
13491351
}
13501352
if (HLifesaved && (how <= GENOCIDED)) { /* Draugr */
1351-
You("float in a sea of nothingness. Then suddenly, you revive!");
1353+
pline("But then suddenly, you start to revive!");
1354+
/* reviving takes a toll */
1355+
(void) adjattrib(A_STR, -1, TRUE);
13521356
(void) adjattrib(A_CON, -1, TRUE);
13531357
savelife(how);
13541358
if (how == GENOCIDED) {
13551359
pline("Unfortunately you are still genocided...");
1360+
} else if (how == DECAPITATED) { /* can't revive if you've lost your head */
1361+
pline("Unfortunately you've lost your %s...",
1362+
body_part(HEAD));
1363+
} else if (u.umortality > DRAUGR_REVIVE) { /* ran out of revive chances */
1364+
pline("Unfortunately you weren't strong enough to revive fully...");
13561365
} else if (is_open_air(x, y) && !Levitation
13571366
&& !(Flying && !(Punished && !carried(uball)
13581367
&& is_open_air(uball->ox, uball->oy)))) {
@@ -1375,7 +1384,8 @@ int how;
13751384
|| !nonliving(youmonst.data) || Race_if(PM_DRAUGR)) {
13761385
Your("medallion %s!", !Blind ? "glows white-hot"
13771386
: "sears your neck");
1378-
You("hear manic laughter in the distance...");
1387+
if (!Deaf)
1388+
You("hear manic laughter in the distance...");
13791389
Your("medallion turns to ash!");
13801390
if (uamul->cursed)
13811391
pline("It appears your luck has run out...");
@@ -1421,7 +1431,10 @@ int how;
14211431
/* explore and wizard modes offer player the option to keep playing */
14221432
if (!survive && (wizard || discover) && how <= GENOCIDED
14231433
&& !paranoid_query(ParanoidDie, "Die?")) {
1424-
pline("OK, so you don't %s.", (how == CHOKING) ? "choke" : "die");
1434+
pline("OK, so you don't %s.",
1435+
(how == CHOKING) ? "choke"
1436+
: (how == DECAPITATED) ? "lose your head"
1437+
: "die");
14251438
iflags.last_msg = PLNMSG_OK_DONT_DIE;
14261439
savelife(how);
14271440
ukiller = (struct monst*) 0;

src/mhitu.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2487,7 +2487,7 @@ register struct attack *mattk;
24872487
killer.format = NO_KILLER_PREFIX;
24882488
Sprintf(killer.name, "decapitated by %s",
24892489
an(l_monnam(mtmp)));
2490-
done(DIED);
2490+
done(DECAPITATED);
24912491
}
24922492
dmg = 0;
24932493
}

src/topten.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ boolean incl_helpless;
106106
"killed by ", "choked on ", "poisoned by ", "died of ",
107107
/* DROWNING, BURNING, DISSOLVED, CRUSHING, */
108108
"drowned in ", "burned by ", "dissolved in ", "crushed to death by ",
109-
/* STONING, TURNED_SLIME, GENOCIDED, */
110-
"petrified by ", "turned to slime by ", "killed by ",
109+
/* STONING, TURNED_SLIME, DECAPITATED, GENOCIDED, */
110+
"petrified by ", "turned to slime by ", "decapitated by ", "killed by ",
111111
/* PANICKED, TRICKED, QUIT, ESCAPED, ASCENDED */
112112
"", "", "", "", ""
113113
};
@@ -1076,6 +1076,8 @@ boolean so;
10761076
Strcat(linebuf, "was crushed to death");
10771077
} else if (!strncmp(t1->death, "petrified by ", 13)) {
10781078
Strcat(linebuf, "turned to stone");
1079+
} else if (!strncmp(t1->death, "decapitated by ", 15)) {
1080+
Strcat(linebuf, "decapitated");
10791081
} else
10801082
Strcat(linebuf, "died");
10811083

0 commit comments

Comments
 (0)