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:
@@ -475,6 +475,7 @@ struct instance_globals_i {
|
||||
/* invent.c */
|
||||
char *invbuf;
|
||||
unsigned invbufsiz;
|
||||
boolean item_action_in_progress;
|
||||
int in_sync_perminvent;
|
||||
|
||||
/* mon.c */
|
||||
|
||||
@@ -746,6 +746,7 @@ extern void Ring_gone(struct obj *) NONNULLARG1;
|
||||
extern void Blindf_on(struct obj *) NONNULLARG1;
|
||||
extern void Blindf_off(struct obj *);
|
||||
extern int dotakeoff(void);
|
||||
extern int ia_dotakeoff(void);
|
||||
extern int doremring(void);
|
||||
extern int cursed(struct obj *);
|
||||
extern int armoroff(struct obj *);
|
||||
|
||||
@@ -2032,8 +2032,9 @@ struct ext_func_tab extcmdlist[] = {
|
||||
/* internal commands: only used by game core, not available for user */
|
||||
{ '\0', "clicklook", NULL, doclicklook, INTERNALCMD | MOUSECMD, NULL },
|
||||
{ '\0', "mouseaction", NULL, domouseaction, INTERNALCMD | MOUSECMD, NULL },
|
||||
{ '\0', "altdip", NULL, dip_into, INTERNALCMD, NULL },
|
||||
{ '\0', "altadjust", NULL, adjust_split, INTERNALCMD, NULL },
|
||||
{ '\0', "altdip", NULL, dip_into, INTERNALCMD, NULL },
|
||||
{ '\0', "alttakeoff", NULL, ia_dotakeoff, INTERNALCMD, NULL },
|
||||
{ '\0', "altunwield", NULL, remarm_swapwep, INTERNALCMD, NULL },
|
||||
{ '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
|
||||
};
|
||||
|
||||
@@ -413,6 +413,7 @@ static const struct instance_globals_i g_init_i = {
|
||||
/* invent.c */
|
||||
NULL, /* invbuf */
|
||||
0U, /* invbufsize */
|
||||
FALSE, /* item_action_in_progress */
|
||||
0, /* in_sync_perminvent */
|
||||
/* mon.c */
|
||||
NULL, /* itermonarr */
|
||||
|
||||
@@ -1783,7 +1783,7 @@ armor_or_accessory_off(struct obj *obj)
|
||||
Strcat(what, " and ");
|
||||
Strcat(what, suit_simple_name(uarm));
|
||||
}
|
||||
Snprintf(why, sizeof(why), " without taking off your %s first",
|
||||
Snprintf(why, sizeof why, " without taking off your %s first",
|
||||
what);
|
||||
} else {
|
||||
Strcpy(why, "; it's embedded");
|
||||
@@ -1841,7 +1841,7 @@ dotakeoff(void)
|
||||
pline("Not wearing any armor or accessories.");
|
||||
return ECMD_OK;
|
||||
}
|
||||
if (Narmorpieces != 1 || ParanoidRemove || cmdq_peek(CQ_CANNED))
|
||||
if (Narmorpieces != 1 || ParanoidRemove || gi.item_action_in_progress)
|
||||
otmp = getobj("take off", takeoff_ok, GETOBJ_NOFLAGS);
|
||||
if (!otmp)
|
||||
return ECMD_CANCEL;
|
||||
@@ -1849,6 +1849,21 @@ dotakeoff(void)
|
||||
return armor_or_accessory_off(otmp);
|
||||
}
|
||||
|
||||
/* 'i' or 'I[' followed by <invlet> and then 'T';
|
||||
plain dotakeoff() would not give any feedback when picking suit
|
||||
covered by cloak or shirt covered by suit and/or cloak due to the
|
||||
default behavior of equip_ok() (skipping inaccessible items) */
|
||||
int
|
||||
ia_dotakeoff(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
gi.item_action_in_progress = TRUE;
|
||||
res = dotakeoff();
|
||||
gi.item_action_in_progress = FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* the #remove command - take off ring or other accessory */
|
||||
int
|
||||
doremring(void)
|
||||
@@ -3256,14 +3271,14 @@ adj_abon(struct obj *otmp, schar delta)
|
||||
}
|
||||
|
||||
/* decide whether a worn item is covered up by some other worn item,
|
||||
used for dipping into liquid and applying grease;
|
||||
used for dipping into liquid and applying grease and takeoff_ok();
|
||||
some criteria are different than select_off()'s */
|
||||
boolean
|
||||
inaccessible_equipment(struct obj *obj,
|
||||
const char *verb, /* "dip" or "grease", or null to
|
||||
avoid messages */
|
||||
boolean only_if_known_cursed) /* ignore covering unless
|
||||
known to be cursed */
|
||||
inaccessible_equipment(
|
||||
struct obj *obj,
|
||||
const char *verb, /* "dip" or "grease", or null to avoid messages */
|
||||
boolean only_if_known_cursed) /* ignore covering unless it is known to
|
||||
* be cursed */
|
||||
{
|
||||
static NEARDATA const char need_to_take_off_outer_armor[] =
|
||||
"need to take off %s to %s %s.";
|
||||
@@ -3315,6 +3330,8 @@ inaccessible_equipment(struct obj *obj,
|
||||
}
|
||||
/* item is not inaccessible */
|
||||
return FALSE;
|
||||
|
||||
#undef BLOCKSACCESS
|
||||
}
|
||||
|
||||
/* not a getobj callback - unifies code among the other 4 getobj callbacks */
|
||||
@@ -3354,9 +3371,11 @@ equip_ok(struct obj *obj, boolean removing, boolean accessory)
|
||||
* can't be worn because the slot is filled with something else. */
|
||||
|
||||
/* removing inaccessible equipment */
|
||||
if (removing && inaccessible_equipment(obj, (const char *) 0,
|
||||
(obj->oclass == RING_CLASS)))
|
||||
return GETOBJ_EXCLUDE_INACCESS;
|
||||
if (removing && !gi.item_action_in_progress) {
|
||||
if (inaccessible_equipment(obj, (const char *) 0,
|
||||
(obj->oclass == RING_CLASS)))
|
||||
return GETOBJ_EXCLUDE_INACCESS;
|
||||
}
|
||||
|
||||
/* all good to go */
|
||||
return GETOBJ_SUGGEST;
|
||||
|
||||
266
src/invent.c
266
src/invent.c
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user