Allow quest leader to catch and return unique item

It's been possible for a while to throw your quest artifact to your
quest leader, completing the quest (he will then throw the object back
to you).  The quest leader will also react to being brought the Amulet
of Yendor (i.e. having it in inventory when you approach or #chat), but
tossing it over like the quest artifact was treated as a hostile act and
would cause the quest leader and guardians to become hostile and attack
the hero.

Make throwing the Amulet of Yendor at the quest leader work like
throwing the quest artifact, and treat the invocation items similarly
just in case people try throwing those (maybe because they are lost,
unsure what to do, and have already seen their quest leader catch and
react to the quest artifact -- regardless of the reason, throwing over
the Book of the Dead is almost certainly not intended to be an attack).
Doing so for invocation items will ID them but not do much more than
that.  The Amulet of Yendor triggers the existing quest pager message.
This commit is contained in:
Michael Meyer
2023-09-17 02:11:51 -04:00
committed by PatR
parent e2203ef9a1
commit bda0b3b807
2 changed files with 30 additions and 7 deletions

View File

@@ -1920,8 +1920,8 @@ tmiss(struct obj *obj, struct monst *mon, boolean maybe_wakeup)
return;
}
#define quest_arti_hits_leader(obj, mon) \
(obj->oartifact && is_quest_artifact(obj) \
#define special_obj_hits_leader(obj, mon) \
((is_quest_artifact(obj) || objects[obj->otyp].oc_unique) \
&& mon->m_id == gq.quest_status.leader_m_id)
/*
@@ -2024,7 +2024,7 @@ thitmonst(
/* don't make game unwinnable if naive player throws artifact
at leader... (kicked artifact is ok too; HMON_APPLIED could
occur if quest artifact polearm or grapnel ever gets added) */
if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) {
if (hmode != HMON_APPLIED && special_obj_hits_leader(obj, mon)) {
/* AIS: changes to wakeup() means that it's now less inappropriate
here than it used to be, but manual version works just as well */
mon->msleeping = 0;

View File

@@ -221,17 +221,40 @@ expulsion(boolean seal)
give another message about the character keeping the artifact
and using the magic portal to return to the dungeon. */
void
finish_quest(struct obj *obj) /* quest artifact; possibly null if carrying
Amulet */
finish_quest(struct obj *obj) /* quest artifact or thrown unique item;
possibly null if carrying Amulet */
{
struct obj *otmp;
if (u.uhave.amulet) { /* unlikely but not impossible */
if (obj && objects[obj->otyp].oc_unique) {
/* tossed one of the invocation items (or AoY) at the quest leader */
if (Deaf)
return; /* optional (unlike quest completion) so skip if deaf */
/* do ID first so that the message identifying the item will refer to
it by name (and so justify the ID we already gave...) */
fully_identify_obj(obj);
/* update_inventory() is not necessary or helpful here because item
was thrown, so isn't currently in inventory anyway */
if (obj->otyp == AMULET_OF_YENDOR)
qt_pager("hasamulet");
else
verbalize("Ah, I see you've found %s.", the(xname(obj)));
return;
}
if (u.uhave.amulet) {
/* has the amulet in inventory -- most likely the player has already
completed the quest and stopped in on her way back up, but it's not
impossible to have gotten the amulet before formally presenting the
quest artifact to the leader. */
qt_pager("hasamulet");
/* leader IDs the real amulet but ignores any fakes */
if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
if ((otmp = carrying(AMULET_OF_YENDOR)) != (struct obj *) 0) {
fully_identify_obj(otmp);
update_inventory();
}
} else {
/* normal quest completion; threw artifact or walked up carrying it */
qt_pager(!Qstat(got_thanks) ? "offeredit" : "offeredit2");
/* should have obtained bell during quest;
if not, suggest returning for it now */