Unlock your quest by killing your quest leader
Allow killing your quest leader, just to make games winnable if you converted before doing the quest. Boost the quest leaders and give them some equipment. King Arthur gets Excalibur. Killing quest leader gives really bad luck and makes your god angry at you, and killing quest guardians gives smaller penalties. This is based on both the EvilHack implementation by k21971 <keith.simpson1971@gmail.com>, and xNetHack implementation by copperwater <aosdict@gmail.com>.
This commit is contained in:
12
src/mon.c
12
src/mon.c
@@ -2205,6 +2205,8 @@ m_detach(
|
||||
wizdead();
|
||||
if (mtmp->data->msound == MS_NEMESIS)
|
||||
nemdead();
|
||||
if (mtmp->data->msound == MS_LEADER)
|
||||
leaddead();
|
||||
if (mtmp->m_id == g.stealmid)
|
||||
thiefdead();
|
||||
relobj(mtmp, 0, FALSE);
|
||||
@@ -2926,12 +2928,17 @@ xkilled(
|
||||
/* adjust alignment points */
|
||||
if (mtmp->m_id == g.quest_status.leader_m_id) { /* REAL BAD! */
|
||||
adjalign(-(u.ualign.record + (int) ALIGNLIM / 2));
|
||||
u.ugangr += 7; /* instantly become "extremely" angry */
|
||||
change_luck(-20);
|
||||
pline("That was %sa bad idea...",
|
||||
u.uevent.qcompleted ? "probably " : "");
|
||||
} else if (mdat->msound == MS_NEMESIS) { /* Real good! */
|
||||
adjalign((int) (ALIGNLIM / 4));
|
||||
if (!g.quest_status.killed_leader)
|
||||
adjalign((int) (ALIGNLIM / 4));
|
||||
} else if (mdat->msound == MS_GUARDIAN) { /* Bad */
|
||||
adjalign(-(int) (ALIGNLIM / 8));
|
||||
u.ugangr++;
|
||||
change_luck(-4);
|
||||
if (!Hallucination)
|
||||
pline("That was probably a bad idea...");
|
||||
else
|
||||
@@ -3368,8 +3375,7 @@ setmangry(struct monst* mtmp, boolean via_attack)
|
||||
}
|
||||
|
||||
/* attacking your own quest leader will anger his or her guardians */
|
||||
if (!g.context.mon_moving /* should always be the case here */
|
||||
&& mtmp->data == &mons[quest_info(MS_LEADER)]) {
|
||||
if (mtmp->data == &mons[quest_info(MS_LEADER)]) {
|
||||
struct monst *mon;
|
||||
struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)];
|
||||
int got_mad = 0;
|
||||
|
||||
60
src/monst.c
60
src/monst.c
@@ -2854,25 +2854,25 @@ struct permonst _mons2[] = {
|
||||
/*
|
||||
* quest leaders
|
||||
*/
|
||||
MON("Lord Carnarvon", S_HUMAN, LVL(20, 12, 0, 30, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
MON("Lord Carnarvon", S_HUMAN, LVL(20, 15, 0, 90, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_MAGC, AD_SPEL, 4, 8),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), 0, 0,
|
||||
M1_TUNNEL | M1_NEEDPICK | M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
|
||||
MON("Pelias", S_HUMAN, LVL(20, 12, 0, 30, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
MON("Pelias", S_HUMAN, LVL(20, 15, 0, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_WEAP, AD_PHYS, 4, 10),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_POISON, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
|
||||
MON("Shaman Karnov", S_HUMAN, LVL(20, 12, 0, 30, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
MON("Shaman Karnov", S_HUMAN, LVL(20, 15, 0, 90, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_MAGC, AD_CLRC, 2, 8),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), 0, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
@@ -2900,23 +2900,23 @@ struct permonst _mons2[] = {
|
||||
| M2_FEMALE | M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISION | M3_INFRAVISIBLE, 22, HI_LORD),
|
||||
#endif
|
||||
MON("Hippocrates", S_HUMAN, LVL(20, 12, 0, 40, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
MON("Hippocrates", S_HUMAN, LVL(20, 15, 0, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_MAGC, AD_CLRC, 3, 8),
|
||||
ATTK(AT_MAGC, AD_CLRC, 3, 8), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_POISON, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
|
||||
MON("King Arthur", S_HUMAN, LVL(20, 12, 0, 40, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
|
||||
MON("King Arthur", S_HUMAN, LVL(20, 15, 0, 90, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_WEAP, AD_PHYS, 4, 10), NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), 0, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 23, HI_LORD),
|
||||
MON("Grand Master", S_HUMAN, LVL(25, 12, 0, 70, 0), (G_NOGEN | G_UNIQ),
|
||||
MON("Grand Master", S_HUMAN, LVL(25, 15, 0, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_CLAW, AD_PHYS, 4, 10), ATTK(AT_KICK, AD_PHYS, 2, 8),
|
||||
ATTK(AT_MAGC, AD_CLRC, 2, 8), ATTK(AT_MAGC, AD_CLRC, 2, 8), NO_ATTK,
|
||||
NO_ATTK),
|
||||
@@ -2926,7 +2926,7 @@ struct permonst _mons2[] = {
|
||||
M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_MALE | M2_NASTY
|
||||
| M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 30, CLR_BLACK),
|
||||
MON("Arch Priest", S_HUMAN, LVL(25, 12, 7, 70, 0), (G_NOGEN | G_UNIQ),
|
||||
MON("Arch Priest", S_HUMAN, LVL(25, 15, 7, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_KICK, AD_PHYS, 2, 8),
|
||||
ATTK(AT_MAGC, AD_CLRC, 2, 8), ATTK(AT_MAGC, AD_CLRC, 2, 8), NO_ATTK,
|
||||
NO_ATTK),
|
||||
@@ -2936,9 +2936,9 @@ struct permonst _mons2[] = {
|
||||
M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_MALE | M2_COLLECT
|
||||
| M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 30, CLR_WHITE),
|
||||
MON("Orion", S_HUMAN, LVL(20, 12, 0, 30, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
|
||||
NO_ATTK),
|
||||
MON("Orion", S_HUMAN, LVL(20, 15, 0, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_MAGC, AD_SPEL, 4, 8),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(2200, 700, MS_LEADER, MZ_HUGE), 0, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS | M1_SWIM | M1_AMPHIBIOUS,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
@@ -2946,43 +2946,43 @@ struct permonst _mons2[] = {
|
||||
M3_CLOSE | M3_INFRAVISION | M3_INFRAVISIBLE, 22, HI_LORD),
|
||||
/* Note: Master of Thieves is also the Tourist's nemesis.
|
||||
*/
|
||||
MON("Master of Thieves", S_HUMAN, LVL(20, 12, 0, 30, -20),
|
||||
MON("Master of Thieves", S_HUMAN, LVL(20, 15, 0, 90, -20),
|
||||
(G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_WEAP, AD_PHYS, 2, 6),
|
||||
ATTK(AT_CLAW, AD_SAMU, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_STONE, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_MALE | M2_GREEDY
|
||||
| M2_JEWELS | M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 24, HI_LORD),
|
||||
MON("Lord Sato", S_HUMAN, LVL(20, 12, 0, 30, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
|
||||
MON("Lord Sato", S_HUMAN, LVL(20, 15, 0, 90, 20), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_WEAP, AD_PHYS, 4, 10), NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), 0, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 23, HI_LORD),
|
||||
MON("Twoflower", S_HUMAN, LVL(20, 12, 10, 20, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
|
||||
MON("Twoflower", S_HUMAN, LVL(20, 15, 10, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), NO_ATTK, NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), 0, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 22, HI_DOMESTIC),
|
||||
MON("Norn", S_HUMAN, LVL(20, 12, 0, 80, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
|
||||
MON("Norn", S_HUMAN, LVL(20, 15, 0, 90, 0), (G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_WEAP, AD_PHYS, 4, 10), NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(1800, 550, MS_LEADER, MZ_HUGE), MR_COLD, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_FEMALE
|
||||
| M2_COLLECT | M2_MAGIC,
|
||||
M3_CLOSE | M3_INFRAVISIBLE, 23, HI_LORD),
|
||||
MON("Neferet the Green", S_HUMAN, LVL(20, 12, 0, 60, 0),
|
||||
MON("Neferet the Green", S_HUMAN, LVL(20, 15, 0, 90, 0),
|
||||
(G_NOGEN | G_UNIQ),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_MAGC, AD_SPEL, 2, 8), NO_ATTK,
|
||||
NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_MAGC, AD_SPEL, 2, 8),
|
||||
ATTK(AT_MAGC, AD_SPEL, 2, 8), NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), 0, 0,
|
||||
M1_HUMANOID | M1_OMNIVORE,
|
||||
M2_NOPOLY | M2_HUMAN | M2_FEMALE | M2_PNAME | M2_PEACEFUL | M2_STRONG
|
||||
|
||||
56
src/quest.c
56
src/quest.c
@@ -17,7 +17,7 @@ static void on_goal(void);
|
||||
static boolean not_capable(void);
|
||||
static int is_pure(boolean);
|
||||
static void expulsion(boolean);
|
||||
static void chat_with_leader(void);
|
||||
static void chat_with_leader(struct monst *);
|
||||
static void chat_with_nemesis(void);
|
||||
static void chat_with_guardian(void);
|
||||
static void prisoner_speaks(struct monst *);
|
||||
@@ -112,6 +112,15 @@ nemdead(void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
leaddead(void)
|
||||
{
|
||||
if (!Qstat(killed_leader)) {
|
||||
Qstat(killed_leader) = TRUE;
|
||||
/* TODO: qt_pager("killed_leader"); ? */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
artitouch(struct obj *obj)
|
||||
{
|
||||
@@ -130,8 +139,8 @@ artitouch(struct obj *obj)
|
||||
boolean
|
||||
ok_to_quest(void)
|
||||
{
|
||||
return (boolean) ((Qstat(got_quest) || Qstat(got_thanks))
|
||||
&& is_pure(FALSE) > 0);
|
||||
return (boolean) (((Qstat(got_quest) || Qstat(got_thanks))
|
||||
&& is_pure(FALSE) > 0) || Qstat(killed_leader));
|
||||
}
|
||||
|
||||
static boolean
|
||||
@@ -240,8 +249,11 @@ finish_quest(struct obj *obj) /* quest artifact; possibly null if carrying
|
||||
}
|
||||
|
||||
static void
|
||||
chat_with_leader(void)
|
||||
chat_with_leader(struct monst *mtmp)
|
||||
{
|
||||
if (!mtmp->mpeaceful || Qstat(pissed_off))
|
||||
return;
|
||||
|
||||
/* Rule 0: Cheater checks. */
|
||||
if (u.uhave.questart && !Qstat(met_nemesis))
|
||||
Qstat(cheater) = TRUE;
|
||||
@@ -293,18 +305,16 @@ chat_with_leader(void)
|
||||
exercise(A_WIS, TRUE);
|
||||
expulsion(FALSE);
|
||||
} else if ((purity = is_pure(TRUE)) < 0) {
|
||||
com_pager("banished");
|
||||
expulsion(TRUE);
|
||||
} else if (purity == 0) {
|
||||
qt_pager("badalign");
|
||||
if (Qstat(not_ready) == MAX_QUEST_TRIES) {
|
||||
qt_pager("leader_last");
|
||||
expulsion(TRUE);
|
||||
} else {
|
||||
Qstat(not_ready)++;
|
||||
exercise(A_WIS, TRUE);
|
||||
if (!Qstat(pissed_off)) {
|
||||
com_pager("banished");
|
||||
Qstat(pissed_off) = TRUE;
|
||||
expulsion(FALSE);
|
||||
}
|
||||
} else if (purity == 0) {
|
||||
qt_pager("badalign");
|
||||
Qstat(not_ready) = 1;
|
||||
exercise(A_WIS, TRUE);
|
||||
expulsion(FALSE);
|
||||
} else { /* You are worthy! */
|
||||
qt_pager("assignquest");
|
||||
exercise(A_WIS, TRUE);
|
||||
@@ -318,6 +328,12 @@ leader_speaks(struct monst *mtmp)
|
||||
{
|
||||
/* maybe you attacked leader? */
|
||||
if (!mtmp->mpeaceful) {
|
||||
if (!Qstat(pissed_off)) {
|
||||
/* again, don't end it permanently if the leader gets angry
|
||||
* since you're going to have to kill him to go questing... :)
|
||||
* ...but do only show this crap once. */
|
||||
qt_pager("leader_last");
|
||||
}
|
||||
Qstat(pissed_off) = TRUE;
|
||||
mtmp->mstrategy &= ~STRAT_WAITMASK; /* end the inaction */
|
||||
}
|
||||
@@ -326,11 +342,8 @@ leader_speaks(struct monst *mtmp)
|
||||
if (!on_level(&u.uz, &qstart_level))
|
||||
return;
|
||||
|
||||
if (Qstat(pissed_off)) {
|
||||
qt_pager("leader_last");
|
||||
expulsion(TRUE);
|
||||
} else
|
||||
chat_with_leader();
|
||||
if (!Qstat(pissed_off))
|
||||
chat_with_leader(mtmp);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -399,7 +412,10 @@ void
|
||||
quest_chat(struct monst *mtmp)
|
||||
{
|
||||
if (mtmp->m_id == Qstat(leader_m_id)) {
|
||||
chat_with_leader();
|
||||
chat_with_leader(mtmp);
|
||||
/* leader might have become pissed during the chat */
|
||||
if (Qstat(pissed_off))
|
||||
setmangry(mtmp, FALSE);
|
||||
return;
|
||||
}
|
||||
switch (mtmp->data->msound) {
|
||||
|
||||
@@ -499,6 +499,9 @@ nh_timeout(void)
|
||||
if (flags.friday13)
|
||||
baseluck -= 1;
|
||||
|
||||
if (g.quest_status.killed_leader)
|
||||
baseluck -= 4;
|
||||
|
||||
if (u.uluck != baseluck
|
||||
&& g.moves % ((u.uhave.amulet || u.ugangr) ? 300 : 600) == 0) {
|
||||
/* Cursed luckstones stop bad luck from timing out; blessed luckstones
|
||||
|
||||
Reference in New Issue
Block a user