diff --git a/include/hack.h b/include/hack.h index d9b59d402..a7ea384ed 100644 --- a/include/hack.h +++ b/include/hack.h @@ -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 { diff --git a/src/apply.c b/src/apply.c index ec9cae2d1..338ea48dd 100644 --- a/src/apply.c +++ b/src/apply.c @@ -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 */ diff --git a/src/artifact.c b/src/artifact.c index 2f04f284e..336d5474a 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -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)); diff --git a/src/cmd.c b/src/cmd.c index 4b58c5401..3d57f9688 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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); diff --git a/src/dig.c b/src/dig.c index d90aaf8ee..2c41ff3c6 100644 --- a/src/dig.c +++ b/src/dig.c @@ -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); } diff --git a/src/do_wear.c b/src/do_wear.c index b65a27105..f0e31d0f3 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -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 */ diff --git a/src/dokick.c b/src/dokick.c index a81d2441b..e7ba06dbf 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -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; diff --git a/src/dothrow.c b/src/dothrow.c index 01bde0e27..93f2d5e43 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -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) { diff --git a/src/eat.c b/src/eat.c index b560b0621..621c02a51 100644 --- a/src/eat.c +++ b/src/eat.c @@ -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; diff --git a/src/engrave.c b/src/engrave.c index a83275323..44ca6b0d3 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -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)); diff --git a/src/invent.c b/src/invent.c index e8c41ba41..d8aeffcb6 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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 diff --git a/src/lock.c b/src/lock.c index c311cf03e..4c63a338a 100644 --- a/src/lock.c +++ b/src/lock.c @@ -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; diff --git a/src/pager.c b/src/pager.c index e8b25a306..d45bca767 100644 --- a/src/pager.c +++ b/src/pager.c @@ -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; diff --git a/src/pickup.c b/src/pickup.c index 8539b2e8d..94136b53d 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -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) { diff --git a/src/polyself.c b/src/polyself.c index 90fb451b0..613106ce3 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -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?"); diff --git a/src/potion.c b/src/potion.c index 87c62d7d7..5b8598c7f 100644 --- a/src/potion.c +++ b/src/potion.c @@ -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; diff --git a/src/read.c b/src/read.c index e92baeb7f..566b7e889 100644 --- a/src/read.c +++ b/src/read.c @@ -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 */ diff --git a/src/sounds.c b/src/sounds.c index f69224bea..a1b0b21a8 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -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) { diff --git a/src/steed.c b/src/steed.c index 7e1c0e5a9..94d35bc84 100644 --- a/src/steed.c +++ b/src/steed.c @@ -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; } diff --git a/src/wield.c b/src/wield.c index 0b4644f27..391a17fe3 100644 --- a/src/wield.c +++ b/src/wield.c @@ -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) { diff --git a/src/write.c b/src/write.c index a4e72a13e..7cfd5f0f1 100644 --- a/src/write.c +++ b/src/write.c @@ -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) diff --git a/src/zap.c b/src/zap.c index 6396c8fef..ae0080418 100644 --- a/src/zap.c +++ b/src/zap.c @@ -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);