diff --git a/dat/Arc-strt.lua b/dat/Arc-strt.lua index 5f759b575..4bccd8441 100644 --- a/dat/Arc-strt.lua +++ b/dat/Arc-strt.lua @@ -70,7 +70,10 @@ des.door("locked",24,14) des.door("closed",31,14) des.door("locked",49,14) -- Lord Carnarvon -des.monster("Lord Carnarvon", 25, 10) +des.monster({ id = "Lord Carnarvon", coord = {25, 10}, inventory = function() + des.object({ id = "fedora", spe = 5 }); + des.object({ id = "bullwhip", spe = 4 }); +end }) -- The treasure of Lord Carnarvon des.object("chest", 25, 10) -- student guards for the audience chamber diff --git a/dat/Bar-strt.lua b/dat/Bar-strt.lua index 79df053e7..57297b73a 100644 --- a/dat/Bar-strt.lua +++ b/dat/Bar-strt.lua @@ -69,7 +69,10 @@ des.door("open",23,13) des.door("open",25,10) des.door("open",28,05) -- Elder -des.monster("Pelias", 10, 07) +des.monster({ id = "Pelias", coord = {10, 07}, inventory = function() + des.object({ id = "runesword", spe = 5 }); + des.object({ id = "chain mail", spe = 5 }); +end }) -- The treasure of Pelias des.object("chest", 09, 05) -- chieftain guards for the audience chamber diff --git a/dat/Cav-strt.lua b/dat/Cav-strt.lua index 83c071d0c..d4b974bd2 100644 --- a/dat/Cav-strt.lua +++ b/dat/Cav-strt.lua @@ -54,7 +54,10 @@ des.door("locked",19,06) -- The temple altar (this will force a priest(ess) to be created) des.altar({ x=36,y=02, align="coaligned", type="shrine" }) -- Shaman Karnov -des.monster("Shaman Karnov", 35, 02) +des.monster({ id = "Shaman Karnov", coord = {35, 02}, inventory = function() + des.object({ id = "leather armor", spe = 5 }); + des.object({ id = "club", spe = 5 }); +end }) -- The treasure of Shaman Karnov des.object("chest", 34, 02) -- neanderthal guards for the audience chamber diff --git a/dat/Hea-strt.lua b/dat/Hea-strt.lua index 1a2f64acc..a936f0212 100644 --- a/dat/Hea-strt.lua +++ b/dat/Hea-strt.lua @@ -60,7 +60,9 @@ des.door("closed",47,08) des.door("closed",48,12) des.door("locked",50,10) -- Hippocrates -des.monster("Hippocrates", 37, 10) +des.monster({ id = "Hippocrates", coord = {37, 10}, inventory = function() + des.object({ id = "silver dagger", spe = 5 }); +end }) -- The treasure of Hippocrates des.object("chest", 37, 10) -- intern guards for the audience chamber diff --git a/dat/Kni-strt.lua b/dat/Kni-strt.lua index 4442d93a7..d7f9284c5 100644 --- a/dat/Kni-strt.lua +++ b/dat/Kni-strt.lua @@ -62,7 +62,10 @@ des.door("closed",45,03) des.door("closed",04,12) des.door("closed",45,12) -- King Arthur -des.monster("King Arthur", 09, 07) +des.monster({ id = "King Arthur", coord = {09, 07}, inventory = function() + des.object({ id = "long sword", spe = 4, buc = "blessed", name = "Excalibur" }); + des.object({ id = "plate mail", spe = 4 }); +end }) -- The treasure of King Arthur des.object("chest", 09, 07) -- knight guards for the watchrooms diff --git a/dat/Mon-strt.lua b/dat/Mon-strt.lua index ae1ad77d0..0ae685a69 100644 --- a/dat/Mon-strt.lua +++ b/dat/Mon-strt.lua @@ -71,7 +71,9 @@ des.door("closed",52,14) -- Unattended Altar - unaligned due to conflict - player must align it. des.altar({ x=28,y=09, align="noalign", type="altar" }) -- The Grand Master -des.monster("Grand Master", 28, 10) +des.monster({ id = "Grand Master", coord = {28, 10}, inventory = function() + des.object({ id = "robe", spe = 6 }); +end }) -- No treasure chest! -- guards for the audience chamber des.monster("abbot", 32, 07) diff --git a/dat/Pri-strt.lua b/dat/Pri-strt.lua index 480a6276d..fb66e6492 100644 --- a/dat/Pri-strt.lua +++ b/dat/Pri-strt.lua @@ -71,7 +71,10 @@ des.door("closed",52,14) -- Unattended Altar - unaligned due to conflict - player must align it. des.altar({ x=28, y=09, align="noalign", type="altar" }) -- High Priest -des.monster("Arch Priest", 28, 10) +des.monster({ id = "Arch Priest", coord = {28, 10}, inventory = function() + des.object({ id = "robe", spe = 4 }); + des.object({ id = "mace", spe = 4 }); +end }) -- The treasure of High Priest des.object("chest", 27, 10) -- knight guards for the audience chamber diff --git a/dat/Ran-strt.lua b/dat/Ran-strt.lua index 69004ebb6..388dd7e9c 100644 --- a/dat/Ran-strt.lua +++ b/dat/Ran-strt.lua @@ -46,7 +46,11 @@ des.stair("down", 10,10) -- Portal arrival point; just about anywhere on the right hand side of the map des.levregion({ region = {51,2,77,18}, region_islev = 1, type="branch" }) -- Orion -des.monster("Orion", 20, 10) +des.monster({ id = "Orion", coord = {20, 10}, inventory = function() + des.object({ id = "leather armor", spe = 4 }); + des.object({ id = "yumi", spe = 4 }); + des.object({ id = "arrow", spe = 4, quantity = 50 }); +end }) -- The treasure of Orion des.object("chest", 20, 10) -- Guards for the audience chamber diff --git a/dat/Rog-strt.lua b/dat/Rog-strt.lua index 58f27f696..b2fd32a79 100644 --- a/dat/Rog-strt.lua +++ b/dat/Rog-strt.lua @@ -103,7 +103,11 @@ des.door("closed", 6,18) des.door("closed", 65,18) des.door("closed", 68,18) -- Master of Thieves -des.monster("Master of Thieves", 36, 11) +des.monster({ id = "Master of Thieves", coord = {36, 11}, inventory = function() + des.object({ id = "leather armor", spe = 5 }); + des.object({ id = "silver dagger", spe = 4 }); + des.object({ id = "dagger", spe = 2, quantity = d(2,4), buc = "not-cursed" }); +end }) -- The treasure of Master of Thieves des.object("chest", 36, 11) -- thug guards, room #1 diff --git a/dat/Sam-strt.lua b/dat/Sam-strt.lua index 8186c3cb4..e7c930bee 100644 --- a/dat/Sam-strt.lua +++ b/dat/Sam-strt.lua @@ -54,7 +54,10 @@ des.door("locked",39,08) des.door("closed",50,04) des.door("closed",50,06) -- Lord Sato -des.monster("Lord Sato", 20, 04) +des.monster({ id = "Lord Sato", coord = {20, 04}, inventory = function() + des.object({ id = "splint mail", spe = 5 }); + des.object({ id = "katana", spe = 4 }); +end }) -- The treasure of Lord Sato des.object("chest", 20, 04) -- roshi guards for the audience chamber diff --git a/dat/Tou-strt.lua b/dat/Tou-strt.lua index c5efa0d29..e7a4f7812 100644 --- a/dat/Tou-strt.lua +++ b/dat/Tou-strt.lua @@ -95,7 +95,10 @@ des.monster("forest centaur") des.monster("forest centaur") des.monster("C") -- Twoflower -des.monster("Twoflower", 64, 03) +des.monster({ id = "Twoflower", coord = {64, 03}, inventory = function() + des.object({ id = "walking shoes", spe = 3 }); + des.object({ id = "hawaiian shirt", spe = 3 }); +end }) -- The treasure of Twoflower des.object("chest", 64, 03) -- guides for the audience chamber diff --git a/dat/Val-strt.lua b/dat/Val-strt.lua index dbce2280d..545dbce6c 100644 --- a/dat/Val-strt.lua +++ b/dat/Val-strt.lua @@ -61,7 +61,10 @@ des.feature("fountain", 53,02) des.door("locked",26,10) des.door("locked",43,10) -- Norn -des.monster("Norn", 35, 10) +des.monster({ id = "Norn", coord = {35, 10}, inventory = function() + des.object({ id = "banded mail", spe = 5 }); + des.object({ id = "long sword", spe = 4 }); +end }) -- The treasure of the Norn des.object("chest", 36, 10) -- valkyrie guards for the audience chamber diff --git a/dat/Wiz-strt.lua b/dat/Wiz-strt.lua index 715cb5744..69172039e 100644 --- a/dat/Wiz-strt.lua +++ b/dat/Wiz-strt.lua @@ -61,7 +61,10 @@ des.door("closed",15,10) des.door("locked",19,10) des.door("locked",20,10) -- Neferet the Green, the quest leader -des.monster("Neferet the Green", 23, 05) +des.monster({ id = "Neferet the Green", coord = {23, 05}, inventory = function() + des.object({ id = "elven cloak", spe = 5 }); + des.object({ id = "quarterstaff", spe = 5 }); +end }) -- The treasure of the quest leader des.object("chest", 24, 05) -- apprentice guards for the audience chamber diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a06c27ea4..5eadb3ae3 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -532,6 +532,8 @@ make anti-magic fields drain more energy and prevent them from showing up eating magical monsters such as wizards or shamans may give a mild buzz make exploding spheres create an actual explosion pets are more careful about attacking monsters at low health +allow killing your quest leader to open the quest +give King Arthur Excalibur Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 548280a50..c9d666210 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2064,6 +2064,7 @@ extern void free_epri(struct monst *); extern void onquest(void); extern void nemdead(void); +extern void leaddead(void); extern void artitouch(struct obj *); extern boolean ok_to_quest(void); extern void leader_speaks(struct monst *); diff --git a/include/patchlevel.h b/include/patchlevel.h index 700a80582..9b4b90091 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 33 +#define EDITLEVEL 34 /* * Development status possibilities. diff --git a/include/quest.h b/include/quest.h index 710af02d9..88fd47eca 100644 --- a/include/quest.h +++ b/include/quest.h @@ -11,6 +11,7 @@ struct q_score { /* Quest "scorecard" */ Bitfield(not_ready, 3); /* rejected due to alignment, etc. */ Bitfield(pissed_off, 1); /* got the leader angry */ Bitfield(got_quest, 1); /* got the quest assignment */ + Bitfield(killed_leader, 1); /* killed the quest leader */ Bitfield(first_locate, 1); /* only set the first time */ Bitfield(met_intermed, 1); /* used if the locate is a person. */ @@ -39,7 +40,6 @@ struct q_score { /* Quest "scorecard" */ unsigned leader_m_id; }; -#define MAX_QUEST_TRIES 7 /* exceed this and you "fail" */ #define MIN_QUEST_ALIGN 20 /* at least this align.record to start */ /* note: align 20 matches "pious" as reported by enlightenment (cmd.c) */ #define MIN_QUEST_LEVEL 14 /* at least this u.ulevel to start */ diff --git a/src/mon.c b/src/mon.c index 423ff0317..b63a3ec91 100644 --- a/src/mon.c +++ b/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; diff --git a/src/monst.c b/src/monst.c index 1da91df09..4f837d1b3 100644 --- a/src/monst.c +++ b/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 diff --git a/src/quest.c b/src/quest.c index 575f4fef8..23d7037ac 100644 --- a/src/quest.c +++ b/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) { diff --git a/src/timeout.c b/src/timeout.c index 47434ad7a..bacf359d7 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -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