From: PatR Date: Mon, 11 Apr 2022 18:34:53 +0000 (-0700) Subject: inventory context: drop and wield X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f68b90e1eacd76fece1f1beb7c8050be2ec2bb97;p=nethack inventory context: drop and wield For context-sensitive actions when picking an item from inventory, exclude drop and wield from the choices if the item is being worn. Move 'O'ffer into alphabetical order. Formatting: fix a couple of cases of '&&' or '||' placed at the end of first half of a split line instead of at the start of second half. --- diff --git a/src/invent.c b/src/invent.c index 76dafd4b2..15f2bc874 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2545,6 +2545,7 @@ itemactions(struct obj *otmp) menu_item *selected; struct monst *mtmp; const char *light = otmp->lamplit ? "Extinguish" : "Light"; + boolean already_worn = (otmp->owornmask & (W_ARMOR | W_ACCESSORY)) != 0; win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); @@ -2638,8 +2639,11 @@ itemactions(struct obj *otmp) else if (otmp->oclass == WAND_CLASS) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Break this wand"); - /* d: drop item, works on everything */ - ia_addmenu(win, IA_DROP_OBJ, 'd', "Drop this item"); + /* d: drop item, works on everything except worn items; those will + always have a takeoff/remove choice so we don't have to worry + about the menu maybe being empty when 'd' is suppressed */ + if (!already_worn) + ia_addmenu(win, IA_DROP_OBJ, 'd', "Drop this item"); /* e: eat item */ if (otmp->otyp == TIN && uwep && uwep->otyp == TIN_OPENER) @@ -2660,13 +2664,29 @@ itemactions(struct obj *otmp) ia_addmenu(win, IA_ENGRAVE_OBJ, 'E', "Write on the floor with this object"); + /* O: offer sacrifice */ + if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) { + /* FIXME: this doesn't match #offer's likely candidates, which don't + include corpses on Astral and don't include amulets off Astral */ + if (otmp->otyp == CORPSE) + ia_addmenu(win, IA_SACRIFICE, 'O', + "Offer this corpse as a sacrifice at this altar"); + else if (otmp->otyp == AMULET_OF_YENDOR + || otmp->otyp == FAKE_AMULET_OF_YENDOR) + ia_addmenu(win, IA_SACRIFICE, 'O', + "Offer this amulet as a sacrifice at this altar"); + } + /* p: pay for unpaid utems */ - if ((mtmp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE))) && - inhishop(mtmp) && otmp->unpaid) + if (otmp->unpaid + /* FIXME: should also handle player owned container (so not + flagged 'unpaid') holding shop owned items */ + && (mtmp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE))) != 0 + && inhishop(mtmp)) ia_addmenu(win, IA_BUY_OBJ, 'p', "Buy this unpaid item"); /* P: put on accessory */ - if (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))) { + if (!already_worn) { if (otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) ia_addmenu(win, IA_WEAR_OBJ, 'P', "Put this ring on"); else if (otmp->oclass == AMULET_CLASS) @@ -2703,7 +2723,7 @@ itemactions(struct obj *otmp) ia_addmenu(win, IA_READ_OBJ, 'r', "Study this spellbook"); /* R: remove accessory or rub item */ - if (otmp->owornmask & (W_RING | W_AMUL | W_TOOL)) + if (otmp->owornmask & W_ACCESSORY) ia_addmenu(win, IA_TAKEOFF_OBJ, 'R', "Remove this accessory"); if (otmp->otyp == OIL_LAMP || otmp->otyp == MAGIC_LAMP || otmp->otyp == BRASS_LANTERN) { @@ -2713,7 +2733,7 @@ itemactions(struct obj *otmp) ia_addmenu(win, IA_RUB_OBJ, 'R', "Rub something on this stone"); /* t: throw item */ - if (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))) { + if (!already_worn) { const char *verb = ammo_and_launcher(otmp, uwep) ? "Shoot" : "Throw"; /* @@ -2740,8 +2760,11 @@ itemactions(struct obj *otmp) "Tip all the contents out of this container"); /* V: invoke */ - if ((otmp->otyp == FAKE_AMULET_OF_YENDOR && !otmp->known) || - otmp->oartifact || objects[otmp->otyp].oc_unique) + if ((otmp->otyp == FAKE_AMULET_OF_YENDOR && !otmp->known) + || otmp->oartifact || objects[otmp->otyp].oc_unique + /* non-artifact crystal balls don't have any unique power but + the #invoke command lists them as likely candidates */ + || otmp->otyp == CRYSTAL_BALL) ia_addmenu(win, IA_INVOKE_OBJ, 'V', "Try to invoke a unique power of this object"); @@ -2754,13 +2777,13 @@ itemactions(struct obj *otmp) ia_addmenu(win, IA_WIELD_OBJ, 'w', "Wield this as your weapon"); else if (otmp->otyp == TIN_OPENER) ia_addmenu(win, IA_WIELD_OBJ, 'w', "Hold the tin opener to open tins"); - else + else if (!already_worn) /* FIXME: there's no concept of "holding an item" that's any different from having it in inventory; 'w' means wield as weapon */ ia_addmenu(win, IA_WIELD_OBJ, 'w', "Hold this item in your hands"); /* W: wear armor */ - if (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))) { + if (!already_worn) { if (otmp->oclass == ARMOR_CLASS) ia_addmenu(win, IA_WEAR_OBJ, 'W', "Wear this armor"); } @@ -2779,16 +2802,6 @@ itemactions(struct obj *otmp) if (otmp->oclass == WAND_CLASS) ia_addmenu(win, IA_ZAP_OBJ, 'z', "Zap this wand to release its magic"); - if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) { - if (otmp->otyp == CORPSE) - ia_addmenu(win, IA_SACRIFICE, 'O', - "Offer this corpse as a sacrifice at this altar"); - else if (otmp->otyp == AMULET_OF_YENDOR - || otmp->otyp == FAKE_AMULET_OF_YENDOR) - ia_addmenu(win, IA_SACRIFICE, 'O', - "Offer this amulet as a sacrifice at this altar"); - } - Sprintf(buf, "Do what with %s?", the(cxname(otmp))); end_menu(win, buf);