#dip command - get item to dip, then get potion to dip it into; precede with 'm' to bypass fountain, pool, or sink at hero's spot */
| 2264 | /* #dip command - get item to dip, then get potion to dip it into; |
| 2265 | precede with 'm' to bypass fountain, pool, or sink at hero's spot */ |
| 2266 | int |
| 2267 | dodip(void) |
| 2268 | { |
| 2269 | static const char Dip_[] = "Dip "; |
| 2270 | struct obj *potion, *obj; |
| 2271 | char qbuf[QBUFSZ], obuf[QBUFSZ]; |
| 2272 | const char *shortestname; /* last resort obj name for prompt */ |
| 2273 | uchar here = levl[u.ux][u.uy].typ; |
| 2274 | boolean is_hands, at_pool = is_pool(u.ux, u.uy), |
| 2275 | at_fountain = IS_FOUNTAIN(here), at_sink = IS_SINK(here), |
| 2276 | at_here = (!iflags.menu_requested |
| 2277 | && (at_pool || at_fountain || at_sink)); |
| 2278 | |
| 2279 | obj = getobj("dip", at_here ? dip_hands_ok : dip_ok, GETOBJ_PROMPT); |
| 2280 | if (!obj) |
| 2281 | return ECMD_CANCEL; |
| 2282 | if (inaccessible_equipment(obj, "dip", FALSE)) |
| 2283 | return ECMD_OK; |
| 2284 | |
| 2285 | is_hands = (obj == &hands_obj); |
| 2286 | shortestname = (is_hands || is_plural(obj) || pair_of(obj)) ? "them" |
| 2287 | : "it"; |
| 2288 | drink_ok_extra = 0; |
| 2289 | /* |
| 2290 | * Bypass safe_qbuf() since it doesn't handle varying suffix without |
| 2291 | * an awful lot of support work. Format the object once, even though |
| 2292 | * the fountain and pool prompts offer a lot more room for it. |
| 2293 | * 3.6.0 used thesimpleoname() unconditionally, which posed no risk |
| 2294 | * of buffer overflow but drew bug reports because it omits user- |
| 2295 | * supplied type name. |
| 2296 | * getobj: "What do you want to dip <the object> into? [xyz or ?*] " |
| 2297 | */ |
| 2298 | if (is_hands) { |
| 2299 | Snprintf(obuf, sizeof obuf, "your %s", makeplural(body_part(HAND))); |
| 2300 | } else { |
| 2301 | Strcpy(obuf, short_oname(obj, doname, thesimpleoname, |
| 2302 | /* 128 - (24 + 54 + 1) leaves 49 for |
| 2303 | <object> */ |
| 2304 | QBUFSZ - sizeof "What do you want to dip\ |
| 2305 | into? [abdeghjkmnpqstvwyzBCEFHIKLNOQRTUWXZ#-# or ?*] ")); |
| 2306 | } |
| 2307 | |
| 2308 | /* preceding #dip with 'm' skips the possibility of dipping into pools, |
| 2309 | fountains, and sinks plus the extra prompting which those entail */ |
| 2310 | if (!iflags.menu_requested) { |
| 2311 | /* Is there a fountain to dip into here? */ |
| 2312 | if (!can_reach_floor(FALSE)) { |
| 2313 | ; /* can't dip something into fountain or pool if can't reach */ |
| 2314 | } else if (at_fountain) { |
| 2315 | Snprintf(qbuf, sizeof(qbuf), "%s%s into the fountain?", Dip_, |
| 2316 | flags.verbose ? obuf : shortestname); |
| 2317 | /* "Dip <the object> into the fountain?" */ |
| 2318 | if (y_n(qbuf) == 'y') { |
| 2319 | if (!is_hands) |
| 2320 | obj->pickup_prev = 0; |
| 2321 | dipfountain(obj); |
| 2322 | return ECMD_TIME; |
| 2323 | } |
nothing calls this directly
no test coverage detected