Add "user canceled" as extended command return value

Instead of returning ECMD_OK, the commands now return ECMD_CANCEL
when user declined to pick a direction or an object to act on.

Note that this can be ORed with ECMD_TIME, if the command still
took a turn.

For now this has no gameplay meaning.
This commit is contained in:
Pasi Kallinen
2022-01-08 20:04:54 +02:00
parent bcccfaaeac
commit 68b822e4dc
22 changed files with 78 additions and 73 deletions

View File

@@ -539,8 +539,9 @@ enum bodypart_types {
#define BRK_KNOWN_OUTCOME (BRK_KNOWN2BREAK | BRK_KNOWN2NOTBREAK)
/* extended command return values */
#define ECMD_OK 0x00 /* cmd done successfully */
#define ECMD_TIME 0x01 /* cmd took time, uses up a turn */
#define ECMD_OK 0x00 /* cmd done successfully */
#define ECMD_TIME 0x01 /* cmd took time, uses up a turn */
#define ECMD_CANCEL 0x02 /* cmd canceled by user */
/* values returned from getobj() callback functions */
enum getobj_callback_returns {

View File

@@ -21,12 +21,12 @@ static void light_cocktail(struct obj **);
static int rub_ok(struct obj *);
static void display_jump_positions(int);
static void use_tinning_kit(struct obj *);
static void use_figurine(struct obj **);
static int use_figurine(struct obj **);
static int grease_ok(struct obj *);
static void use_grease(struct obj *);
static int use_grease(struct obj *);
static void use_trap(struct obj *);
static int touchstone_ok(struct obj *);
static void use_stone(struct obj *);
static int use_stone(struct obj *);
static int set_trap(void); /* occupation callback */
static void display_polearm_positions(int);
static int use_cream_pie(struct obj *);
@@ -56,7 +56,7 @@ use_camera(struct obj *obj)
return ECMD_OK;
}
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
if (obj->spe <= 0) {
pline1(nothing_happens);
@@ -315,7 +315,7 @@ use_stethoscope(struct obj *obj)
return ECMD_OK;
}
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
res = (g.hero_seq == g.context.stethoscope_seq) ? ECMD_TIME : ECMD_OK;
g.context.stethoscope_seq = g.hero_seq;
@@ -852,7 +852,7 @@ use_mirror(struct obj *obj)
boolean vis, invis_mirror, useeit, monable;
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
invis_mirror = Invis;
useeit = !Blind && (!invis_mirror || See_invisible);
uvisage = beautiful();
@@ -1569,14 +1569,11 @@ dorub(void)
return ECMD_OK;
}
obj = getobj("rub", rub_ok, GETOBJ_NOFLAGS);
if (!obj) {
/* pline1(Never_mind); -- handled by getobj() */
return ECMD_OK;
}
if (!obj)
return ECMD_CANCEL;
if (obj->oclass == GEM_CLASS || obj->oclass == FOOD_CLASS) {
if (is_graystone(obj)) {
use_stone(obj);
return ECMD_TIME;
return use_stone(obj);
} else if (obj->otyp == LUMP_OF_ROYAL_JELLY) {
return use_royal_jelly(obj);
} else {
@@ -2280,7 +2277,7 @@ figurine_location_checks(struct obj *obj, coord *cc, boolean quietly)
return TRUE;
}
static void
static int
use_figurine(struct obj **optr)
{
register struct obj *obj = *optr;
@@ -2290,11 +2287,11 @@ use_figurine(struct obj **optr)
if (u.uswallow) {
/* can't activate a figurine while swallowed */
if (!figurine_location_checks(obj, (coord *) 0, FALSE))
return;
return ECMD_OK;
}
if (!getdir((char *) 0)) {
g.context.move = g.multi = 0;
return;
return ECMD_CANCEL;
}
x = u.ux + u.dx;
y = u.uy + u.dy;
@@ -2302,7 +2299,7 @@ use_figurine(struct obj **optr)
cc.y = y;
/* Passing FALSE arg here will result in messages displayed */
if (!figurine_location_checks(obj, &cc, FALSE))
return;
return ECMD_TIME;
You("%s and it %stransforms.",
(u.dx || u.dy) ? "set the figurine beside you"
: (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
@@ -2317,6 +2314,7 @@ use_figurine(struct obj **optr)
if (Blind)
map_invisible(cc.x, cc.y);
*optr = 0;
return ECMD_TIME;
}
/* getobj callback for object to apply grease to */
@@ -2337,7 +2335,7 @@ grease_ok(struct obj *obj)
return GETOBJ_SUGGEST;
}
static void
static int
use_grease(struct obj *obj)
{
struct obj *otmp;
@@ -2346,7 +2344,7 @@ use_grease(struct obj *obj)
pline("%s from your %s.", Tobjnam(obj, "slip"),
fingers_or_gloves(FALSE));
dropx(obj);
return;
return ECMD_TIME;
}
if (obj->spe > 0) {
@@ -2358,13 +2356,13 @@ use_grease(struct obj *obj)
pline("%s from your %s.", Tobjnam(obj, "slip"),
fingers_or_gloves(FALSE));
dropx(obj);
return;
return ECMD_TIME;
}
otmp = getobj("grease", grease_ok, GETOBJ_PROMPT);
if (!otmp)
return;
return ECMD_CANCEL;
if (inaccessible_equipment(otmp, "grease", FALSE))
return;
return ECMD_OK;
consume_obj_charge(obj, TRUE);
oldglib = (int) (Glib & TIMEOUT);
@@ -2387,6 +2385,7 @@ use_grease(struct obj *obj)
pline("%s to be empty.", Tobjnam(obj, "seem"));
}
update_inventory();
return ECMD_TIME;
}
/* getobj callback for object to rub on a known touchstone */
@@ -2412,7 +2411,7 @@ touchstone_ok(struct obj *obj)
/* touchstones - by Ken Arnold */
static void
static int
use_stone(struct obj *tstone)
{
static const char scritch[] = "\"scritch, scritch\"";
@@ -2433,11 +2432,11 @@ use_stone(struct obj *tstone)
junk as likely candidates for rubbing */
if ((obj = getobj(stonebuf, known ? touchstone_ok : any_obj_ok,
GETOBJ_PROMPT)) == 0)
return;
return ECMD_CANCEL;
if (obj == tstone && obj->quan == 1L) {
You_cant("rub %s on itself.", the(xname(obj)));
return;
return ECMD_OK;
}
if (tstone->otyp == TOUCHSTONE && tstone->cursed
@@ -2451,15 +2450,15 @@ use_stone(struct obj *tstone)
pline("A sharp crack shatters %s%s.",
(obj->quan > 1L) ? "one of " : "", the(xname(obj)));
useup(obj);
return;
return ECMD_TIME;
}
if (Blind) {
pline(scritch);
return;
return ECMD_TIME;
} else if (Hallucination) {
pline("Oh wow, man: Fractals!");
return;
return ECMD_TIME;
}
do_scratch = FALSE;
@@ -2484,7 +2483,7 @@ use_stone(struct obj *tstone)
makeknown(TOUCHSTONE);
makeknown(obj->otyp);
prinv((char *) 0, obj, 0L);
return;
return ECMD_TIME;
} else {
/* either a ring or the touchstone was not effective */
if (objects[obj->otyp].oc_material == GLASS) {
@@ -2499,13 +2498,13 @@ use_stone(struct obj *tstone)
switch (objects[obj->otyp].oc_material) {
case CLOTH:
pline("%s a little more polished now.", Tobjnam(tstone, "look"));
return;
return ECMD_TIME;
case LIQUID:
if (!obj->known) /* note: not "whetstone" */
You("must think this is a wetstone, do you?");
else
pline("%s a little wetter now.", Tobjnam(tstone, "are"));
return;
return ECMD_TIME;
case WAX:
streak_color = "waxy";
break; /* okay even if not touchstone */
@@ -2542,7 +2541,7 @@ use_stone(struct obj *tstone)
You_see("%s streaks on the %s.", streak_color, stonebuf);
else
pline(scritch);
return;
return ECMD_TIME;
}
void
@@ -2704,7 +2703,7 @@ use_whip(struct obj *obj)
res = ECMD_TIME;
}
if (!getdir((char *) 0))
return res;
return (res|ECMD_CANCEL);
if (u.uswallow) {
mtmp = u.ustuck;
@@ -3284,8 +3283,7 @@ use_royal_jelly(struct obj *obj)
if (!eobj) {
addinv(obj); /* put the unused lump back; if it came from
* a split, it should merge back */
/* pline1(Never_mind); -- getobj() took care of this */
return ECMD_OK;
return ECMD_CANCEL;
}
You("smear royal jelly all over %s.", yname(eobj));
@@ -3785,7 +3783,7 @@ doapply(void)
obj = getobj("use or apply", apply_ok, GETOBJ_NOFLAGS);
if (!obj)
return ECMD_OK;
return ECMD_CANCEL;
if (!retouch_object(&obj, FALSE))
return ECMD_TIME; /* evading your grasp costs a turn; just be
@@ -3836,7 +3834,7 @@ doapply(void)
(void) bagotricks(obj, FALSE, (int *) 0);
break;
case CAN_OF_GREASE:
use_grease(obj);
res = use_grease(obj);
break;
case LOCK_PICK:
case CREDIT_CARD:
@@ -3921,7 +3919,7 @@ doapply(void)
res = use_tin_opener(obj);
break;
case FIGURINE:
use_figurine(&obj);
res = use_figurine(&obj);
break;
case UNICORN_HORN:
use_unicorn_horn(&obj);
@@ -3949,7 +3947,7 @@ doapply(void)
case LUCKSTONE:
case LOADSTONE:
case TOUCHSTONE:
use_stone(obj);
res = use_stone(obj);
break;
default:
/* Pole-weapons can strike at a distance */

View File

@@ -1434,7 +1434,7 @@ doinvoke(void)
obj = getobj("invoke", invoke_ok, GETOBJ_PROMPT);
if (!obj)
return ECMD_OK;
return ECMD_CANCEL;
if (!retouch_object(&obj, FALSE))
return ECMD_TIME;
return arti_invoke(obj);
@@ -1532,7 +1532,7 @@ arti_invoke(struct obj *obj)
if (!otmp) {
obj->age = 0;
return ECMD_OK;
return ECMD_CANCEL;
}
b_effect = (obj->blessed && (oart->role == Role_switch
|| oart->role == NON_PM));

View File

@@ -3606,6 +3606,11 @@ rhack(char *cmd)
set_occupation(func, tlist->f_text, g.multi);
res = (*func)(); /* perform the command */
}
if ((res & ECMD_CANCEL)) {
/* command was canceled by user, maybe they declined to
pick an object to act on. */
cmdq_clear();
}
if (!(res & ECMD_TIME)) {
g.context.move = FALSE;
g.multi = 0;
@@ -4042,7 +4047,7 @@ dotherecmdmenu(void)
char ch;
if (!getdir((const char *) 0) || !isok(u.ux + u.dx, u.uy + u.dy))
return ECMD_OK;
return ECMD_CANCEL;
if (u.dx || u.dy)
ch = there_cmd_menu(TRUE, u.ux + u.dx, u.uy + u.dy);

View File

@@ -1016,7 +1016,7 @@ use_pick_axe(struct obj *obj)
*dsp = 0;
Sprintf(qbuf, "In what direction do you want to %s? [%s]", verb, dirsyms);
if (!getdir(qbuf))
return res;
return (res|ECMD_CANCEL);
return use_pick_axe2(obj);
}

View File

@@ -1667,7 +1667,7 @@ dotakeoff(void)
if (Narmorpieces != 1 || ParanoidRemove)
otmp = getobj("take off", takeoff_ok, GETOBJ_NOFLAGS);
if (!otmp)
return ECMD_OK;
return ECMD_CANCEL;
return armor_or_accessory_off(otmp);
}
@@ -1686,7 +1686,7 @@ doremring(void)
if (Naccessories != 1 || ParanoidRemove)
otmp = getobj("remove", remove_ok, GETOBJ_NOFLAGS);
if (!otmp)
return ECMD_OK;
return ECMD_CANCEL;
return armor_or_accessory_off(otmp);
}
@@ -2244,7 +2244,7 @@ dowear(void)
return ECMD_OK;
}
otmp = getobj("wear", wear_ok, GETOBJ_NOFLAGS);
return otmp ? accessory_or_armor_on(otmp) : ECMD_OK;
return otmp ? accessory_or_armor_on(otmp) : ECMD_CANCEL;
}
/* the #puton command */
@@ -2263,7 +2263,7 @@ doputon(void)
return ECMD_OK;
}
otmp = getobj("put on", puton_ok, GETOBJ_NOFLAGS);
return otmp ? accessory_or_armor_on(otmp) : ECMD_OK;
return otmp ? accessory_or_armor_on(otmp) : ECMD_CANCEL;
}
/* calculate current armor class */

View File

@@ -822,9 +822,9 @@ dokick(void)
}
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
if (!u.dx && !u.dy)
return ECMD_OK;
return ECMD_CANCEL;
x = u.ux + u.dx;
y = u.uy + u.dy;

View File

@@ -98,7 +98,7 @@ throw_obj(struct obj *obj, int shotlimit)
if (obj->o_id == g.context.objsplit.parent_oid
|| obj->o_id == g.context.objsplit.child_oid)
(void) unsplitobj(obj);
return ECMD_OK; /* no time passes */
return ECMD_CANCEL; /* no time passes */
}
/*
@@ -333,7 +333,7 @@ dothrow(void)
/* it is also possible to throw food */
/* (or jewels, or iron balls... ) */
return obj ? throw_obj(obj, shotlimit) : ECMD_OK;
return obj ? throw_obj(obj, shotlimit) : ECMD_CANCEL;
}
/* KMH -- Automatically fill quiver */
@@ -479,6 +479,8 @@ dofire(void)
/* choose something from inventory, then usually quiver it */
obj = getobj("throw", throw_ok, GETOBJ_PROMPT | GETOBJ_ALLOWCNT);
/* Q command doesn't allow gold in quiver */
if (!obj)
return ECMD_CANCEL;
if (obj && !obj->owornmask && obj->oclass != COIN_CLASS)
setuqwep(obj); /* demi-autoquiver */
}
@@ -2294,7 +2296,7 @@ throw_gold(struct obj *obj)
if (obj->o_id == g.context.objsplit.parent_oid
|| obj->o_id == g.context.objsplit.child_oid)
(void) unsplitobj(obj);
return ECMD_OK;
return ECMD_CANCEL;
}
freeinv(obj);
if (u.uswallow) {

View File

@@ -2817,7 +2817,7 @@ use_tin_opener(struct obj *obj)
otmp = getobj("open", tinopen_ok, GETOBJ_NOFLAGS);
if (!otmp)
return res;
return (res|ECMD_CANCEL);
start_tin(otmp);
return ECMD_TIME;

View File

@@ -565,7 +565,7 @@ doengrave(void)
otmp = getobj("write with", stylus_ok, GETOBJ_PROMPT);
if (!otmp) /* otmp == cg.zeroobj if fingers */
return ECMD_OK;
return ECMD_CANCEL;
if (otmp == &cg.zeroobj) {
Strcat(strcpy(fbuf, "your "), body_part(FINGERTIP));

View File

@@ -4174,7 +4174,7 @@ doorganize(void) /* inventory organizer by Del Lamb */
/* get object the user wants to organize (the 'from' slot) */
obj = getobj("adjust", adjust_filter, GETOBJ_PROMPT | GETOBJ_ALLOWCNT);
if (!obj)
return ECMD_OK;
return ECMD_CANCEL;
/* can only be gold if check_invent_gold() found a problem: multiple '$'
stacks and/or gold in some other slot, otherwise (*adjust_filter)()
won't allow gold to be picked; if player has picked any stack of gold

View File

@@ -868,7 +868,7 @@ doclose(void)
}
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
x = u.ux + u.dx;
y = u.uy + u.dy;

View File

@@ -1739,7 +1739,7 @@ doidtrap(void)
int x, y, tt, glyph;
if (!getdir("^"))
return ECMD_OK;
return ECMD_CANCEL;
x = u.ux + u.dx;
y = u.uy + u.dy;

View File

@@ -3304,7 +3304,7 @@ dotip(void)
/* either no floor container(s) or couldn't tip one or didn't tip any */
cobj = getobj("tip", tip_ok, GETOBJ_PROMPT);
if (!cobj)
return ECMD_OK;
return ECMD_CANCEL;
/* normal case */
if (Is_container(cobj) || cobj->otyp == HORN_OF_PLENTY) {

View File

@@ -1196,7 +1196,7 @@ dobreathe(void)
g.context.botl = 1;
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
mattk = attacktype_fordmg(g.youmonst.data, AT_BREA, AD_ANY);
if (!mattk)
@@ -1216,7 +1216,7 @@ dospit(void)
struct attack *mattk;
if (!getdir((char *) 0))
return ECMD_OK;
return ECMD_CANCEL;
mattk = attacktype_fordmg(g.youmonst.data, AT_SPIT, AD_ANY);
if (!mattk) {
impossible("bad spit attack?");

View File

@@ -534,7 +534,7 @@ dodrink(void)
otmp = getobj("drink", drink_ok, GETOBJ_NOFLAGS);
if (!otmp)
return ECMD_OK;
return ECMD_CANCEL;
/* quan > 1 used to be left to useup(), but we need to force
the current potion to be unworn, and don't want to do
@@ -2142,7 +2142,7 @@ dodip(void)
const char *shortestname; /* last resort obj name for prompt */
if (!(obj = getobj("dip", dip_ok, GETOBJ_PROMPT)))
return ECMD_OK;
return ECMD_CANCEL;
if (inaccessible_equipment(obj, "dip", FALSE))
return ECMD_OK;
@@ -2198,7 +2198,7 @@ dodip(void)
flags.verbose ? obuf : shortestname);
potion = getobj(qbuf, drink_ok, GETOBJ_NOFLAGS);
if (!potion)
return ECMD_OK;
return ECMD_CANCEL;
if (potion == obj && potion->quan == 1L) {
pline("That is a potion bottle, not a Klein bottle!");
return ECMD_OK;

View File

@@ -356,7 +356,7 @@ doread(void)
scroll = getobj("read", read_ok, GETOBJ_PROMPT);
if (!scroll)
return ECMD_OK;
return ECMD_CANCEL;
otyp = scroll->otyp;
/* outrumor has its own blindness check */

View File

@@ -1100,7 +1100,7 @@ dochat(void)
if (!getdir("Talk to whom? (in what direction)")) {
/* decided not to chat */
return ECMD_OK;
return ECMD_CANCEL;
}
if (u.usteed && u.dz > 0) {

View File

@@ -45,7 +45,7 @@ use_saddle(struct obj* otmp)
/* Select an animal */
if (u.uswallow || Underwater || !getdir((char *) 0)) {
pline1(Never_mind);
return ECMD_OK;
return ECMD_CANCEL;
}
if (!u.dx && !u.dy) {
pline("Saddle yourself? Very funny...");
@@ -175,7 +175,7 @@ doride(void)
return (mount_steed(m_at(u.ux + u.dx, u.uy + u.dy), forcemount)
? ECMD_TIME : ECMD_OK);
} else {
return ECMD_OK;
return ECMD_CANCEL;
}
return ECMD_TIME;
}

View File

@@ -329,8 +329,7 @@ dowield(void)
clear_splitobjs();
if (!(wep = getobj("wield", wield_ok, GETOBJ_PROMPT | GETOBJ_ALLOWCNT))) {
/* Cancelled */
cmdq_clear();
return ECMD_OK;
return ECMD_CANCEL;
} else if (wep == uwep) {
already_wielded:
You("are already wielding that!");
@@ -491,7 +490,7 @@ dowieldquiver(void)
if (!newquiver) {
/* Cancelled */
return ECMD_OK;
return ECMD_CANCEL;
} else if (newquiver == &cg.zeroobj) { /* no object */
/* Explicitly nothing */
if (uquiver) {

View File

@@ -125,7 +125,7 @@ dowrite(struct obj *pen)
/* get paper to write on */
paper = getobj("write on", write_ok, GETOBJ_NOFLAGS);
if (!paper)
return ECMD_OK;
return ECMD_CANCEL;
/* can't write on a novel (unless/until it's been converted into a blank
spellbook), but we want messages saying so to avoid "spellbook" */
typeword = (paper->otyp == SPE_NOVEL)

View File

@@ -2380,7 +2380,7 @@ dozap(void)
return ECMD_OK;
obj = getobj("zap", zap_ok, GETOBJ_NOFLAGS);
if (!obj)
return ECMD_OK;
return ECMD_CANCEL;
check_unpaid(obj);