PR #1096 - more quest leader interactions

Pull request from entrez:  implement a couple of features that were
mentioned in new comments in the 'fixes entry' commit when PR #1093
was adopted.
1) throwing/kicking an unIDed fake amulet of Yendor at the quest
   leader will identify it rather than be considered an attack;
2) throwing/kicking the Bell of Opening, Candelabrum of Invocation,
   or Book of the Dead at the leader will ID the item as in #1093,
   but if the invocation has already been performed, the leader will
   keep the item rather than return it.

Closes #1096
This commit is contained in:
PatR
2023-09-22 21:40:56 -07:00
2 changed files with 36 additions and 22 deletions

View File

@@ -1921,7 +1921,8 @@ tmiss(struct obj *obj, struct monst *mon, boolean maybe_wakeup)
}
#define special_obj_hits_leader(obj, mon) \
((is_quest_artifact(obj) || objects[obj->otyp].oc_unique) \
((is_quest_artifact(obj) || objects[obj->otyp].oc_unique \
|| (obj->otyp == FAKE_AMULET_OF_YENDOR && !obj->known)) \
&& mon->m_id == gq.quest_status.leader_m_id)
/*
@@ -2032,7 +2033,30 @@ thitmonst(
if (mon->mcanmove) {
pline("%s catches %s.", Some_Monnam(mon), the(xname(obj)));
if (mon->mpeaceful) {
/* leader will keep tossed invocation item after you've done the
invocation and it's become unnecessary for completion.. */
if ((u.uevent.invoked && objects[obj->otyp].oc_unique
&& obj->otyp != AMULET_OF_YENDOR)
/* ...or any special item, if you've made him angry */
|| !mon->mpeaceful) {
/* give an explanation for keeping the item only if leader is
not doing it out of anger */
if (mon->mpeaceful && !Deaf) {
/* just in case, identify the object so its name will
appear in the message */
fully_identify_obj(obj);
verbalize("%s part in this is finished.",
s_suffix(The(xname(obj))));
verbalize(
"We will guard it in case it is ever needed again, %s forbid.",
align_gname(u.ualignbase[A_ORIGINAL]));
}
if (*u.ushops || obj->unpaid) /* not very likely... */
check_shop_obj(obj, mon->mx, mon->my, FALSE);
(void) mpickobj(mon, obj);
} else {
/* under normal circumstances, leader will say something and
then return the item to the hero */
boolean next2u = monnear(mon, u.ux, u.uy);
finish_quest(obj); /* acknowledge quest completion */
@@ -2042,11 +2066,6 @@ thitmonst(
sho_obj_return_to_u(obj);
obj = addinv(obj); /* back into your inventory */
(void) encumber_msg();
} else {
/* angry leader caught it and isn't returning it */
if (*u.ushops || obj->unpaid) /* not very likely... */
check_shop_obj(obj, mon->mx, mon->my, FALSE);
(void) mpickobj(mon, obj);
}
return 1; /* caller doesn't need to place it */
}

View File

@@ -223,22 +223,13 @@ expulsion(boolean seal)
if hero throws or kicks an invocation item (probably the Bell)
at the leader. */
void
finish_quest(struct obj *obj) /* quest artifact or thrown unique item;
* possibly null if carrying the Amulet */
finish_quest(struct obj *obj) /* quest artifact or thrown unique item or faux
* AoY; possibly null if carrying the Amulet */
{
struct obj *otmp;
/*
* Possible extensions [would mostly need to be done in thitmonst()]:
* if the invocation has already been performed, leader keeps any
* thrown (or kicked) invocation item, perhaps stating the intent
* to guard it for the future;
* if the item is an unidentified fake Amulet, identify it instead
* of treating the throw as an attack.
*/
if (obj && objects[obj->otyp].oc_unique) {
/* tossed one of the invocation items (or AoY) at the quest leader */
if (obj && !is_quest_artifact(obj)) {
/* tossed an invocation item (or [fake] 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
@@ -246,10 +237,14 @@ finish_quest(struct obj *obj) /* quest artifact or thrown unique item;
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)
if (obj->otyp == AMULET_OF_YENDOR) {
qt_pager("hasamulet");
else
} else if (obj->otyp == FAKE_AMULET_OF_YENDOR) {
verbalize(
"Sorry to say, this is a mere imitation of the true Amulet of Yendor.");
} else {
verbalize("Ah, I see you've found %s.", the(xname(obj)));
}
return;
}