item action 'T' against covered armor

Using 'i'+menu choice for suit+'T' to try to take off a suit that is
covered by a cloak (or shirt covered by suit and/or cloak) wouldn't
do anything.  It should report that you need to take off the outer
garment first and then not take the chosen item off.

There is probably a simpler fix.  It took me a long time to figure
where things were going wrong and them cobble this together.

A big chunk of the diff for invent.c is just identation, surrounding
a one-line change there.
This commit is contained in:
PatR
2025-10-20 13:29:42 -07:00
parent a9f84bfe9a
commit 966145a61d
6 changed files with 168 additions and 145 deletions

View File

@@ -2980,142 +2980,142 @@ ia_addmenu(winid win, int act, char let, const char *txt)
ATR_NONE, clr, txt, MENU_ITEMFLAGS_NONE);
}
/* set up a command to execute on a specific item next */
staticfn void
itemactions_pushkeys(struct obj *otmp, int act)
{
switch (act) {
default:
impossible("Unknown item action");
break;
case IA_NONE:
break;
case IA_UNWIELD:
cmdq_add_ec(CQ_CANNED, (otmp == uwep) ? dowield
: (otmp == uswapwep) ? remarm_swapwep
: (otmp == uquiver) ? dowieldquiver
: donull); /* can't happen */
cmdq_add_key(CQ_CANNED, '-');
break;
case IA_APPLY_OBJ:
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_DIP_OBJ:
/* #altdip instead of normal #dip - takes potion to dip into
first (the inventory item instigating this) and item to
be dipped second, also ignores floor features such as
fountain/sink so we don't need to force m-prefix here */
cmdq_add_ec(CQ_CANNED, dip_into);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_NAME_OBJ:
case IA_NAME_OTYP:
cmdq_add_ec(CQ_CANNED, docallcmd);
cmdq_add_key(CQ_CANNED, (act == IA_NAME_OBJ) ? 'i' : 'o');
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_DROP_OBJ:
cmdq_add_ec(CQ_CANNED, dodrop);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_EAT_OBJ:
/* start with m-prefix; for #eat, it means ignore floor food
if present and eat food from invent */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, doeat);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ENGRAVE_OBJ:
cmdq_add_ec(CQ_CANNED, doengrave);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_FIRE_OBJ:
cmdq_add_ec(CQ_CANNED, dofire);
break;
case IA_ADJUST_OBJ:
cmdq_add_ec(CQ_CANNED, doorganize); /* #adjust */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ADJUST_STACK:
cmdq_add_ec(CQ_CANNED, adjust_split); /* #altadjust */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_SACRIFICE:
cmdq_add_ec(CQ_CANNED, dosacrifice);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_BUY_OBJ:
cmdq_add_ec(CQ_CANNED, dopay);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_QUAFF_OBJ:
/* start with m-prefix; for #quaff, it means ignore fountain
or sink if present and drink a potion from invent */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, dodrink);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_QUIVER_OBJ:
cmdq_add_ec(CQ_CANNED, dowieldquiver);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_READ_OBJ:
cmdq_add_ec(CQ_CANNED, doread);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_RUB_OBJ:
cmdq_add_ec(CQ_CANNED, dorub);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_THROW_OBJ:
cmdq_add_ec(CQ_CANNED, dothrow);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_TAKEOFF_OBJ:
cmdq_add_ec(CQ_CANNED, dotakeoff);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_TIP_CONTAINER:
/* start with m-prefix to skip floor containers;
for menustyle:Traditional when more than one floor
container is present, player will get a #tip menu and
have to pick the "tip something being carried" choice,
then this item will be already chosen from inventory;
suboptimal but possibly an acceptable tradeoff since
combining item actions with use of traditional ggetobj()
is an unlikely scenario */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, dotip);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_INVOKE_OBJ:
cmdq_add_ec(CQ_CANNED, doinvoke);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WIELD_OBJ:
cmdq_add_ec(CQ_CANNED, dowield);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WEAR_OBJ:
cmdq_add_ec(CQ_CANNED, dowear);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_SWAPWEAPON:
cmdq_add_ec(CQ_CANNED, doswapweapon);
break;
case IA_TWOWEAPON:
cmdq_add_ec(CQ_CANNED, dotwoweapon);
break;
case IA_ZAP_OBJ:
cmdq_add_ec(CQ_CANNED, dozap);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WHATIS_OBJ:
cmdq_add_ec(CQ_CANNED, dowhatis); /* "/" command */
cmdq_add_key(CQ_CANNED, 'i'); /* "i" == item from inventory */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
}
switch (act) {
default:
impossible("Unknown item action %d", act);
break;
case IA_NONE:
break;
case IA_UNWIELD:
cmdq_add_ec(CQ_CANNED, (otmp == uwep) ? dowield
: (otmp == uswapwep) ? remarm_swapwep
: (otmp == uquiver) ? dowieldquiver
: donull); /* can't happen */
cmdq_add_key(CQ_CANNED, HANDS_SYM);
break;
case IA_APPLY_OBJ:
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_DIP_OBJ:
/* #altdip instead of normal #dip - takes potion to dip into
first (the inventory item instigating this) and item to
be dipped second, also ignores floor features such as
fountain/sink so we don't need to force m-prefix here */
cmdq_add_ec(CQ_CANNED, dip_into);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_NAME_OBJ:
case IA_NAME_OTYP:
cmdq_add_ec(CQ_CANNED, docallcmd);
cmdq_add_key(CQ_CANNED, (act == IA_NAME_OBJ) ? 'i' : 'o');
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_DROP_OBJ:
cmdq_add_ec(CQ_CANNED, dodrop);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_EAT_OBJ:
/* start with m-prefix; for #eat, it means ignore floor food
if present and eat food from invent */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, doeat);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ENGRAVE_OBJ:
cmdq_add_ec(CQ_CANNED, doengrave);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_FIRE_OBJ:
cmdq_add_ec(CQ_CANNED, dofire);
break;
case IA_ADJUST_OBJ:
cmdq_add_ec(CQ_CANNED, doorganize); /* #adjust */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ADJUST_STACK:
cmdq_add_ec(CQ_CANNED, adjust_split); /* #altadjust */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_SACRIFICE:
cmdq_add_ec(CQ_CANNED, dosacrifice);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_BUY_OBJ:
cmdq_add_ec(CQ_CANNED, dopay);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_QUAFF_OBJ:
/* start with m-prefix; for #quaff, it means ignore fountain
or sink if present and drink a potion from invent */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, dodrink);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_QUIVER_OBJ:
cmdq_add_ec(CQ_CANNED, dowieldquiver);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_READ_OBJ:
cmdq_add_ec(CQ_CANNED, doread);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_RUB_OBJ:
cmdq_add_ec(CQ_CANNED, dorub);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_THROW_OBJ:
cmdq_add_ec(CQ_CANNED, dothrow);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_TAKEOFF_OBJ:
cmdq_add_ec(CQ_CANNED, ia_dotakeoff); /* #altdotakeoff */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_TIP_CONTAINER:
/* start with m-prefix to skip floor containers;
for menustyle:Traditional when more than one floor container
is present, player will get a #tip menu and have to pick
the "tip something being carried" choice, then this item
will be already chosen from inventory; suboptimal but
possibly an acceptable tradeoff since combining item actions
with use of traditional ggetobj() is an unlikely scenario */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, dotip);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_INVOKE_OBJ:
cmdq_add_ec(CQ_CANNED, doinvoke);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WIELD_OBJ:
cmdq_add_ec(CQ_CANNED, dowield);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WEAR_OBJ:
cmdq_add_ec(CQ_CANNED, dowear);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_SWAPWEAPON:
cmdq_add_ec(CQ_CANNED, doswapweapon);
break;
case IA_TWOWEAPON:
cmdq_add_ec(CQ_CANNED, dotwoweapon);
break;
case IA_ZAP_OBJ:
cmdq_add_ec(CQ_CANNED, dozap);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WHATIS_OBJ:
cmdq_add_ec(CQ_CANNED, dowhatis); /* "/" command */
cmdq_add_key(CQ_CANNED, 'i'); /* "i" == item from inventory */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
}
}
/* Show menu of possible actions hero could do with item otmp */