1 /* NetHack 3.6 potion.c $NHDT-Date: 1520797133 2018/03/11 19:38:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.144 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2013. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 boolean notonhead = FALSE;
15 static NEARDATA int nothing, unkn;
16 static NEARDATA const char beverages[] = { POTION_CLASS, 0 };
18 STATIC_DCL long FDECL(itimeout, (long));
19 STATIC_DCL long FDECL(itimeout_incr, (long, int));
20 STATIC_DCL void NDECL(ghost_from_bottle);
22 FDECL(H2Opotion_dip, (struct obj *, struct obj *, BOOLEAN_P, const char *));
23 STATIC_DCL short FDECL(mixtype, (struct obj *, struct obj *));
25 /* force `val' to be within valid range for intrinsic timeout value */
38 /* increment `old' by `incr' and force result to be valid intrinsic timeout */
40 itimeout_incr(old, incr)
44 return itimeout((old & TIMEOUT) + (long) incr);
47 /* set the timeout field of intrinsic `which' */
49 set_itimeout(which, val)
53 *which |= itimeout(val);
56 /* increment the timeout field of intrinsic `which' */
58 incr_itimeout(which, incr)
62 set_itimeout(which, itimeout_incr(*which, incr));
66 make_confused(xtime, talk)
70 long old = HConfusion;
78 You_feel("less %s now.", Hallucination ? "trippy" : "confused");
80 You("%s
\82ª
\82¨
\82³
\82Ü
\82Á
\82½
\81D", Hallucination ? "
\83w
\83\8d\83w
\83\8d" : "
\8d¬
\97\90");
82 if ((xtime && !old) || (!xtime && old))
85 set_itimeout(&HConfusion, xtime);
89 make_stunned(xtime, talk)
102 Hallucination ? "less wobbly" : "a bit steadier");
105 Hallucination ? "
\82Ö
\82ë
\82è
\82ç
\82ª
\82¨
\82³
\82Ü
\82Á
\82½" : "
\82¾
\82ñ
\82¾
\82ñ
\82µ
\82Á
\82©
\82è
\82µ
\82Ä
\82«
\82½");
112 You("wobble in the saddle.");
114 You("
\88Æ
\82Ì
\8fã
\82Å
\82®
\82ç
\82®
\82ç
\82µ
\82½
\81D");
117 You("%s...", stagger(youmonst.data, "stagger"));
119 You("
\82
\82ç
\82
\82ç
\82µ
\82½
\81D
\81D
\81D");
122 if ((!xtime && old) || (xtime && !old))
125 set_itimeout(&HStun, xtime);
129 make_sick(xtime, cause, talk, type)
131 const char *cause; /* sickness cause */
147 You_feel("deathly sick.");
149 You("
\95a
\8bC
\82Å
\8e\80\82É
\82»
\82¤
\82¾
\81D");
154 You_feel("%s worse.", xtime <= Sick / 2L ? "much" : "even");
156 You("%s
\88«
\89»
\82µ
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82·
\82é
\81D", xtime <= Sick/2L ? "
\82³
\82ç
\82É" : "
\82à
\82Á
\82Æ");
158 set_itimeout(&Sick, xtime);
159 u.usick_type |= type;
161 } else if (old && (type & u.usick_type)) {
162 /* was sick, now not */
163 u.usick_type &= ~type;
164 if (u.usick_type) { /* only partly cured */
167 You_feel("somewhat better.");
169 You("
\82¿
\82å
\82Á
\82Æ
\82æ
\82
\82È
\82Á
\82½
\81D");
170 set_itimeout(&Sick, Sick * 2); /* approximation */
174 You_feel("cured. What a relief!");
176 pline("
\89ñ
\95\9c\82µ
\82½
\81D
\82 \82 \8f\95\82©
\82Á
\82½
\81I");
177 Sick = 0L; /* set_itimeout(&Sick, 0L) */
183 exercise(A_CON, FALSE);
184 delayed_killer(SICK, KILLED_BY_AN, cause);
186 dealloc_killer(find_delayed_killer(SICK));
190 make_slimed(xtime, msg)
200 set_itimeout(&Slimed, xtime);
201 if ((xtime != 0L) ^ (old != 0L)) {
207 dealloc_killer(find_delayed_killer(SLIMED));
210 /* start or stop petrification */
212 make_stoned(xtime, msg, killedby, killername)
216 const char *killername;
224 set_itimeout(&Stoned, xtime);
225 if ((xtime != 0L) ^ (old != 0L)) {
231 dealloc_killer(find_delayed_killer(STONED));
233 delayed_killer(STONED, killedby, killername);
237 make_vomiting(xtime, talk)
246 set_itimeout(&Vomiting, xtime);
251 You_feel("much less nauseated now.");
253 You("
\93f
\82«
\8bC
\82ª
\82¨
\82³
\82Ü
\82Á
\82½
\81D");
257 static const char vismsg[] = "vision seems to %s for a moment but is %s now.";
259 static const char vismsg[] = "
\8e\8b\8aE
\82Í
\88ê
\8fu%s
\82È
\82Á
\82½
\82ª
\82Ü
\82½%s
\82È
\82Á
\82½
\81D";
261 static const char eyemsg[] = "%s momentarily %s.";
263 static const char eyemsg[] = "%s
\82Í
\88ê
\8fu%s
\81D";
266 make_blinded(xtime, talk)
271 boolean u_could_see, can_see_now;
276 /* we need to probe ahead in case the Eyes of the Overworld
277 are or will be overriding blindness */
278 u_could_see = !Blind;
279 Blinded = xtime ? 1L : 0L;
280 can_see_now = !Blind;
281 Blinded = old; /* restore */
286 if (can_see_now && !u_could_see) { /* regaining sight */
290 pline("Far out! Everything is all cosmic again!");
292 pline("
\82°
\81I
\82È
\82É
\82à
\82©
\82à
\82ª
\82Ü
\82½
\93ø
\90F
\82É
\8c©
\82¦
\82é
\81I");
295 You("can see again.");
297 You("
\82Ü
\82½
\8c©
\82¦
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
299 } else if (old && !xtime) {
300 /* clearing temporary blindness without toggling blindness */
302 if (!haseyes(youmonst.data)) {
303 strange_feeling((struct obj *) 0, (char *) 0);
304 } else if (Blindfolded) {
306 eyes = body_part(EYE);
307 if (eyecount(youmonst.data) != 1)
308 eyes = makeplural(eyes);
309 Your(eyemsg, eyes, vtense(eyes, "itch"));
311 Your(eyemsg, body_part(EYE), "
\82©
\82ä
\82
\82È
\82Á
\82½");
313 } else { /* Eyes of the Overworld */
315 Your(vismsg, "brighten", Hallucination ? "sadder" : "normal");
317 Your(vismsg, "
\96¾
\82é
\82", Hallucination ? "
\8dª
\88Ã
\82É" : "
\95\81\92Ê
\82É");
322 if (u_could_see && !can_see_now) { /* losing sight */
326 pline("Oh, bummer! Everything is dark! Help!");
328 pline("
\88Ã
\82¢
\82æ
\81[
\81C
\8b·
\82¢
\82æ
\81[
\81C
\8b°
\82¢
\82æ
\81[
\81I");
331 pline("A cloud of darkness falls upon you.");
333 pline("
\88Ã
\8d\95\82Ì
\89_
\82ª
\82 \82È
\82½
\82ð
\95¢
\82Á
\82½
\81D");
335 /* Before the hero goes blind, set the ball&chain variables. */
338 } else if (!old && xtime) {
339 /* setting temporary blindness without toggling blindness */
341 if (!haseyes(youmonst.data)) {
342 strange_feeling((struct obj *) 0, (char *) 0);
343 } else if (Blindfolded) {
345 eyes = body_part(EYE);
346 if (eyecount(youmonst.data) != 1)
347 eyes = makeplural(eyes);
348 Your(eyemsg, eyes, vtense(eyes, "twitch"));
350 Your(eyemsg, body_part(EYE), "
\83s
\83N
\83s
\83N
\82µ
\82½");
352 } else { /* Eyes of the Overworld */
354 Your(vismsg, "dim", Hallucination ? "happier" : "normal");
356 Your(vismsg, "
\94\96\88Ã
\82", Hallucination ? "
\83n
\83b
\83s
\81[
\82É" : "
\95\81\92Ê
\82É");
361 set_itimeout(&Blinded, xtime);
363 if (u_could_see ^ can_see_now) { /* one or the other but not both */
365 vision_full_recalc = 1; /* blindness just got toggled */
366 /* this vision recalculation used to be deferred until
367 moveloop(), but that made it possible for vision
368 irregularities to occur (cited case was force bolt
369 hitting adjacent potion of blindness and then a
370 secret door; hero was blinded by vapors but then
371 got the message "a door appears in the wall") */
373 if (Blind_telepat || Infravision)
376 /* avoid either of the sequences
377 "Sting starts glowing", [become blind], "Sting stops quivering" or
378 "Sting starts quivering", [regain sight], "Sting stops glowing"
379 by giving "Sting is quivering" when becoming blind or
380 "Sting is glowing" when regaining sight so that the eventual
381 "stops" message matches */
382 if (warn_obj_cnt && uwep && (EWarn_of_mon & W_WEP) != 0L)
384 /* update dknown flag for inventory picked up while blind */
386 learn_unseen_invent();
391 make_hallucinated(xtime, talk, mask)
392 long xtime; /* nonzero if this is an attempt to turn on hallucination */
394 long mask; /* nonzero if resistance status should change by mask */
396 long old = HHallucination;
398 const char *message, *verb;
404 message = (!xtime) ? "Everything %s SO boring now."
405 : "Oh wow! Everything %s so cosmic!";
407 message = (!xtime) ? "
\89½
\82à
\82©
\82à
\82ª
\81\96\91Þ
\8bü
\81\96\82É%s
\82é
\81D"
408 : "
\83\8f\81[
\83I
\81I
\89½
\82à
\82©
\82à
\93ø
\90F
\82É%s
\82é
\81I";
411 verb = (!Blind) ? "looks" : "feels";
413 verb = (!Blind) ? "
\8c©
\82¦" : "
\8a´
\82¶";
420 EHalluc_resistance |= mask;
422 EHalluc_resistance &= ~mask;
424 if (!EHalluc_resistance && (!!HHallucination != !!xtime))
426 set_itimeout(&HHallucination, xtime);
428 /* clearing temporary hallucination without toggling vision */
429 if (!changed && !HHallucination && old && talk) {
430 if (!haseyes(youmonst.data)) {
431 strange_feeling((struct obj *) 0, (char *) 0);
434 const char *eyes = body_part(EYE);
436 if (eyecount(youmonst.data) != 1)
437 eyes = makeplural(eyes);
438 Your(eyemsg, eyes, vtense(eyes, "itch"));
440 Your(eyemsg, body_part(EYE), "
\82©
\82ä
\82
\82È
\82Á
\82½");
442 } else { /* Grayswandir */
444 Your(vismsg, "flatten", "normal");
446 Your(vismsg, "
\82¨
\82©
\82µ
\82", "
\95\81\92Ê
\82É");
452 /* in case we're mimicking an orange (hallucinatory form
453 of mimicking gold) update the mimicking's-over message */
458 swallowed(0); /* redraw swallow display */
460 /* The see_* routines should be called *before* the pline. */
466 /* for perm_inv and anything similar
467 (eg. Qt windowport's equipped items display) */
472 pline(message, verb);
478 make_deaf(xtime, talk)
487 set_itimeout(&HDeaf, xtime);
488 if ((xtime != 0L) ^ (old != 0L)) {
492 You(old ? "can hear again." : "are unable to hear anything.");
494 You(old ? "
\82Ü
\82½
\95·
\82±
\82¦
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D" : "
\89½
\82à
\95·
\82±
\82¦
\82È
\82
\82È
\82Á
\82½
\81D");
503 Hallucination ? "Far out, man! You"
504 : "Gee! All of a sudden, you",
505 See_invisible ? "can see right through yourself"
506 : "can't see yourself");
508 pline("%s
\82 \82È
\82½
\82Í%s
\81D",
509 Hallucination ? "
\83\8f\81[
\83I
\81I" : "
\82°
\81I
\93Ë
\91R",
510 See_invisible ? "
\8e©
\95ª
\8e©
\90g
\82ª
\82¿
\82á
\82ñ
\82Æ
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½"
511 : "
\8e©
\95ª
\8e©
\90g
\82ª
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½");
518 struct monst *mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS);
522 pline("This bottle turns out to be empty.");
524 pline("
\95r
\82Í
\8bó
\82Á
\82Û
\82¾
\82Á
\82½
\81D");
529 pline("As you open the bottle, %s emerges.", something);
531 pline("
\95r
\82ð
\8aJ
\82¯
\82é
\82Æ
\81C
\89½
\82©
\82ª
\8fo
\82Ä
\82«
\82½
\81D");
535 pline("As you open the bottle, an enormous %s emerges!",
536 Hallucination ? rndmonnam(NULL) : (const char *) "ghost");
538 pline("
\95r
\82ð
\8aJ
\82¯
\82é
\82Æ
\81C
\8b\90\91å
\82È%s
\82ª
\8fo
\82Ä
\82«
\82½
\81I",
539 Hallucination ? rndmonnam(NULL) : (const char *) "
\97H
\97ì");
543 You("are frightened to death, and unable to move.");
545 You("
\82Ü
\82Á
\82³
\82¨
\82É
\82È
\82Á
\82Ä
\8bÁ
\82«
\81C
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
548 multi_reason = "being frightened to death";
550 multi_reason = "
\8e\80\82Ê
\82Ù
\82Ç
\8bÁ
\82¢
\82½
\8c\84\82É";
552 nomovemsg = "You regain your composure.";
554 nomovemsg = "
\82 \82È
\82½
\82Í
\95½
\90Ã
\82ð
\8eæ
\82è
\96ß
\82µ
\82½
\81D";
557 /* "Quaffing is like drinking, except you spill more." - Terry Pratchett */
561 register struct obj *otmp;
562 const char *potion_descr;
566 pline("If you can't breathe air, how can you drink liquid?");
568 pline("
\91§
\82à
\82Å
\82«
\82È
\82¢
\82Ì
\82É
\81C
\82Ç
\82¤
\82â
\82Á
\82Ä
\89t
\91Ì
\82ð
\88ù
\82Þ
\82ñ
\82¾
\82¢
\81H");
571 /* Is there a fountain to drink from here? */
572 if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
573 /* not as low as floor level but similar restrictions apply */
574 && can_reach_floor(FALSE)) {
576 if (yn("Drink from the fountain?") == 'y') {
578 if (yn("
\90ò
\82Ì
\90\85\82ð
\88ù
\82Ý
\82Ü
\82·
\82©
\81H") == 'y') {
583 /* Or a kitchen sink? */
584 if (IS_SINK(levl[u.ux][u.uy].typ)
585 /* not as low as floor level but similar restrictions apply */
586 && can_reach_floor(FALSE)) {
588 if (yn("Drink from the sink?") == 'y') {
590 if (yn("
\97¬
\82µ
\91ä
\82Ì
\90\85\82ð
\88ù
\82Ý
\82Ü
\82·
\82©
\81H") == 'y') {
595 /* Or are you surrounded by water? */
596 if (Underwater && !u.uswallow) {
598 if (yn("Drink the water around you?") == 'y') {
600 if (yn("
\82Ü
\82í
\82è
\82Ì
\90\85\82ð
\88ù
\82Ý
\82Ü
\82·
\82©
\81H") == 'y') {
602 pline("Do you know what lives in this water?");
604 pline("
\82±
\82Ì
\90\85\92\86\82Å
\89½
\82ª
\90¶
\82«
\82Ä
\82¢
\82é
\82Ì
\82©
\92m
\82Á
\82Ä
\82é
\82©
\82¢
\81H");
609 otmp = getobj(beverages, "drink");
613 /* quan > 1 used to be left to useup(), but we need to force
614 the current potion to be unworn, and don't want to do
615 that for the entire stack when starting with more than 1.
616 [Drinking a wielded potion of polymorph can trigger a shape
617 change which causes hero's weapon to be dropped. In 3.4.x,
618 that led to an "object lost" panic since subsequent useup()
619 was no longer dealing with an inventory item. Unwearing
620 the current potion is intended to keep it in inventory.] */
621 if (otmp->quan > 1L) {
622 otmp = splitobj(otmp, 1L);
623 otmp->owornmask = 0L; /* rest of original stuck unaffected */
624 } else if (otmp->owornmask) {
625 remove_worn_item(otmp, FALSE);
627 otmp->in_use = TRUE; /* you've opened the stopper */
629 potion_descr = OBJ_DESCR(objects[otmp->otyp]);
632 if (!strcmp(potion_descr, "milky")
634 if (!strcmp(potion_descr, "
\83~
\83\8b\83N
\90F
\82Ì")
635 && !(mvitals[PM_GHOST].mvflags & G_GONE)
636 && !rn2(POTION_OCCUPANT_CHANCE(mvitals[PM_GHOST].born))) {
641 } else if (!strcmp(potion_descr, "smoky")
643 } else if (!strcmp(potion_descr, "
\89\8c\82ª
\82Å
\82Ä
\82¢
\82é")
644 && !(mvitals[PM_DJINNI].mvflags & G_GONE)
645 && !rn2(POTION_OCCUPANT_CHANCE(mvitals[PM_DJINNI].born))) {
646 djinni_from_bottle(otmp);
651 return dopotion(otmp);
656 register struct obj *otmp;
662 if ((retval = peffects(otmp)) >= 0)
668 You("have a %s feeling for a moment, then it passes.",
669 Hallucination ? "normal" : "peculiar");
671 You("%s
\8bC
\95ª
\82É
\82¨
\82»
\82í
\82ê
\82½
\82ª
\81C
\82·
\82®
\82É
\8fÁ
\82¦
\82³
\82Á
\82½
\81D",
672 Hallucination ? "
\95\81\92Ê
\82Ì" : "
\93Æ
\93Á
\82È");
675 if (otmp->dknown && !objects[otmp->otyp].oc_name_known) {
677 makeknown(otmp->otyp);
678 more_experienced(0, 10);
679 } else if (!objects[otmp->otyp].oc_uname)
688 register struct obj *otmp;
690 register int i, ii, lim;
692 switch (otmp->otyp) {
693 case POT_RESTORE_ABILITY:
694 case SPE_RESTORE_ABILITY:
698 pline("Ulch! This makes you feel mediocre!");
700 pline("
\82¤
\81[
\82ñ
\81C
\82Ç
\82¤
\82à
\82³
\82¦
\82È
\82¢
\82È
\82 \81D");
703 /* unlike unicorn horn, overrides Fixed_abil */
705 pline("Wow! This makes you feel %s!",
707 ? (unfixable_trouble_count(FALSE) ? "better" : "great")
710 pline("
\83\8f\81[
\83I
\81I
\8bC
\95ª
\82ª%s
\82È
\82Á
\82½
\81I",
712 ? (unfixable_trouble_count(FALSE) ? "
\82¾
\82¢
\82Ô
\82æ
\82" : "
\82Æ
\82Ä
\82à
\82æ
\82")
715 i = rn2(A_MAX); /* start at a random point */
716 for (ii = 0; ii < A_MAX; ii++) {
718 /* this used to adjust 'lim' for A_STR when u.uhs was
719 WEAK or worse, but that's handled via ATEMP(A_STR) now */
720 if (ABASE(i) < lim) {
723 /* only first found if not blessed */
731 /* when using the potion (not the spell) also restore lost levels,
732 to make the potion more worth keeping around for players with
733 the spell or with a unihorn; this is better than full healing
734 in that it can restore all of them, not just half, and a
735 blessed potion restores them all at once */
736 if (otmp->otyp == POT_RESTORE_ABILITY &&
737 u.ulevel < u.ulevelmax) {
740 } while (u.ulevel < u.ulevelmax && otmp->blessed);
744 case POT_HALLUCINATION:
745 if (Hallucination || Halluc_resistance)
747 (void) make_hallucinated(
748 itimeout_incr(HHallucination, rn1(200, 600 - 300 * bcsign(otmp))),
752 if (!otmp->blessed && !otmp->cursed) {
754 pline("This tastes like %s.", hliquid("water"));
756 pline("%s
\82Ì
\82æ
\82¤
\82È
\96¡
\82ª
\82·
\82é
\81D", hliquid("
\90\85"));
757 u.uhunger += rnd(10);
762 if (is_undead(youmonst.data) || is_demon(youmonst.data)
763 || u.ualign.type == A_CHAOTIC) {
766 pline("This burns like %s!", hliquid("acid"));
768 pline("%s
\82Ì
\82æ
\82¤
\82É
\90ã
\82ª
\82Ð
\82è
\82Ð
\82è
\82·
\82é
\81I", hliquid("
\8e_"));
769 exercise(A_CON, FALSE);
770 if (u.ulycn >= LOW_PM) {
772 Your("affinity to %s disappears!",
774 Your("%s
\82Ö
\82Ì
\90e
\8bß
\8a´
\82Í
\82È
\82
\82È
\82Á
\82½
\81I",
775 makeplural(mons[u.ulycn].mname));
776 if (youmonst.data == &mons[u.ulycn])
778 set_ulycn(NON_PM); /* cure lycanthropy */
781 losehp(Maybe_Half_Phys(d(2, 6)), "potion of holy water",
783 losehp(Maybe_Half_Phys(d(2, 6)), "
\90¹
\90\85\82Å",
785 } else if (otmp->cursed) {
787 You_feel("quite proud of yourself.");
789 You("
\8e©
\91¸
\90S
\82ð
\8a´
\82¶
\82½
\81D");
790 healup(d(2, 6), 0, 0, 0);
791 if (u.ulycn >= LOW_PM && !Upolyd)
793 exercise(A_CON, TRUE);
798 You_feel("full of awe.");
800 You("
\88Ø
\95|
\82Ì
\94O
\82É
\82©
\82ç
\82ê
\82½
\81D");
801 make_sick(0L, (char *) 0, TRUE, SICK_ALL);
802 exercise(A_WIS, TRUE);
803 exercise(A_CON, TRUE);
804 if (u.ulycn >= LOW_PM)
805 you_unwere(TRUE); /* "Purified" */
806 /* make_confused(0L, TRUE); */
808 if (u.ualign.type == A_LAWFUL) {
810 pline("This burns like %s!", hliquid("acid"));
812 pline("%s
\82Ì
\82æ
\82¤
\82É
\90ã
\82ª
\82Ð
\82è
\82Ð
\82è
\82·
\82é
\81I", hliquid("
\8e_"));
814 losehp(Maybe_Half_Phys(d(2, 6)), "potion of unholy water",
816 losehp(Maybe_Half_Phys(d(2, 6)), "
\95s
\8fò
\82È
\90\85\82Å",
820 You_feel("full of dread.");
822 You("
\8b°
\95|
\82Ì
\94O
\82É
\82©
\82ç
\82ê
\82½
\81D");
823 if (u.ulycn >= LOW_PM && !Upolyd)
825 exercise(A_CON, FALSE);
832 pline("Ooph! This tastes like %s%s!",
833 otmp->odiluted ? "watered down " : "",
834 Hallucination ? "dandelion wine" : "liquid fire");
836 pline("
\82¤
\82¥
\82Á
\82Õ
\81I
\82±
\82ê
\82Í%s%s
\82Ì
\82æ
\82¤
\82È
\96¡
\82ª
\82·
\82é
\81I",
837 otmp->odiluted ? "
\90\85\82Å
\94\96\82ß
\82½" : "",
838 Hallucination ? "
\83^
\83\93\83|
\83|
\83\8f\83C
\83\93" : "
\94R
\97¿
\83I
\83C
\83\8b");
841 make_confused(itimeout_incr(HConfusion, d(3, 8)), FALSE);
842 /* the whiskey makes us feel better */
844 healup(1, 0, FALSE, FALSE);
845 u.uhunger += 10 * (2 + bcsign(otmp));
847 exercise(A_WIS, FALSE);
852 You("
\8bC
\90â
\82µ
\82½
\81D");
855 nomovemsg = "You awake with a headache.";
857 nomovemsg = "
\96Ú
\82ª
\82³
\82ß
\82½
\82ª
\93ª
\92É
\82ª
\82·
\82é
\81D";
860 case POT_ENLIGHTENMENT:
864 You("have an uneasy feeling...");
866 You("
\95s
\88À
\82È
\8bC
\8e\9d\82É
\82È
\82Á
\82½
\81D
\81D
\81D");
867 exercise(A_WIS, FALSE);
870 (void) adjattrib(A_INT, 1, FALSE);
871 (void) adjattrib(A_WIS, 1, FALSE);
874 You_feel("self-knowledgeable...");
876 You("
\8e©
\95ª
\8e©
\90g
\82ª
\94»
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D
\81D
\81D");
877 display_nhwindow(WIN_MESSAGE, FALSE);
878 enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS);
880 pline_The("feeling subsides.");
882 pline("
\82»
\82Ì
\8a´
\82¶
\82Í
\82È
\82
\82È
\82Á
\82½
\81D");
883 exercise(A_WIS, TRUE);
886 case SPE_INVISIBILITY:
887 /* spell cannot penetrate mummy wrapping */
888 if (BInvis && uarmc->otyp == MUMMY_WRAPPING) {
890 You_feel("rather itchy under %s.", yname(uarmc));
892 You("%s
\82Ì
\89º
\82ª
\83\80\83Y
\83\80\83Y
\82µ
\82½
\81D", xname(uarmc));
896 case POT_INVISIBILITY:
897 if (Invis || Blind || BInvis) {
900 self_invis_message();
903 HInvis |= FROMOUTSIDE;
905 incr_itimeout(&HInvis, rn1(15, 31));
906 newsym(u.ux, u.uy); /* update position */
909 pline("For some reason, you feel your presence is known.");
911 pline("
\82È
\82º
\82©
\81C
\91¶
\8dÝ
\82ª
\92m
\82ç
\82ê
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
915 case POT_SEE_INVISIBLE: /* tastes like fruit juice in Rogue */
916 case POT_FRUIT_JUICE: {
917 int msg = Invisible && !Blind;
922 pline("Yecch! This tastes %s.",
923 Hallucination ? "overripe" : "rotten");
925 pline("
\83I
\83F
\81[
\81I
\82±
\82ê
\82Í%s
\83W
\83\85\81[
\83X
\82Ì
\96¡
\82ª
\82·
\82é
\81D",
926 Hallucination ? "
\8fn
\82µ
\82·
\82¬
\82½" : "
\95\85\82Á
\82½");
932 ? "This tastes like 10%% real %s%s all-natural beverage."
933 : "This tastes like %s%s.",
934 otmp->odiluted ? "reconstituted " : "", fruitname(TRUE));
938 ? "10%%%s
\82Ì
\8f\83\8e©
\91R
\88ù
\97¿
\82Ì
\82æ
\82¤
\82È
\96¡
\82ª
\82·
\82é
\81D"
939 : "%s%s
\83W
\83\85\81[
\83X
\82Ì
\82æ
\82¤
\82È
\96¡
\82ª
\82·
\82é
\81D",
940 otmp->odiluted ? "
\90¬
\95ª
\92²
\90®
\82³
\82ê
\82½" : "", fruitname(TRUE));
942 if (otmp->otyp == POT_FRUIT_JUICE) {
943 u.uhunger += (otmp->odiluted ? 5 : 10) * (2 + bcsign(otmp));
948 /* Tell them they can see again immediately, which
949 * will help them identify the potion...
951 make_blinded(0L, TRUE);
954 HSee_invisible |= FROMOUTSIDE;
956 incr_itimeout(&HSee_invisible, rn1(100, 750));
957 set_mimic_blocking(); /* do special mimic handling */
958 see_monsters(); /* see invisible monsters */
959 newsym(u.ux, u.uy); /* see yourself! */
960 if (msg && !Blind) { /* Blind possible if polymorphed */
962 You("can see through yourself, but you are visible!");
964 You("
\93§
\96¾
\82Å
\82 \82é
\81D
\82µ
\82©
\82µ
\8c©
\82¦
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81I");
972 You("stiffen momentarily.");
974 You("
\88ê
\8fu
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
976 if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
978 You("are motionlessly suspended.");
980 You("
\8bó
\92\86\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81D");
983 You("are frozen in place!");
985 You("
\82»
\82Ì
\8fê
\82Å
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
988 Your("%s are frozen to the %s!", makeplural(body_part(FOOT)),
989 surface(u.ux, u.uy));
991 You("
\93®
\82¯
\82È
\82
\82È
\82Á
\82½
\81I");
993 nomul(-(rn1(10, 25 - 12 * bcsign(otmp))));
995 multi_reason = "frozen by a potion";
997 multi_reason = "
\96ò
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
998 nomovemsg = You_can_move_again;
999 exercise(A_DEX, FALSE);
1003 if (Sleep_resistance || Free_action) {
1007 You("
\82 \82
\82Ñ
\82ð
\82µ
\82½
\81D");
1010 You("suddenly fall asleep!");
1012 pline("
\93Ë
\91R
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1013 fall_asleep(-rn1(10, 25 - 12 * bcsign(otmp)), TRUE);
1016 case POT_MONSTER_DETECTION:
1017 case SPE_DETECT_MONSTERS:
1018 if (otmp->blessed) {
1021 if (Detect_monsters)
1024 /* after a while, repeated uses become less effective */
1025 if ((HDetect_monsters & TIMEOUT) >= 300L)
1029 incr_itimeout(&HDetect_monsters, i);
1030 for (x = 1; x < COLNO; x++) {
1031 for (y = 0; y < ROWNO; y++) {
1032 if (levl[x][y].glyph == GLYPH_INVISIBLE) {
1043 You_feel("lonely.");
1045 You("
\90S
\8d×
\82
\82È
\82Á
\82½
\81D");
1048 if (monster_detect(otmp, 0))
1049 return 1; /* nothing detected */
1050 exercise(A_WIS, TRUE);
1052 case POT_OBJECT_DETECTION:
1053 case SPE_DETECT_TREASURE:
1054 if (object_detect(otmp, 0))
1055 return 1; /* nothing detected */
1056 exercise(A_WIS, TRUE);
1060 pline("Yecch! This stuff tastes like poison.");
1062 pline("
\83E
\83F
\81[
\81I
\93Å
\82Ì
\82æ
\82¤
\82È
\96¡
\82ª
\82·
\82é
\81D");
1063 if (otmp->blessed) {
1065 pline("(But in fact it was mildly stale %s.)", fruitname(TRUE));
1067 pline("(
\82µ
\82©
\82µ
\8eÀ
\8dÛ
\82»
\82ê
\82Í
\8f
\82µ
\8cÃ
\82
\82È
\82Á
\82½%s
\81D)", fruitname(TRUE));
1068 if (!Role_if(PM_HEALER)) {
1069 /* NB: blessed otmp->fromsink is not possible */
1071 losehp(1, "mildly contaminated potion", KILLED_BY_AN);
1073 losehp(1, "
\95a
\8bC
\82É
\89\98\90õ
\82³
\82ê
\82½
\96ò
\82Å", KILLED_BY_AN);
1076 if (Poison_resistance)
1078 pline("(But in fact it was biologically contaminated %s.)",
1080 pline("(
\82µ
\82©
\82µ
\8eÀ
\8dÛ
\82»
\82ê
\82Í
\90¶
\95¨
\8aw
\93I
\82É
\89\98\90õ
\82³
\82ê
\82½%s
\82¾
\81D)",
1082 if (Role_if(PM_HEALER)) {
1084 pline("Fortunately, you have been immunized.");
1086 pline("
\8dK
\89^
\82È
\82±
\82Æ
\82É
\81C
\82 \82È
\82½
\82Í
\96Æ
\89u
\82ª
\82 \82é
\81D");
1088 char contaminant[BUFSZ];
1089 int typ = rn2(A_MAX);
1092 Sprintf(contaminant, "%s%s",
1093 (Poison_resistance) ? "mildly " : "",
1094 (otmp->fromsink) ? "contaminated tap water"
1095 : "contaminated potion");
1097 Sprintf(contaminant, "%s
\89\98\90õ
\82³
\82ê
\82½%s
\82Å",
1098 (Poison_resistance) ? "
\8f
\82µ" : "",
1099 (otmp->fromsink) ? "
\90\85"
1103 poisontell(typ, FALSE);
1104 (void) adjattrib(typ, Poison_resistance ? -1 : -rn1(4, 3),
1107 if (!Poison_resistance) {
1109 losehp(rnd(10) + 5 * !!(otmp->cursed), contaminant,
1112 losehp(rnd(10) + 5 * !!(otmp->cursed), contaminant,
1115 /* rnd loss is so that unblessed poorer than blessed */
1116 losehp(1 + rn2(2), contaminant,
1117 (otmp->fromsink) ? KILLED_BY : KILLED_BY_AN);
1119 exercise(A_CON, FALSE);
1122 if (Hallucination) {
1124 You("are shocked back to your senses!");
1126 You("
\8cÜ
\8a´
\82É
\8fÕ
\8c\82\82ð
\8eó
\82¯
\82½
\81I");
1127 (void) make_hallucinated(0L, FALSE, 0L);
1132 if (Hallucination) {
1134 pline("What a trippy feeling!");
1136 pline("
\82È
\82ñ
\82©
\83w
\83\8d\83w
\83\8d\82·
\82é
\81I");
1140 pline("Huh, What? Where am I?");
1142 pline("
\82Ù
\82¦
\81H
\8e\84\82Í
\92N
\81H");
1145 make_confused(itimeout_incr(HConfusion,
1146 rn1(7, 16 - 8 * bcsign(otmp))),
1149 case POT_GAIN_ABILITY:
1152 pline("Ulch! That potion tasted foul!");
1154 pline("
\83E
\83F
\81I
\88«
\8fL
\82ª
\82·
\82é
\81I");
1156 } else if (Fixed_abil) {
1158 } else { /* If blessed, increase all; if not, try up to */
1159 int itmp; /* 6 times to find one which can be increased. */
1161 i = -1; /* increment to 0 */
1162 for (ii = A_MAX; ii > 0; ii--) {
1163 i = (otmp->blessed ? i + 1 : rn2(A_MAX));
1164 /* only give "your X is already as high as it can get"
1165 message on last attempt (except blessed potions) */
1166 itmp = (otmp->blessed || ii == 1) ? 0 : -1;
1167 if (adjattrib(i, 1, itmp) && !otmp->blessed)
1173 if (Wounded_legs && !otmp->cursed && !u.usteed) {
1174 /* heal_legs() would heal steeds legs */
1180 case SPE_HASTE_SELF:
1181 if (!Very_fast) { /* wwf@doe.carleton.ca */
1183 You("are suddenly moving %sfaster.", Fast ? "" : "much ");
1185 You("
\93Ë
\91R%s
\91¬
\82
\88Ú
\93®
\82Å
\82«
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D", Fast ? "" : "
\82Æ
\82Ä
\82à");
1188 Your("%s get new energy.", makeplural(body_part(LEG)));
1190 pline("%s
\82É
\83G
\83l
\83\8b\83M
\81[
\82ª
\92\8d\82¬
\82±
\82Ü
\82ê
\82é
\82æ
\82¤
\82È
\8a´
\82¶
\82ª
\82µ
\82½
\81D", body_part(LEG));
1193 exercise(A_DEX, TRUE);
1194 incr_itimeout(&HFast, rn1(10, 100 + 60 * bcsign(otmp)));
1199 make_blinded(itimeout_incr(Blinded,
1200 rn1(200, 250 - 125 * bcsign(otmp))),
1203 case POT_GAIN_LEVEL:
1206 /* they went up a level */
1207 if ((ledger_no(&u.uz) == 1 && u.uhave.amulet)
1208 || Can_rise_up(u.ux, u.uy, &u.uz)) {
1210 const char *riseup = "rise up, through the %s!";
1212 const char *riseup ="%s
\82ð
\93Ë
\82«
\94²
\82¯
\82½
\81I";
1214 if (ledger_no(&u.uz) == 1) {
1215 You(riseup, ceiling(u.ux, u.uy));
1216 goto_level(&earth_level, FALSE, FALSE, FALSE);
1218 register int newlev = depth(&u.uz) - 1;
1221 get_level(&newlevel, newlev);
1222 if (on_level(&newlevel, &u.uz)) {
1224 pline("It tasted bad.");
1226 pline("
\82Æ
\82Ä
\82à
\82Ü
\82¸
\82¢
\81D");
1229 You(riseup, ceiling(u.ux, u.uy));
1230 goto_level(&newlevel, FALSE, FALSE, FALSE);
1234 You("have an uneasy feeling.");
1236 You("
\95s
\88À
\82È
\8bC
\8e\9d\82É
\82È
\82Á
\82½
\81D");
1240 /* blessed potions place you at a random spot in the
1241 middle of the new level instead of the low point */
1243 u.uexp = rndexp(TRUE);
1247 You_feel("better.");
1249 You("
\8bC
\95ª
\82ª
\82æ
\82
\82È
\82Á
\82½
\81D");
1250 healup(d(6 + 2 * bcsign(otmp), 4), !otmp->cursed ? 1 : 0,
1251 !!otmp->blessed, !otmp->cursed);
1252 exercise(A_CON, TRUE);
1254 case POT_EXTRA_HEALING:
1256 You_feel("much better.");
1258 You("
\8bC
\95ª
\82ª
\82Æ
\82Ä
\82à
\82æ
\82
\82È
\82Á
\82½
\81D");
1259 healup(d(6 + 2 * bcsign(otmp), 8),
1260 otmp->blessed ? 5 : !otmp->cursed ? 2 : 0, !otmp->cursed,
1262 (void) make_hallucinated(0L, TRUE, 0L);
1263 exercise(A_CON, TRUE);
1264 exercise(A_STR, TRUE);
1266 case POT_FULL_HEALING:
1268 You_feel("completely healed.");
1270 You("
\8a®
\91S
\82É
\89ñ
\95\9c\82µ
\82½
\81D");
1271 healup(400, 4 + 4 * bcsign(otmp), !otmp->cursed, TRUE);
1272 /* Restore one lost level if blessed */
1273 if (otmp->blessed && u.ulevel < u.ulevelmax) {
1274 /* when multiple levels have been lost, drinking
1275 multiple potions will only get half of them back */
1279 (void) make_hallucinated(0L, TRUE, 0L);
1280 exercise(A_STR, TRUE);
1281 exercise(A_CON, TRUE);
1283 case POT_LEVITATION:
1284 case SPE_LEVITATION:
1286 * BLevitation will be set if levitation is blocked due to being
1287 * inside rock (currently or formerly in phazing xorn form, perhaps)
1288 * but it doesn't prevent setting or incrementing Levitation timeout
1289 * (which will take effect after escaping from the rock if it hasn't
1292 if (!Levitation && !BLevitation) {
1293 /* kludge to ensure proper operation of float_up() */
1294 set_itimeout(&HLevitation, 1L);
1296 /* This used to set timeout back to 0, then increment it below
1297 for blessed and uncursed effects. But now we leave it so
1298 that cursed effect yields "you float down" on next turn.
1299 Blessed and uncursed get one extra turn duration. */
1300 } else /* already levitating, or can't levitate */
1304 /* 'already levitating' used to block the cursed effect(s)
1305 aside from ~I_SPECIAL; it was not clear whether that was
1306 intentional; either way, it no longer does (as of 3.6.1) */
1307 HLevitation &= ~I_SPECIAL; /* can't descend upon demand */
1309 ; /* rising via levitation is blocked */
1310 } else if ((u.ux == xupstair && u.uy == yupstair)
1311 || (sstairs.up && u.ux == sstairs.sx && u.uy == sstairs.sy)
1312 || (xupladder && u.ux == xupladder && u.uy == yupladder)) {
1314 /* in case we're already Levitating, which would have
1315 resulted in incrementing 'nothing' */
1316 nothing = 0; /* not nothing after all */
1317 } else if (has_ceiling(&u.uz)) {
1318 int dmg = rnd(!uarmh ? 10 : !is_metallic(uarmh) ? 6 : 3);
1321 You("hit your %s on the %s.", body_part(HEAD),
1322 ceiling(u.ux, u.uy));
1324 You("%s
\82ð%s
\82É
\82Ô
\82Â
\82¯
\82½
\81D", body_part(HEAD),
1325 ceiling(u.ux,u.uy));
1328 losehp(Maybe_Half_Phys(dmg), "colliding with the ceiling",
1330 losehp(Maybe_Half_Phys(dmg), "
\93V
\88ä
\82É
\93ª
\82ð
\82Ô
\82Â
\82¯
\82Ä",
1332 nothing = 0; /* not nothing after all */
1334 } else if (otmp->blessed) {
1335 /* at this point, timeout is already at least 1 */
1336 incr_itimeout(&HLevitation, rn1(50, 250));
1337 /* can descend at will (stop levitating via '>') provided timeout
1338 is the only factor (ie, not also wearing Lev ring or boots) */
1339 HLevitation |= I_SPECIAL;
1340 } else /* timeout is already at least 1 */
1341 incr_itimeout(&HLevitation, rn1(140, 10));
1343 if (Levitation && IS_SINK(levl[u.ux][u.uy].typ))
1345 /* levitating blocks flying */
1348 case POT_GAIN_ENERGY: { /* M. Stephenson */
1353 You_feel("lackluster.");
1355 You("
\88Ó
\8bC
\8fÁ
\92¾
\82µ
\82½
\81D");
1358 pline("Magical energies course through your body.");
1360 pline("
\96\82\96@
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ª
\82 \82È
\82½
\82Ì
\91Ì
\82É
\96\9e\82¿
\82½
\81D");
1362 /* old: num = rnd(5) + 5 * otmp->blessed + 1;
1363 * blessed: +7..11 max & current (+9 avg)
1364 * uncursed: +2.. 6 max & current (+4 avg)
1365 * cursed: -2.. 6 max & current (-4 avg)
1367 * blessed: +3..18 max (+10.5 avg), +9..54 current (+31.5 avg)
1368 * uncursed: +2..12 max (+ 7 avg), +6..36 current (+21 avg)
1369 * cursed: -1.. 6 max (- 3.5 avg), -3..18 current (-10.5 avg)
1371 num = d(otmp->blessed ? 3 : !otmp->cursed ? 2 : 1, 6);
1373 num = -num; /* subtract instead of add when cursed */
1378 if (u.uen > u.uenmax)
1380 else if (u.uen <= 0)
1383 exercise(A_WIS, TRUE);
1386 case POT_OIL: { /* P. Winner */
1387 boolean good_for_you = FALSE;
1389 if (otmp->lamplit) {
1390 if (likes_fire(youmonst.data)) {
1392 pline("Ahh, a refreshing drink.");
1394 pline("
\82í
\81[
\82¨
\81C
\90¶
\82«
\95Ô
\82é
\81D");
1395 good_for_you = TRUE;
1398 You("burn your %s.", body_part(FACE));
1400 Your("%s
\82Í
\8d\95\8fÅ
\82°
\82É
\82È
\82Á
\82½
\81D", body_part(FACE));
1403 losehp(d(Fire_resistance ? 1 : 3, 4), "burning potion of oil",
1405 losehp(d(Fire_resistance ? 1 : 3, 4), "
\94R
\82¦
\82Ä
\82¢
\82é
\96û
\82ð
\88ù
\82ñ
\82Å",
1408 } else if (otmp->cursed)
1410 pline("This tastes like castor oil.");
1412 pline("
\82Ð
\82Ü
\82µ
\96û
\82Ì
\82æ
\82¤
\82È
\96¡
\82ª
\82·
\82é
\81D");
1415 pline("That was smooth!");
1417 pline("
\8cû
\82 \82½
\82è
\82ª
\82æ
\82¢
\81I");
1418 exercise(A_WIS, good_for_you);
1422 if (Acid_resistance) {
1423 /* Not necessarily a creature who _likes_ acid */
1425 pline("This tastes %s.", Hallucination ? "tangy" : "sour");
1427 pline("%s
\96¡
\82ª
\82·
\82é
\81D", Hallucination ? "
\82Ò
\82è
\82Á
\82Æ
\82µ
\82½" : "
\8e_
\82Ì");
1432 pline("This burns%s!",
1433 otmp->blessed ? " a little" : otmp->cursed ? " a lot"
1436 pline("%s
\8fÅ
\82°
\82½
\81I",
1437 otmp->blessed ? "
\8f
\82µ" : otmp->cursed ? "
\82·
\82²
\82"
1440 dmg = d(otmp->cursed ? 2 : 1, otmp->blessed ? 4 : 8);
1442 losehp(Maybe_Half_Phys(dmg), "potion of acid", KILLED_BY_AN);
1444 losehp(Maybe_Half_Phys(dmg), "
\8e_
\82Ì
\96ò
\82ð
\88ù
\82ñ
\82Å", KILLED_BY_AN);
1445 exercise(A_CON, FALSE);
1448 fix_petrification();
1449 unkn++; /* holy/unholy water can burn like acid too */
1453 You_feel("a little %s.", Hallucination ? "normal" : "strange");
1455 You("
\8f
\82µ%s
\82È
\8a´
\82¶
\82ª
\82µ
\82½
\81D", Hallucination ? "
\95\81\92Ê" : "
\95Ï");
1460 impossible("What a funny potion! (%u)", otmp->otyp);
1468 make_totter(xtime, talk)
1469 long xtime; /* nonzero if this is an attempt to turn on hallucination */
1472 const char *message = 0;
1475 message = "
\95û
\8cü
\8a´
\8ao
\82ª
\90³
\8fí
\82É
\82È
\82Á
\82½
\81D";
1477 message = "
\95û
\8cü
\8a´
\8ao
\82ª
\96\83á
\83\82µ
\82½
\81D";
1479 set_itimeout(&Totter, xtime);
1485 healup(nhp, nxtra, curesick, cureblind)
1487 register boolean curesick, cureblind;
1493 u.mh = (u.mhmax += nxtra);
1496 if (u.uhp > u.uhpmax)
1497 u.uhp = (u.uhpmax += nxtra);
1501 /* 3.6.1: it's debatible whether healing magic should clean off
1502 mundane 'dirt', but if it doesn't, blindness isn't cured */
1504 make_blinded(0L, TRUE);
1507 make_vomiting(0L, TRUE);
1508 make_sick(0L, (char *) 0, TRUE, SICK_ALL);
1515 strange_feeling(obj, txt)
1519 if (flags.beginner || !txt)
1521 You("have a %s feeling for a moment, then it passes.",
1522 Hallucination ? "normal" : "strange");
1524 You("%s
\8bC
\95ª
\82É
\82¨
\82»
\82í
\82ê
\82½
\82ª
\81C
\82·
\82®
\82É
\8fÁ
\82¦
\82³
\82Á
\82½
\81D",
1525 Hallucination ? "
\95\81\92Ê
\82Ì" : "
\8aï
\96
\82È");
1530 if (!obj) /* e.g., crystal ball finds no traps */
1533 if (obj->dknown && !objects[obj->otyp].oc_name_known
1534 && !objects[obj->otyp].oc_uname)
1541 const char *bottlenames[] = { "bottle", "phial", "flagon", "carafe",
1542 "flask", "jar", "vial" };
1544 const char *bottlenames[] = { "
\95r", "àÞ
\97\9e\95r", "
\88ê
\8f¡
\95r", "
\90\85\8d·
\82µ",
1545 "
\83t
\83\89\83X
\83R", "
\92Ù", "
\83K
\83\89\83X
\95r" };
1551 return bottlenames[rn2(SIZE(bottlenames))];
1554 /* handle item dipped into water potion or steed saddle splashed by same */
1556 H2Opotion_dip(potion, targobj, useeit, objphrase)
1557 struct obj *potion, *targobj;
1559 const char *objphrase; /* "Your widget glows" or "Steed's saddle glows" */
1561 void FDECL((*func), (OBJ_P)) = 0;
1562 const char *glowcolor = 0;
1563 #define COST_alter (-2)
1564 #define COST_none (-1)
1565 int costchange = COST_none;
1566 boolean altfmt = FALSE, res = FALSE;
1568 if (!potion || potion->otyp != POT_WATER)
1571 if (potion->blessed) {
1572 if (targobj->cursed) {
1574 glowcolor = NH_AMBER;
1575 costchange = COST_UNCURS;
1576 } else if (!targobj->blessed) {
1578 glowcolor = NH_LIGHT_BLUE;
1579 costchange = COST_alter;
1580 altfmt = TRUE; /* "with a <color> aura" */
1582 } else if (potion->cursed) {
1583 if (targobj->blessed) {
1586 glowcolor = "brown";
1588 glowcolor = "
\92\83\90F
\82Ì";
1589 costchange = COST_UNBLSS;
1590 } else if (!targobj->cursed) {
1592 glowcolor = NH_BLACK;
1593 costchange = COST_alter;
1597 /* dipping into uncursed water; carried() check skips steed saddle */
1598 if (carried(targobj)) {
1599 if (water_damage(targobj, 0, TRUE) != ER_NOTHING)
1604 /* give feedback before altering the target object;
1605 this used to set obj->bknown even when not seeing
1606 the effect; now hero has to see the glow, and bknown
1607 is cleared instead of set if perception is distorted */
1609 glowcolor = hcolor(glowcolor);
1610 /*JP:3.6.0
\8e\9e\93_
\82Å
\82Í
\93®
\8e\8c\82Í"glow"
\82¾
\82¯
\82È
\82Ì
\82Å
\8c\88\82ß
\8c\82\82¿*/
1613 pline("%s with %s aura.", objphrase, an(glowcolor));
1615 pline("%s
\82Í%s
\83I
\81[
\83\89\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81D", objphrase, glowcolor);
1619 pline("%s %s.", objphrase, glowcolor);
1621 pline("%s
\82Í%s
\8bP
\82¢
\82½
\81D", objphrase, jconj_adj(glowcolor));
1623 iflags.last_msg = PLNMSG_OBJ_GLOWS;
1624 targobj->bknown = !Hallucination;
1626 /* potions of water are the only shop goods whose price depends
1627 on their curse/bless state */
1628 if (targobj->unpaid && targobj->otyp == POT_WATER) {
1629 if (costchange == COST_alter)
1630 /* added blessing or cursing; update shop
1631 bill to reflect item's new higher price */
1632 alter_cost(targobj, 0L);
1633 else if (costchange != COST_none)
1634 /* removed blessing or cursing; you
1635 degraded it, now you'll have to buy it... */
1636 costly_alteration(targobj, costchange);
1638 /* finally, change curse/bless state */
1645 /* potion obj hits monster mon, which might be youmonst; obj always used up */
1647 potionhit(mon, obj, how)
1652 const char *botlnam = bottlename();
1653 boolean isyou = (mon == &youmonst);
1654 int distance, tx, ty;
1655 struct obj *saddle = (struct obj *) 0;
1656 boolean hit_saddle = FALSE, your_fault = (how <= POTHIT_HERO_THROW);
1659 tx = u.ux, ty = u.uy;
1662 pline_The("%s crashes on your %s and breaks into shards.", botlnam,
1665 pline("%s
\82ª
\82 \82È
\82½
\82Ì%s
\82Ì
\8fã
\82Å
\89ó
\82ê
\94j
\95Ð
\82Æ
\82È
\82Á
\82½
\81D", botlnam,
1669 losehp(Maybe_Half_Phys(rnd(2)),
1670 (how == POTHIT_OTHER_THROW) ? "propelled potion" /* scatter */
1673 #else /*
\82Ç
\82¿
\82ç
\82à
\81u
\93\8a\82°
\82ç
\82ê
\82½
\81v
\82Å
\82æ
\82¢*/
1674 losehp(Maybe_Half_Phys(rnd(2)), "
\93\8a\82°
\82ç
\82ê
\82½
\96ò
\82Å", KILLED_BY_AN);
1677 tx = mon->mx, ty = mon->my;
1678 /* sometimes it hits the saddle */
1679 if (((mon->misc_worn_check & W_SADDLE)
1680 && (saddle = which_armor(mon, W_SADDLE)))
1682 || (obj->otyp == POT_WATER
1683 && ((rnl(10) > 7 && obj->cursed)
1684 || (rnl(10) < 4 && obj->blessed) || !rn2(3)))))
1686 distance = distu(tx, ty);
1687 if (!cansee(tx, ty)) {
1691 pline("
\83K
\83V
\83\83\83\93\81I");
1693 char *mnam = mon_nam(mon);
1696 if (hit_saddle && saddle) {
1698 Sprintf(buf, "%s saddle",
1699 s_suffix(x_monnam(mon, ARTICLE_THE, (char *) 0,
1700 (SUPPRESS_IT | SUPPRESS_SADDLE),
1703 Sprintf(buf, "%s
\82Ì
\88Æ",
1704 x_monnam(mon, ARTICLE_THE, (char *) 0,
1705 (SUPPRESS_IT | SUPPRESS_SADDLE),
1708 } else if (has_head(mon->data)) {
1710 Sprintf(buf, "%s %s", s_suffix(mnam),
1711 (notonhead ? "body" : "head"));
1713 Sprintf(buf, "%s
\82Ì%s", mnam,
1714 (notonhead ? "
\91Ì" : "
\93ª"));
1720 pline_The("%s crashes on %s and breaks into shards.", botlnam,
1723 pline("%s
\82ª%s
\82Ì
\8fã
\82Å
\89ó
\82ê
\94j
\95Ð
\82Æ
\82È
\82Á
\82½
\81D", botlnam,
1727 if (rn2(5) && mon->mhp > 1 && !hit_saddle)
1731 /* oil doesn't instantly evaporate; Neither does a saddle hit */
1732 if (obj->otyp != POT_OIL && !hit_saddle && cansee(tx, ty))
1734 pline("%s.", Tobjnam(obj, "evaporate"));
1736 pline("%s
\82Í
\8fö
\94
\82µ
\82½
\81D", xname(obj));
1739 switch (obj->otyp) {
1742 explode_oil(obj, u.ux, u.uy);
1746 You_feel("a little %s.", Hallucination ? "normal" : "strange");
1748 You("%s
\82È
\8a´
\82¶
\82ª
\82µ
\82½
\81D", Hallucination ? "
\95\81\92Ê" : "
\95Ï");
1749 if (!Unchanging && !Antimagic)
1753 if (!Acid_resistance) {
1757 pline("This burns%s!",
1758 obj->blessed ? " a little"
1759 : obj->cursed ? " a lot" : "");
1761 pline("%s
\94R
\82¦
\82½
\81I",
1762 obj->blessed ? "
\8f
\82µ"
1763 : obj->cursed ? "
\82Í
\82°
\82µ
\82" : "");
1765 dmg = d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8);
1767 losehp(Maybe_Half_Phys(dmg), "potion of acid", KILLED_BY_AN);
1769 losehp(Maybe_Half_Phys(dmg), "
\8e_
\82Ì
\96ò
\82ð
\97\81\82Ñ
\82Ä", KILLED_BY_AN);
1773 } else if (hit_saddle && saddle) {
1774 char *mnam, buf[BUFSZ], saddle_glows[BUFSZ];
1775 boolean affected = FALSE;
1776 boolean useeit = !Blind && canseemon(mon) && cansee(tx, ty);
1778 mnam = x_monnam(mon, ARTICLE_THE, (char *) 0,
1779 (SUPPRESS_IT | SUPPRESS_SADDLE), FALSE);
1780 Sprintf(buf, "%s", upstart(s_suffix(mnam)));
1782 switch (obj->otyp) {
1785 Sprintf(saddle_glows, "%s %s", buf, aobjnam(saddle, "glow"));
1787 Sprintf(saddle_glows, "%s", buf);
1788 affected = H2Opotion_dip(obj, saddle, useeit, saddle_glows);
1791 /* Do we allow the saddle to polymorph? */
1794 if (useeit && !affected)
1796 pline("%s %s wet.", buf, aobjnam(saddle, "get"));
1798 pline("%s
\82Í
\94G
\82ê
\82½
\81D", buf);
1800 boolean angermon = your_fault, cureblind = FALSE;
1802 switch (obj->otyp) {
1803 case POT_FULL_HEALING:
1806 case POT_EXTRA_HEALING:
1813 if (mon->data == &mons[PM_PESTILENCE])
1816 case POT_RESTORE_ABILITY:
1817 case POT_GAIN_ABILITY:
1820 if (mon->mhp < mon->mhpmax) {
1821 mon->mhp = mon->mhpmax;
1824 pline("%s looks sound and hale again.", Monnam(mon));
1826 pline("%s
\82Í
\8c³
\8bC
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D", Monnam(mon));
1829 mcureblindness(mon, canseemon(mon));
1832 if (mon->data == &mons[PM_PESTILENCE])
1834 if (dmgtype(mon->data, AD_DISE)
1835 /* won't happen, see prior goto */
1836 || dmgtype(mon->data, AD_PEST)
1837 /* most common case */
1838 || resists_poison(mon)) {
1841 pline("%s looks unharmed.", Monnam(mon));
1843 pline("%s
\82Í
\82È
\82ñ
\82Æ
\82à
\82È
\82¢
\82æ
\82¤
\82¾
\81D", Monnam(mon));
1848 if ((mon->mhpmax > 3) && !resist(mon, POTION_CLASS, 0, NOTELL))
1850 if ((mon->mhp > 2) && !resist(mon, POTION_CLASS, 0, NOTELL))
1852 if (mon->mhp > mon->mhpmax)
1853 mon->mhp = mon->mhpmax;
1856 pline("%s looks rather ill.", Monnam(mon));
1858 pline("%s
\82Í
\95a
\8bC
\82Á
\82Û
\82
\8c©
\82¦
\82é
\81D", Monnam(mon));
1862 if (!resist(mon, POTION_CLASS, 0, NOTELL))
1865 case POT_INVISIBILITY: {
1866 boolean sawit = canspotmon(mon);
1869 mon_set_minvis(mon);
1870 if (sawit && !canspotmon(mon) && cansee(mon->mx, mon->my))
1871 map_invisible(mon->mx, mon->my);
1875 /* wakeup() doesn't rouse victims of temporary sleep */
1876 if (sleep_monst(mon, rnd(12), POTION_CLASS)) {
1878 pline("%s falls asleep.", Monnam(mon));
1880 pline("%s
\82Í
\96°
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D", Monnam(mon));
1885 if (mon->mcanmove) {
1886 /* really should be rnd(5) for consistency with players
1887 * breathing potions, but...
1889 paralyze_monst(mon, rnd(25));
1894 mon_adjust_speed(mon, 1, obj);
1897 if (haseyes(mon->data)) {
1898 int btmp = 64 + rn2(32)
1899 + rn2(32) * !resist(mon, POTION_CLASS, 0, NOTELL);
1901 btmp += mon->mblinded;
1902 mon->mblinded = min(btmp, 127);
1907 if (is_undead(mon->data) || is_demon(mon->data)
1908 || is_were(mon->data) || is_vampshifter(mon)) {
1911 pline("%s %s in pain!", Monnam(mon),
1912 is_silent(mon->data) ? "writhes" : "shrieks");
1914 pline("%s
\82Í
\8bê
\92É%s
\81I", Monnam(mon),
1915 is_silent(mon->data) ? "
\82É
\90g
\82à
\82¾
\82¦
\82µ
\82½" : "
\82Ì
\8b©
\82Ñ
\90º
\82ð
\82 \82°
\82½");
1917 if (!is_silent(mon->data))
1918 wake_nearto(tx, ty, mon->data->mlevel * 10);
1919 mon->mhp -= d(2, 6);
1920 /* should only be by you */
1923 else if (is_were(mon->data) && !is_human(mon->data))
1924 new_were(mon); /* revert to human */
1925 } else if (obj->cursed) {
1929 pline("%s looks healthier.", Monnam(mon));
1931 pline("%s
\82Í
\82æ
\82è
\8c³
\8bC
\82É
\82È
\82Á
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82é
\81D", Monnam(mon));
1932 mon->mhp += d(2, 6);
1933 if (mon->mhp > mon->mhpmax)
1934 mon->mhp = mon->mhpmax;
1935 if (is_were(mon->data) && is_human(mon->data)
1936 && !Protection_from_shape_changers)
1937 new_were(mon); /* transform into beast */
1939 } else if (mon->data == &mons[PM_GREMLIN]) {
1941 (void) split_mon(mon, (struct monst *) 0);
1942 } else if (mon->data == &mons[PM_IRON_GOLEM]) {
1945 pline("%s rusts.", Monnam(mon));
1947 pline("%s
\82Í
\8eK
\82Ñ
\82½
\81D", Monnam(mon));
1948 mon->mhp -= d(1, 6);
1949 /* should only be by you */
1956 explode_oil(obj, tx, ty);
1959 if (!resists_acid(mon) && !resist(mon, POTION_CLASS, 0, NOTELL)) {
1961 pline("%s %s in pain!", Monnam(mon),
1962 is_silent(mon->data) ? "writhes" : "shrieks");
1964 pline("%s
\82Í
\8bê
\92É%s
\81I", Monnam(mon),
1965 is_silent(mon->data) ? "
\82É
\90g
\82à
\82¾
\82¦
\82µ
\82½" : "
\82Ì
\8b©
\82Ñ
\90º
\82ð
\82 \82°
\82½");
1967 if (!is_silent(mon->data))
1968 wake_nearto(tx, ty, mon->data->mlevel * 10);
1969 mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8);
1974 monkilled(mon, "", AD_ACID);
1979 (void) bhitm(mon, obj);
1982 case POT_GAIN_LEVEL:
1983 case POT_LEVITATION:
1984 case POT_FRUIT_JUICE:
1985 case POT_MONSTER_DETECTION:
1986 case POT_OBJECT_DETECTION:
1990 /* target might have been killed */
1999 /* Note: potionbreathe() does its own docall() */
2000 if ((distance == 0 || (distance < 3 && rn2(5)))
2001 && (!breathless(youmonst.data) || haseyes(youmonst.data)))
2003 else if (obj->dknown && !objects[obj->otyp].oc_name_known
2004 && !objects[obj->otyp].oc_uname && cansee(tx, ty))
2007 if (*u.ushops && obj->unpaid) {
2008 struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
2010 /* neither of the first two cases should be able to happen;
2011 only the hero should ever have an unpaid item, and only
2012 when inside a tended shop */
2013 if (!shkp) /* if shkp was killed, unpaid ought to cleared already */
2015 else if (context.mon_moving) /* obj thrown by monster */
2016 subfrombill(obj, shkp);
2017 else /* obj thrown by hero */
2018 (void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
2021 obfree(obj, (struct obj *) 0);
2024 /* vapors are inhaled or get in your eyes */
2027 register struct obj *obj;
2029 int i, ii, isdone, kn = 0;
2030 boolean cureblind = FALSE;
2032 /* potion of unholy water might be wielded; prevent
2033 you_were() -> drop_weapon() from dropping it so that it
2034 remains in inventory where our caller expects it to be */
2037 switch (obj->otyp) {
2038 case POT_RESTORE_ABILITY:
2039 case POT_GAIN_ABILITY:
2041 if (!breathless(youmonst.data))
2043 pline("Ulch! That potion smells terrible!");
2045 pline("
\83E
\83Q
\83F
\81I
\96ò
\82Í
\82à
\82Ì
\82·
\82²
\82¢
\93õ
\82¢
\82ª
\82·
\82é
\81I");
2046 else if (haseyes(youmonst.data)) {
2048 const char *eyes = body_part(EYE);
2050 if (eyecount(youmonst.data) != 1)
2051 eyes = makeplural(eyes);
2052 Your("%s %s!", eyes, vtense(eyes, "sting"));
2054 Your("%s
\82ª
\82¸
\82«
\82¸
\82«
\82·
\82é
\81I", body_part(EYE));
2059 i = rn2(A_MAX); /* start at a random point */
2060 for (isdone = ii = 0; !isdone && ii < A_MAX; ii++) {
2061 if (ABASE(i) < AMAX(i)) {
2063 /* only first found if not blessed */
2064 isdone = !(obj->blessed);
2072 case POT_FULL_HEALING:
2073 if (Upolyd && u.mh < u.mhmax)
2074 u.mh++, context.botl = 1;
2075 if (u.uhp < u.uhpmax)
2076 u.uhp++, context.botl = 1;
2079 case POT_EXTRA_HEALING:
2080 if (Upolyd && u.mh < u.mhmax)
2081 u.mh++, context.botl = 1;
2082 if (u.uhp < u.uhpmax)
2083 u.uhp++, context.botl = 1;
2088 if (Upolyd && u.mh < u.mhmax)
2089 u.mh++, context.botl = 1;
2090 if (u.uhp < u.uhpmax)
2091 u.uhp++, context.botl = 1;
2095 make_blinded(0L, !u.ucreamed);
2096 exercise(A_CON, TRUE);
2099 if (!Role_if(PM_HEALER)) {
2112 exercise(A_CON, FALSE);
2115 case POT_HALLUCINATION:
2117 You("have a momentary vision.");
2119 You("
\88ê
\8fu
\8c¶
\89e
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81D");
2125 You_feel("somewhat dizzy.");
2127 You("
\82ß
\82Ü
\82¢
\82ð
\8a´
\82¶
\82½
\81D");
2128 make_confused(itimeout_incr(HConfusion, rnd(5)), FALSE);
2130 case POT_INVISIBILITY:
2131 if (!Blind && !Invis) {
2134 pline("For an instant you %s!",
2135 See_invisible ? "could see right through yourself"
2136 : "couldn't see yourself");
2138 pline("
\88ê
\8fu
\8e©
\95ª
\8e©
\90g
\82ª%s
\8c©
\82¦
\82È
\82
\82È
\82Á
\82½
\81I",
2139 See_invisible ? "
\90³
\82µ
\82"
2148 pline("%s seems to be holding you.", Something);
2150 pline("%s
\82ª
\82 \82È
\82½
\82ð
\82Â
\82©
\82Ü
\82¦
\82Ä
\82¢
\82é
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D", Something);
2153 multi_reason = "frozen by a potion";
2155 multi_reason = "
\96ò
\82Å
\8dd
\92¼
\82µ
\82Ä
\82¢
\82é
\8e\9e\82É";
2156 nomovemsg = You_can_move_again;
2157 exercise(A_DEX, FALSE);
2160 You("stiffen momentarily.");
2162 You("
\88ê
\8fu
\8dd
\92¼
\82µ
\82½
\81D");
2166 if (!Free_action && !Sleep_resistance) {
2168 You_feel("rather tired.");
2170 You("
\82·
\82±
\82µ
\94æ
\82ê
\82½
\81D");
2173 multi_reason = "sleeping off a magical draught";
2175 multi_reason = "
\96\82\96@
\93I
\82É
\96°
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82É";
2176 nomovemsg = You_can_move_again;
2177 exercise(A_DEX, FALSE);
2182 You("
\82 \82
\82Ñ
\82ð
\82µ
\82½
\81D");
2187 Your("knees seem more flexible now.");
2189 Your("
\95G
\82Í
\82æ
\82è
\82·
\82Î
\82â
\82
\93®
\82
\82æ
\82¤
\82É
\82È
\82Á
\82½
\81D");
2190 incr_itimeout(&HFast, rnd(5));
2191 exercise(A_DEX, TRUE);
2194 if (!Blind && !Unaware) {
2197 pline("It suddenly gets dark.");
2199 pline("
\93Ë
\91R
\88Ã
\82
\82È
\82Á
\82½
\81D");
2201 make_blinded(itimeout_incr(Blinded, rnd(5)), FALSE);
2202 if (!Blind && !Unaware)
2203 Your1(vision_clears);
2206 if (u.umonnum == PM_GREMLIN) {
2207 (void) split_mon(&youmonst, (struct monst *) 0);
2208 } else if (u.ulycn >= LOW_PM) {
2209 /* vapor from [un]holy water will trigger
2210 transformation but won't cure lycanthropy */
2211 if (obj->blessed && youmonst.data == &mons[u.ulycn])
2213 else if (obj->cursed && !Upolyd)
2219 exercise(A_CON, FALSE);
2222 case POT_GAIN_LEVEL:
2223 case POT_LEVITATION:
2224 case POT_FRUIT_JUICE:
2225 case POT_MONSTER_DETECTION:
2226 case POT_OBJECT_DETECTION:
2231 /* note: no obfree() -- that's our caller's responsibility */
2234 makeknown(obj->otyp);
2235 else if (!objects[obj->otyp].oc_name_known
2236 && !objects[obj->otyp].oc_uname)
2241 /* returns the potion type when o1 is dipped in o2 */
2244 register struct obj *o1, *o2;
2246 /* cut down on the number of cases below */
2247 if (o1->oclass == POTION_CLASS
2248 && (o2->otyp == POT_GAIN_LEVEL || o2->otyp == POT_GAIN_ENERGY
2249 || o2->otyp == POT_HEALING || o2->otyp == POT_EXTRA_HEALING
2250 || o2->otyp == POT_FULL_HEALING || o2->otyp == POT_ENLIGHTENMENT
2251 || o2->otyp == POT_FRUIT_JUICE)) {
2263 case POT_GAIN_LEVEL:
2264 case POT_GAIN_ENERGY:
2265 return POT_EXTRA_HEALING;
2267 case POT_EXTRA_HEALING:
2269 case POT_GAIN_LEVEL:
2270 case POT_GAIN_ENERGY:
2271 return POT_FULL_HEALING;
2273 case POT_FULL_HEALING:
2275 case POT_GAIN_LEVEL:
2276 case POT_GAIN_ENERGY:
2277 return POT_GAIN_ABILITY;
2282 return POT_FRUIT_JUICE;
2283 case POT_HALLUCINATION:
2289 case AMETHYST: /* "a-methyst" == "not intoxicated" */
2290 if (o2->otyp == POT_BOOZE)
2291 return POT_FRUIT_JUICE;
2293 case POT_GAIN_LEVEL:
2294 case POT_GAIN_ENERGY:
2297 return (rn2(3) ? POT_BOOZE : POT_ENLIGHTENMENT);
2299 return POT_EXTRA_HEALING;
2300 case POT_EXTRA_HEALING:
2301 return POT_FULL_HEALING;
2302 case POT_FULL_HEALING:
2303 return POT_GAIN_ABILITY;
2304 case POT_FRUIT_JUICE:
2305 return POT_SEE_INVISIBLE;
2307 return POT_HALLUCINATION;
2310 case POT_FRUIT_JUICE:
2313 return POT_SICKNESS;
2314 case POT_ENLIGHTENMENT:
2317 case POT_GAIN_LEVEL:
2318 case POT_GAIN_ENERGY:
2319 return POT_SEE_INVISIBLE;
2322 case POT_ENLIGHTENMENT:
2324 case POT_LEVITATION:
2326 return POT_GAIN_LEVEL;
2328 case POT_FRUIT_JUICE:
2331 return POT_CONFUSION;
2336 return STRANGE_OBJECT;
2344 static const char Dip_[] = "Dip ";
2346 static const char Dip_[] = "
\90Z
\82·";
2347 register struct obj *potion, *obj;
2348 struct obj *singlepotion;
2352 char qbuf[QBUFSZ], obuf[QBUFSZ];
2354 const char *shortestname; /* last resort obj name for prompt */
2357 allowall[0] = ALL_CLASSES;
2359 if (!(obj = getobj(allowall, "dip")))
2362 if (inaccessible_equipment(obj, "dip", FALSE))
2364 if (inaccessible_equipment(obj, "
\82ð
\90Z
\82·", FALSE))
2368 shortestname = (is_plural(obj) || pair_of(obj)) ? "them" : "it";
2371 * Bypass safe_qbuf() since it doesn't handle varying suffix without
2372 * an awful lot of support work. Format the object once, even though
2373 * the fountain and pool prompts offer a lot more room for it.
2374 * 3.6.0 used thesimpleoname() unconditionally, which posed no risk
2375 * of buffer overflow but drew bug reports because it omits user-
2376 * supplied type name.
2377 * getobj: "What do you want to dip <the object> into? [xyz or ?*] "
2379 Strcpy(obuf, short_oname(obj, doname, thesimpleoname,
2380 /* 128 - (24 + 54 + 1) leaves 49 for <object> */
2381 QBUFSZ - sizeof "What do you want to dip \
2382 into? [abdeghjkmnpqstvwyzBCEFHIKLNOQRTUWXZ#-# or ?*] "));
2384 here = levl[u.ux][u.uy].typ;
2385 /* Is there a fountain to dip into here? */
2386 if (IS_FOUNTAIN(here)) {
2388 Sprintf(qbuf, "%s%s into the fountain?", Dip_,
2389 flags.verbose ? obuf : shortestname);
2391 Sprintf(qbuf, "
\90ò
\82É%s
\81H", Dip_);
2393 /* "Dip <the object> into the fountain?" */
2394 if (yn(qbuf) == 'y') {
2398 } else if (is_pool(u.ux, u.uy)) {
2399 const char *pooltype = waterbody_name(u.ux, u.uy);
2402 Sprintf(qbuf, "%s%s into the %s?", Dip_,
2403 flags.verbose ? obuf : shortestname, pooltype);
2404 #else /*JP:
\89p
\8cê
\82Å
\82Í
\89½
\82ð
\90Z
\82·
\82©
\82ð
\8aÜ
\82ß
\82Ä
\82¢
\82é
\82ª
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82Ì
\93s
\8d\87\82Å
\82Æ
\82è
\82 \82¦
\82¸
\8fÈ
\97ª*/
2405 Sprintf(qbuf, "%s
\82É%s
\81H", pooltype, Dip_);
2407 /* "Dip <the object> into the {pool, moat, &c}?" */
2408 if (yn(qbuf) == 'y') {
2410 floating_above(pooltype);
2411 } else if (u.usteed && !is_swimmer(u.usteed->data)
2412 && P_SKILL(P_RIDING) < P_BASIC) {
2413 rider_cant_reach(); /* not skilled enough to reach */
2415 if (obj->otyp == POT_ACID)
2417 if (water_damage(obj, 0, TRUE) != ER_DESTROYED && obj->in_use)
2425 /* "What do you want to dip <the object> into? [xyz or ?*] " */
2426 Sprintf(qbuf, "dip %s into", flags.verbose ? obuf : shortestname);
2428 /* "What do you want to dip into? [xyz or ?*] " */
2429 Sprintf(qbuf, "dip into");
2431 potion = getobj(beverages, qbuf);
2434 if (potion == obj && potion->quan == 1L) {
2436 pline("That is a potion bottle, not a Klein bottle!");
2438 pline("
\82±
\82ê
\82Í
\96ò
\95r
\82¾
\81I
\83N
\83\89\83C
\83\93\82Ì
\92Ù
\82¶
\82á
\82È
\82¢
\81I");
2441 potion->in_use = TRUE; /* assume it will be used up */
2442 if (potion->otyp == POT_WATER) {
2443 boolean useeit = !Blind || (obj == ublindf && Blindfolded_only);
2445 const char *obj_glows = Yobjnam2(obj, "glow");
2447 const char *obj_glows = cxname(obj);
2450 if (H2Opotion_dip(potion, obj, useeit, obj_glows))
2452 } else if (obj->otyp == POT_POLYMORPH || potion->otyp == POT_POLYMORPH) {
2453 /* some objects can't be polymorphed */
2454 if (obj->otyp == potion->otyp /* both POT_POLY */
2455 || obj->otyp == WAN_POLYMORPH || obj->otyp == SPE_POLYMORPH
2456 || obj == uball || obj == uskin
2457 || obj_resists(obj->otyp == POT_POLYMORPH ? potion : obj,
2459 pline1(nothing_happens);
2461 boolean was_wep, was_swapwep, was_quiver;
2462 short save_otyp = obj->otyp;
2465 u.uconduct.polypiles++;
2467 was_wep = (obj == uwep);
2468 was_swapwep = (obj == uswapwep);
2469 was_quiver = (obj == uquiver);
2471 obj = poly_obj(obj, STRANGE_OBJECT);
2475 else if (was_swapwep)
2477 else if (was_quiver)
2480 if (obj->otyp != save_otyp) {
2481 makeknown(POT_POLYMORPH);
2483 prinv((char *) 0, obj, 0L);
2487 pline("Nothing seems to happen.");
2489 pline("
\89½
\82à
\8bN
\82±
\82ç
\82È
\82©
\82Á
\82½
\82æ
\82¤
\82¾
\81D");
2493 potion->in_use = FALSE; /* didn't go poof */
2495 } else if (obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) {
2496 int amt = (int) obj->quan;
2499 mixture = mixtype(obj, potion);
2501 magic = (mixture != STRANGE_OBJECT) ? objects[mixture].oc_magic
2502 : (objects[obj->otyp].oc_magic || objects[potion->otyp].oc_magic);
2504 Strcpy(qbuf, "The"); /* assume full stack */
2508 if (amt > (magic ? 3 : 7)) {
2509 /* trying to dip multiple potions will usually affect only a
2510 subset; pick an amount between 3 and 8, inclusive, for magic
2511 potion result, between 7 and N for non-magic */
2513 amt = rnd(min(amt, 8) - (3 - 1)) + (3 - 1); /* 1..6 + 2 */
2515 amt = rnd(amt - (7 - 1)) + (7 - 1); /* 1..(N-6) + 6 */
2517 if ((long) amt < obj->quan) {
2518 obj = splitobj(obj, (long) amt);
2520 Sprintf(qbuf, "%ld of the", obj->quan);
2522 Sprintf(qbuf, "%ld
\96{
\82Ì", obj->quan);
2526 /* [N of] the {obj(s)} mix(es) with [one of] {the potion}... */
2528 pline("%s %s %s with %s%s...", qbuf, simpleonames(obj),
2529 otense(obj, "mix"), (potion->quan > 1L) ? "one of " : "",
2530 thesimpleoname(potion));
2531 #else /* [N
\96{
\82Ì]{obj}
\82ð{the potion}[
\82Ì
\88ê
\82Â]
\82Æ
\8d¬
\82º
\82½
\81D
\81D
\81D */
2532 pline("%s%s
\82ð%s%s
\82Æ
\8d¬
\82º
\82½
\81D
\81D
\81D", qbuf, simpleonames(obj),
2533 thesimpleoname(potion),
2534 (potion->quan > 1L) ? "
\82Ì
\88ê
\82Â" : "");
2536 /* Mixing potions is dangerous...
2537 KMH, balance patch -- acid is particularly unstable */
2538 if (obj->cursed || obj->otyp == POT_ACID || !rn2(10)) {
2539 /* it would be better to use up the whole stack in advance
2540 of the message, but we can't because we need to keep it
2541 around for potionbreathe() [and we can't set obj->in_use
2542 to 'amt' because that's not implemented] */
2545 pline("BOOM! They explode!");
2547 pline("
\83o
\81[
\83\93\81I
\94\9a\94
\82µ
\82½
\81I");
2548 wake_nearto(u.ux, u.uy, (BOLT_LIM + 1) * (BOLT_LIM + 1));
2549 exercise(A_STR, FALSE);
2550 if (!breathless(youmonst.data) || haseyes(youmonst.data))
2554 losehp(amt + rnd(9), /* not physical damage */
2556 "alchemic blast", KILLED_BY_AN);
2558 "
\92²
\8d\87\82Ì
\8e¸
\94s
\82Å", KILLED_BY_AN);
2562 obj->blessed = obj->cursed = obj->bknown = 0;
2563 if (Blind || Hallucination)
2566 if (mixture != STRANGE_OBJECT) {
2567 obj->otyp = mixture;
2569 switch (obj->odiluted ? 1 : rnd(8)) {
2571 obj->otyp = POT_WATER;
2575 obj->otyp = POT_SICKNESS;
2578 struct obj *otmp = mkobj(POTION_CLASS, FALSE);
2580 obj->otyp = otmp->otyp;
2581 obfree(otmp, (struct obj *) 0);
2589 pline_The("mixture glows brightly and evaporates.");
2591 pline("
\8d¬
\82º
\82é
\82Æ
\96ò
\82Í
\96¾
\82é
\82
\8bP
\82«
\81C
\8fö
\94
\82µ
\82½
\81D");
2595 obj->odiluted = (obj->otyp != POT_WATER);
2597 if (obj->otyp == POT_WATER && !Hallucination) {
2599 pline_The("mixture bubbles%s.", Blind ? "" : ", then clears");
2601 pline("
\96ò
\82ð
\8d¬
\82º
\82é
\82Æ%s
\96A
\82¾
\82Á
\82½
\81D", Blind ? "" : "
\82µ
\82Î
\82ç
\82");
2602 } else if (!Blind) {
2604 pline_The("mixture looks %s.",
2606 pline("
\8d¬
\82º
\82½
\96ò
\82Í%s
\96ò
\82É
\8c©
\82¦
\82é
\81D",
2607 hcolor(OBJ_DESCR(objects[obj->otyp])));
2611 /* this is required when 'obj' was split off from a bigger stack,
2612 so that 'obj' will now be assigned its own inventory slot;
2613 it has a side-effect of merging 'obj' into another compatible
2614 stack if there is one, so we do it even when no split has
2615 been made in order to get the merge result for both cases;
2616 as a consequence, mixing while Fumbling drops the mixture */
2619 (void) hold_another_object(obj, "You drop %s!", doname(obj),
2622 (void) hold_another_object(obj, "%s
\82ð
\97\8e\82µ
\82½
\81I", doname(obj),
2628 if (potion->otyp == POT_ACID && obj->otyp == CORPSE
2629 && obj->corpsenm == PM_LICHEN && !Blind) {
2631 pline("%s %s %s around the edges.", The(cxname(obj)),
2632 otense(obj, "turn"),
2633 potion->odiluted ? hcolor(NH_ORANGE) : hcolor(NH_RED));
2635 pline("%s
\82Í
\82Ó
\82¿
\82ª%s
\82È
\82Á
\82½
\81D", The(cxname(obj)),
2636 jconj_adj(potion->odiluted ? hcolor(NH_ORANGE) : hcolor(NH_RED)));
2638 potion->in_use = FALSE; /* didn't go poof */
2642 if (potion->otyp == POT_WATER && obj->otyp == TOWEL) {
2644 pline_The("towel soaks it up!");
2646 pline_The("
\83^
\83I
\83\8b\82Í
\90\85\82ð
\8bz
\82¢
\8d\9e\82ñ
\82¾
\81I");
2647 /* wetting towel already done via water_damage() in H2Opotion_dip */
2651 if (is_poisonable(obj)) {
2652 if (potion->otyp == POT_SICKNESS && !obj->opoisoned) {
2655 if (potion->quan > 1L)
2657 Sprintf(buf, "One of %s", the(xname(potion)));
2659 Sprintf(buf, "%s
\82Ì
\88ê
\82Â", the(xname(potion)));
2661 Strcpy(buf, The(xname(potion)));
2663 pline("%s forms a coating on %s.", buf, the(xname(obj)));
2665 pline("%s
\82ª%s
\82É
\93h
\82ç
\82ê
\82½
\81D", buf, the(xname(obj)));
2666 obj->opoisoned = TRUE;
2668 } else if (obj->opoisoned && (potion->otyp == POT_HEALING
2669 || potion->otyp == POT_EXTRA_HEALING
2670 || potion->otyp == POT_FULL_HEALING)) {
2672 pline("A coating wears off %s.", the(xname(obj)));
2674 pline("
\93Å
\82ª%s
\82©
\82ç
\94\8d\82°
\82¨
\82¿
\82½
\81D", the(xname(obj)));
2680 if (potion->otyp == POT_ACID) {
2681 if (erode_obj(obj, 0, ERODE_CORRODE, EF_GREASE) != ER_NOTHING)
2685 if (potion->otyp == POT_OIL) {
2686 boolean wisx = FALSE;
2688 if (potion->lamplit) { /* burning */
2689 fire_damage(obj, TRUE, u.ux, u.uy);
2690 } else if (potion->cursed) {
2692 pline_The("potion spills and covers your %s with oil.",
2694 pline("
\96û
\82Í
\94ò
\82Ñ
\8eU
\82è
\82 \82È
\82½
\82Ì%s
\82É
\82©
\82©
\82Á
\82½
\81D",
2695 makeplural(body_part(FINGER)));
2696 incr_itimeout(&Glib, d(2, 10));
2697 } else if (obj->oclass != WEAPON_CLASS && !is_weptool(obj)) {
2698 /* the following cases apply only to weapons */
2700 /* Oil removes rust and corrosion, but doesn't unburn.
2701 * Arrows, etc are classed as metallic due to arrowhead
2702 * material, but dipping in oil shouldn't repair them.
2704 } else if ((!is_rustprone(obj) && !is_corrodeable(obj))
2705 || is_ammo(obj) || (!obj->oeroded && !obj->oeroded2)) {
2706 /* uses up potion, doesn't set obj->greased */
2708 pline("%s %s with an oily sheen.", Yname2(obj),
2709 otense(obj, "gleam"));
2711 pline("%s
\82Í
\96û
\82Ì
\8cõ
\91ò
\82Å
\82«
\82ç
\82è
\82Æ
\8cõ
\82Á
\82½
\81D", Yname2(obj));
2715 pline("%s %s less %s.", Yname2(obj), otense(obj, "are"),
2716 (obj->oeroded && obj->oeroded2)
2717 ? "corroded and rusty"
2718 : obj->oeroded ? "rusty" : "corroded");
2720 pline("%s
\82Ì%s
\82ª
\8eæ
\82ê
\82½
\81D", Yname2(obj),
2721 (obj->oeroded && obj->oeroded2)
2722 ? "
\95\85\90H
\82Æ
\8eK"
2723 : obj->oeroded ? "
\8eK" : "
\95\85\90H");
2725 if (obj->oeroded > 0)
2727 if (obj->oeroded2 > 0)
2731 exercise(A_WIS, wisx);
2732 makeknown(potion->otyp);
2738 /* Allow filling of MAGIC_LAMPs to prevent identification by player */
2739 if ((obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP)
2740 && (potion->otyp == POT_OIL)) {
2741 /* Turn off engine before fueling, turn off fuel too :-) */
2742 if (obj->lamplit || potion->lamplit) {
2744 explode(u.ux, u.uy, 11, d(6, 6), 0, EXPL_FIERY);
2745 exercise(A_WIS, FALSE);
2748 /* Adding oil to an empty magic lamp renders it into an oil lamp */
2749 if ((obj->otyp == MAGIC_LAMP) && obj->spe == 0) {
2750 obj->otyp = OIL_LAMP;
2753 if (obj->age > 1000L) {
2755 pline("%s %s full.", Yname2(obj), otense(obj, "are"));
2757 pline("%s
\82É
\82Í
\82½
\82Á
\82Õ
\82è
\93ü
\82Á
\82Ä
\82¢
\82é
\81D", Yname2(obj));
2758 potion->in_use = FALSE; /* didn't go poof */
2761 You("fill %s with oil.", yname(obj));
2763 You("%s
\82É
\96û
\82ð
\93ü
\82ê
\82½
\81D", yname(obj));
2764 check_unpaid(potion); /* Yendorian Fuel Tax */
2765 obj->age += 2 * potion->age; /* burns more efficiently */
2766 if (obj->age > 1500L)
2769 exercise(A_WIS, TRUE);
2777 potion->in_use = FALSE; /* didn't go poof */
2778 if ((obj->otyp == UNICORN_HORN || obj->otyp == AMETHYST)
2779 && (mixture = mixtype(obj, potion)) != STRANGE_OBJECT) {
2780 char oldbuf[BUFSZ], newbuf[BUFSZ];
2781 short old_otyp = potion->otyp;
2782 boolean old_dknown = FALSE;
2783 boolean more_than_one = potion->quan > 1L;
2786 if (potion->dknown) {
2789 Sprintf(oldbuf, "%s ", hcolor(OBJ_DESCR(objects[potion->otyp])));
2791 Sprintf(oldbuf, "%s", hcolor(OBJ_DESCR(objects[potion->otyp])));
2793 /* with multiple merged potions, split off one and
2795 if (potion->quan > 1L) {
2796 singlepotion = splitobj(potion, 1L);
2798 singlepotion = potion;
2800 costly_alteration(singlepotion, COST_NUTRLZ);
2801 singlepotion->otyp = mixture;
2802 singlepotion->blessed = 0;
2803 if (mixture == POT_WATER)
2804 singlepotion->cursed = singlepotion->odiluted = 0;
2806 singlepotion->cursed = obj->cursed; /* odiluted left as-is */
2807 singlepotion->bknown = FALSE;
2809 singlepotion->dknown = FALSE;
2811 singlepotion->dknown = !Hallucination;
2813 if (mixture == POT_WATER && singlepotion->dknown)
2814 Sprintf(newbuf, "clears");
2816 Sprintf(newbuf, "turns %s",
2817 hcolor(OBJ_DESCR(objects[mixture])));
2818 pline_The("%spotion%s %s.", oldbuf,
2819 more_than_one ? " that you dipped into" : "", newbuf);
2821 if (mixture == POT_WATER && singlepotion->dknown)
2822 Sprintf(newbuf, "
\93§
\96¾");
2824 Sprintf(newbuf, "%s
\96ò",
2825 hcolor(OBJ_DESCR(objects[mixture])));
2826 pline_The("%s%s
\96ò
\82Í%s
\82É
\82È
\82Á
\82½
\81D.", more_than_one ? "
\90Z
\82µ
\82½" : "",
2829 if (!objects[old_otyp].oc_uname
2830 && !objects[old_otyp].oc_name_known && old_dknown) {
2834 fakeobj.otyp = old_otyp;
2835 fakeobj.oclass = POTION_CLASS;
2839 obj_extract_self(singlepotion);
2842 hold_another_object(singlepotion, "You juggle and drop %s!",
2844 hold_another_object(singlepotion, "
\82¨
\8eè
\8bÊ
\82µ
\82Ä%s
\82ð
\97\8e\82Æ
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
2845 doname(singlepotion), (const char *) 0);
2851 pline("Interesting...");
2853 pline("
\96Ê
\94\92\82¢
\81D
\81D
\81D");
2857 if (!objects[potion->otyp].oc_name_known
2858 && !objects[potion->otyp].oc_uname)
2864 /* *monp grants a wish and then leaves the game */
2867 struct monst **monp;
2869 struct monst *mon = *monp;
2870 int mx = mon->mx, my = mon->my, glyph = glyph_at(mx, my);
2872 /* remove the monster first in case wish proves to be fatal
2873 (blasted by artifact), to keep it out of resulting bones file */
2875 *monp = 0; /* inform caller that monster is gone */
2876 /* hide that removal from player--map is visible during wish prompt */
2877 tmp_at(DISP_ALWAYS, glyph);
2879 /* grant the wish */
2882 tmp_at(DISP_END, 0);
2886 djinni_from_bottle(obj)
2892 if (!(mtmp = makemon(&mons[PM_DJINNI], u.ux, u.uy, NO_MM_FLAGS))) {
2894 pline("It turns out to be empty.");
2896 if (obj->otyp == MAGIC_LAMP) {
2897 pline("
\83\89\83\93\83v
\82Í
\8bó
\82Á
\82Û
\82¾
\82Á
\82½
\81D");
2899 pline("
\96ò
\82Í
\8bó
\82Á
\82Û
\82¾
\82Á
\82½
\81D");
2907 pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp));
2909 pline("
\89\8c\82Ì
\92\86\82©
\82ç
\81C%s
\82ª
\8c»
\82í
\82ê
\82½
\81I", a_monnam(mtmp));
2911 pline("%s speaks.", Monnam(mtmp));
2913 pline("%s
\82Í
\98b
\82µ
\82©
\82¯
\82½
\81D", Monnam(mtmp));
2916 You("smell acrid fumes.");
2918 You("
\83c
\83\93\82Æ
\82·
\82é
\93õ
\82¢
\82ª
\82µ
\82½
\81D");
2920 pline("%s speaks.", Something);
2922 pline("%s
\82ª
\98b
\82µ
\82©
\82¯
\82½
\81D", Something);
2927 chance = (chance == 4) ? rnd(4) : 0;
2928 else if (obj->cursed)
2929 chance = (chance == 0) ? rn2(4) : 4;
2930 /* 0,1,2,3,4: b=80%,5,5,5,5; nc=20%,20,20,20,20; c=5%,5,5,5,80 */
2935 verbalize("I am in your debt. I will grant one wish!");
2937 verbalize("
\82¨
\91O
\82É
\82Í
\8eØ
\82è
\82ª
\82Å
\82«
\82½
\81D
\88ê
\82Â
\8aè
\82¢
\82ð
\82©
\82È
\82¦
\82Ä
\82â
\82ë
\82¤
\81I");
2938 /* give a wish and discard the monster (mtmp set to null) */
2939 mongrantswish(&mtmp);
2943 verbalize("Thank you for freeing me!");
2945 verbalize("
\8e\84\82ð
\8f\95\82¯
\82Ä
\82
\82ê
\82½
\82±
\82Æ
\82ð
\8a´
\8eÓ
\82·
\82é
\81I");
2946 (void) tamedog(mtmp, (struct obj *) 0);
2950 verbalize("You freed me!");
2952 verbalize("
\89ð
\95ú
\82µ
\82Ä
\82
\82ê
\82½
\82Ì
\82Í
\82¨
\91O
\82©
\81I");
2953 mtmp->mpeaceful = TRUE;
2958 verbalize("It is about time!");
2960 verbalize("
\82³
\82ç
\82Î
\82¾
\81I");
2961 if (canspotmon(mtmp))
2963 pline("%s vanishes.", Monnam(mtmp));
2965 pline("%s
\82Í
\8fÁ
\82¦
\82½
\81D", Monnam(mtmp));
2970 verbalize("You disturbed me, fool!");
2972 verbalize("
\82¨
\82Ü
\82¦
\82Í
\8e\84\82Ì
\96°
\82è
\82ð
\96W
\82°
\82½
\81D
\82¨
\82ë
\82©
\82à
\82Ì
\82ß
\81I");
2973 mtmp->mpeaceful = FALSE;
2979 /* clone a gremlin or mold (2nd arg non-null implies heat as the trigger);
2980 hit points are cut in half (odd HP stays with original) */
2982 split_mon(mon, mtmp)
2983 struct monst *mon, /* monster being split */
2984 *mtmp; /* optional attacker whose heat triggered it */
2986 struct monst *mtmp2;
2992 Sprintf(reason, " from %s heat",
2993 (mtmp == &youmonst) ? the_your[1]
2994 : (const char *) s_suffix(mon_nam(mtmp)));
2996 Sprintf(reason, "%s
\82Ì
\94M
\82Å",
2997 (mtmp == &youmonst) ? the_your[1]
2998 : (const char *) mon_nam(mtmp));
3001 if (mon == &youmonst) {
3004 mtmp2->mhpmax = u.mhmax / 2;
3005 u.mhmax -= mtmp2->mhpmax;
3008 You("multiply%s!", reason);
3010 You("%s
\95ª
\97ô
\82µ
\82½
\81I", reason);
3013 mtmp2 = clone_mon(mon, 0, 0);
3015 mtmp2->mhpmax = mon->mhpmax / 2;
3016 mon->mhpmax -= mtmp2->mhpmax;
3017 if (canspotmon(mon))
3019 pline("%s multiplies%s!", Monnam(mon), reason);
3021 pline("%s
\82Í%s
\95ª
\97ô
\82µ
\82½
\81I", Monnam(mon), reason);