From: PatR Date: Tue, 19 Apr 2022 11:33:01 +0000 (-0700) Subject: item-action name/call X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9f0e511b00856e56c858707827df76b61a669453;p=nethack item-action name/call Add opportunity to name an individual object or call the type of an object to the context-sensitive inventory item-actions. --- diff --git a/include/extern.h b/include/extern.h index e6786e8ea..d6a4ca252 100644 --- a/include/extern.h +++ b/include/extern.h @@ -484,6 +484,8 @@ extern const char *safe_oname(struct obj *); extern struct monst *christen_monst(struct monst *, const char *); extern struct obj *oname(struct obj *, const char *, unsigned); extern boolean objtyp_is_callable(int); +extern int name_ok(struct obj *); +extern int call_ok(struct obj *); extern int docallcmd(void); extern void docall(struct obj *); extern const char *rndghostname(void); diff --git a/src/do_name.c b/src/do_name.c index ed88d2dab..66f124ae3 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -21,8 +21,6 @@ static void truncate_to_map(int *, int *, schar, schar); static void do_mgivenname(void); static boolean alreadynamed(struct monst *, char *, char *); static void do_oname(struct obj *); -static int name_ok(struct obj *); -static int call_ok(struct obj *); static char *docall_xname(struct obj *); static void namefloorobj(void); @@ -1231,7 +1229,7 @@ do_mgivenname(void) * allocates a replacement object, so that old risk is gone. */ static void -do_oname(register struct obj *obj) +do_oname(struct obj *obj) { char *bufp, buf[BUFSZ], bufcpy[BUFSZ], qbuf[QBUFSZ]; const char *aname; @@ -1387,17 +1385,20 @@ objtyp_is_callable(int i) } /* getobj callback for object to name (specific item) - anything but gold */ -static int +int name_ok(struct obj *obj) { if (!obj || obj->oclass == COIN_CLASS) return GETOBJ_EXCLUDE; + if (!obj->dknown || obj->oartifact || obj->otyp == SPE_NOVEL) + return GETOBJ_DOWNPLAY; + return GETOBJ_SUGGEST; } /* getobj callback for object to call (name its type) */ -static int +int call_ok(struct obj *obj) { if (!obj || !objtyp_is_callable(obj->otyp)) @@ -1414,10 +1415,18 @@ docallcmd(void) winid win; anything any; menu_item *pick_list = 0; - char ch; + struct _cmd_queue *cmdq; + char ch = 0; /* if player wants a,b,c instead of i,o when looting, do that here too */ boolean abc = flags.lootabc; + if ((cmdq = cmdq_pop()) != 0) { + if (cmdq->typ == CMDQ_KEY) + ch = cmdq->key; + else + cmdq_clear(); + goto docallcmd; + } win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); any = cg.zeroany; @@ -1456,6 +1465,7 @@ docallcmd(void) ch = 'q'; destroy_nhwindow(win); + docallcmd: switch (ch) { default: case 'q': diff --git a/src/invent.c b/src/invent.c index e108328fb..e6c2af2cf 100644 --- a/src/invent.c +++ b/src/invent.c @@ -35,6 +35,7 @@ static boolean tool_being_used(struct obj *); static int adjust_ok(struct obj *); static int adjust_gold_ok(struct obj *); static char obj_to_let(struct obj *); +static boolean item_naming_classification(struct obj *, char *, char *); static void mime_action(const char *); /* wizards can wish for venom, which will become an invisible inventory @@ -2510,6 +2511,8 @@ enum item_action_actions { IA_NONE = 0, IA_UNWIELD, /* hack for 'w-' */ IA_APPLY_OBJ, + IA_NAME_OBJ, /* 'c' name individual item */ + IA_NAME_OTYP, /* 'C' name item's type */ IA_DIP_OBJ, IA_DROP_OBJ, IA_EAT_OBJ, @@ -2530,6 +2533,32 @@ enum item_action_actions { IA_SACRIFICE, }; +/* construct text for the menu entries for IA_NAME_OBJ and IA_NAME_OTYP */ +static boolean +item_naming_classification(struct obj *obj, char *onamebuf, char *ocallbuf) +{ + static const char Name[] = "Name", Rename[] = "Rename or unname"; + + onamebuf[0] = ocallbuf[0] = '\0'; + if (name_ok(obj) == GETOBJ_SUGGEST) { + Sprintf(onamebuf, "%s %s %s", + (!has_oname(obj) || !*ONAME(obj)) ? Name : Rename, + !is_plural(obj) ? "this" : "these", + simpleonames(obj)); + } + if (call_ok(obj) == GETOBJ_SUGGEST) { + char *callname = simpleonames(obj); + + if (!is_plural(obj)) /* when not already plural, force plural */ + callname = makeplural(callname); + Sprintf(ocallbuf, "%s the type for %s", + (!objects[obj->otyp].oc_uname + || !*objects[obj->otyp].oc_uname) ? Name : Rename, + callname); + } + return (*onamebuf || *ocallbuf) ? TRUE : FALSE; +} + static void ia_addmenu(winid win, int act, char let, const char *txt) { @@ -2547,7 +2576,7 @@ itemactions(struct obj *otmp) { int n, act = IA_NONE; winid win; - char buf[BUFSZ]; + char buf[BUFSZ], buf2[BUFSZ]; menu_item *selected; struct monst *mtmp; const char *light = otmp->lamplit ? "Extinguish" : "Light"; @@ -2648,6 +2677,14 @@ itemactions(struct obj *otmp) else if (otmp->oclass == WAND_CLASS) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Break this wand"); + /* 'c', 'C' - call an item or its type something */ + if (item_naming_classification(otmp, buf, buf2)) { + if (*buf) + ia_addmenu(win, IA_NAME_OBJ, 'c', buf); + if (*buf2) + ia_addmenu(win, IA_NAME_OTYP, 'C', buf2); + } + /* 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 */ @@ -2833,6 +2870,12 @@ itemactions(struct obj *otmp) cmdq_add_ec(doapply); cmdq_add_key(otmp->invlet); break; + case IA_NAME_OBJ: + case IA_NAME_OTYP: + cmdq_add_ec(docallcmd); + cmdq_add_key((act == IA_NAME_OBJ) ? 'i' : 'o'); + cmdq_add_key(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