1 /* SCCS Id: @(#)read.c 3.4 2003/10/22 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
7 /* KMH -- Copied from pray.c; this really belongs in a header file */
11 #define Your_Own_Role(mndx) \
12 ((mndx) == urole.malenum || \
13 (urole.femalenum != NON_PM && (mndx) == urole.femalenum))
14 #define Your_Own_Race(mndx) \
15 ((mndx) == urace.malenum || \
16 (urace.femalenum != NON_PM && (mndx) == urace.femalenum))
22 static NEARDATA const char readable[] =
23 { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
24 static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
26 static void FDECL(wand_explode, (struct obj *));
27 static void NDECL(do_class_genocide);
28 static void FDECL(stripspe,(struct obj *));
29 static void FDECL(p_glow1,(struct obj *));
30 static void FDECL(p_glow2,(struct obj *,const char *));
31 static void FDECL(randomize,(int *, int));
32 static void FDECL(forget_single_object, (int));
33 static void FDECL(forget, (int));
34 static void FDECL(maybe_tame, (struct monst *,struct obj *));
36 STATIC_PTR void FDECL(set_lit, (int,int,genericptr_t));
41 register struct obj *scroll;
42 register boolean confused;
45 if(check_capacity((char *)0)) return (0);
46 scroll = getobj(readable, "read");
47 if(!scroll) return(0);
49 /* outrumor has its own blindness check */
50 if(scroll->otyp == FORTUNE_COOKIE) {
52 You("break up the cookie and throw away the pieces.");
53 outrumor(bcsign(scroll), BY_COOKIE);
54 if (!Blind) u.uconduct.literate++;
58 } else if (scroll->otyp == T_SHIRT) {
59 static const char *shirt_msgs[] = { /* Scott Bigham */
60 "I explored the Dungeons of Doom and all I got was this lousy T-shirt!",
61 "Is that Mjollnir in your pocket or are you just happy to see me?",
62 "It's not the size of your sword, it's how #enhance'd you are with it.",
63 "Madame Elvira's House O' Succubi Lifetime Customer",
64 "Madame Elvira's House O' Succubi Employee of the Month",
65 "Ludios Vault Guards Do It In Small, Dark Rooms",
66 "Yendor Military Soldiers Do It In Large Groups",
67 "I survived Yendor Military Boot Camp",
68 "Ludios Accounting School Intra-Mural Lacrosse Team",
69 "Oracle(TM) Fountains 10th Annual Wet T-Shirt Contest",
70 "Hey, black dragon! Disintegrate THIS!",
71 "I'm With Stupid -->",
72 "Don't blame me, I voted for Izchak!",
73 "Don't Panic", /* HHGTTG */
74 "Furinkan High School Athletic Dept.", /* Ranma 1/2 */
75 "Hel-LOOO, Nurse!", /* Animaniacs */
81 You_cant("feel any Braille writing.");
84 u.uconduct.literate++;
87 Strcpy(buf, shirt_msgs[scroll->o_id % SIZE(shirt_msgs)]);
88 erosion = greatest_erosion(scroll);
91 (int)(strlen(buf) * erosion / (2*MAX_ERODE)),
92 scroll->o_id ^ (unsigned)u.ubirthday);
96 } else if (scroll->oclass != SCROLL_CLASS
97 && scroll->oclass != SPBOOK_CLASS) {
98 pline(silly_thing_to, "read");
101 const char *what = 0;
102 if (scroll->oclass == SPBOOK_CLASS)
103 what = "mystic runes";
104 else if (!scroll->dknown)
105 what = "formula on the scroll";
107 pline("Being blind, you cannot read the %s.", what);
112 /* Actions required to win the game aren't counted towards conduct */
113 if (scroll->otyp != SPE_BOOK_OF_THE_DEAD &&
114 scroll->otyp != SPE_BLANK_PAPER &&
115 scroll->otyp != SCR_BLANK_PAPER)
116 u.uconduct.literate++;
118 confused = (Confusion != 0);
120 if (scroll->otyp == SCR_MAIL) confused = FALSE;
122 if(scroll->oclass == SPBOOK_CLASS) {
123 return(study_book(scroll));
125 scroll->in_use = TRUE; /* scroll, not spellbook, now being read */
126 if(scroll->otyp != SCR_BLANK_PAPER) {
128 pline("As you %s the formula on it, the scroll disappears.",
129 is_silent(youmonst.data) ? "cogitate" : "pronounce");
131 pline("As you read the scroll, it disappears.");
134 pline("Being so trippy, you screw up...");
136 pline("Being confused, you mis%s the magic words...",
137 is_silent(youmonst.data) ? "understand" : "pronounce");
140 if(!seffects(scroll)) {
141 if(!objects[scroll->otyp].oc_name_known) {
143 makeknown(scroll->otyp);
144 more_experienced(0,10);
145 } else if(!objects[scroll->otyp].oc_uname)
148 if(scroll->otyp != SCR_BLANK_PAPER)
150 else scroll->in_use = FALSE;
157 register struct obj *obj;
159 if (obj->blessed) pline(nothing_happens);
163 if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
165 Your("%s %s briefly.",xname(obj), otense(obj, "vibrate"));
166 } else pline(nothing_happens);
172 register struct obj *otmp;
174 Your("%s %s briefly.", xname(otmp),
175 otense(otmp, Blind ? "vibrate" : "glow"));
180 register struct obj *otmp;
181 register const char *color;
183 Your("%s %s%s%s for a moment.",
185 otense(otmp, Blind ? "vibrate" : "glow"),
187 Blind ? nul : hcolor(color));
190 /* Is the object chargeable? For purposes of inventory display; it is */
191 /* possible to be able to charge things for which this returns FALSE. */
196 if (obj->oclass == WAND_CLASS) return TRUE;
197 /* known && !uname is possible after amnesia/mind flayer */
198 if (obj->oclass == RING_CLASS)
199 return (boolean)(objects[obj->otyp].oc_charged &&
200 (obj->known || objects[obj->otyp].oc_uname));
201 if (is_weptool(obj)) /* specific check before general tools */
203 if (obj->oclass == TOOL_CLASS)
204 return (boolean)(objects[obj->otyp].oc_charged);
205 return FALSE; /* why are weapons/armor considered charged anyway? */
209 * recharge an object; curse_bless is -1 if the recharging implement
210 * was cursed, +1 if blessed, 0 otherwise.
213 recharge(obj, curse_bless)
218 boolean is_cursed, is_blessed;
220 is_cursed = curse_bless < 0;
221 is_blessed = curse_bless > 0;
223 if (obj->oclass == WAND_CLASS) {
224 /* undo any prior cancellation, even when is_cursed */
225 if (obj->spe == -1) obj->spe = 0;
228 * Recharging might cause wands to explode.
229 * v = number of previous recharges
230 * v = percentage chance to explode on this attempt
231 * v = cumulative odds for exploding
241 n = (int)obj->recharged;
242 if (n > 0 && (obj->otyp == WAN_WISHING ||
243 (n * n * n > rn2(7*7*7)))) { /* recharge_limit */
247 /* didn't explode, so increment the recharge count */
248 obj->recharged = (unsigned)(n + 1);
250 /* now handle the actual recharging */
254 int lim = (obj->otyp == WAN_WISHING) ? 3 :
255 (objects[obj->otyp].oc_dir != NODIR) ? 8 : 15;
257 n = (lim == 3) ? 3 : rn1(5, lim + 1 - 5);
258 if (!is_blessed) n = rnd(n);
260 if (obj->spe < n) obj->spe = n;
262 if (obj->otyp == WAN_WISHING && obj->spe > 3) {
266 if (obj->spe >= lim) p_glow2(obj, NH_BLUE);
270 } else if (obj->oclass == RING_CLASS &&
271 objects[obj->otyp].oc_charged) {
272 /* charging does not affect ring's curse/bless status */
273 int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
274 boolean is_on = (obj == uleft || obj == uright);
276 /* destruction depends on current state, not adjustment */
277 if (obj->spe > rn2(7) || obj->spe <= -5) {
278 Your("%s %s momentarily, then %s!",
279 xname(obj), otense(obj,"pulsate"), otense(obj,"explode"));
280 if (is_on) Ring_gone(obj);
281 s = rnd(3 * abs(obj->spe)); /* amount of damage */
283 losehp(s, "exploding ring", KILLED_BY_AN);
285 long mask = is_on ? (obj == uleft ? LEFT_RING :
287 Your("%s spins %sclockwise for a moment.",
288 xname(obj), s < 0 ? "counter" : "");
289 /* cause attributes and/or properties to be updated */
290 if (is_on) Ring_off(obj);
291 obj->spe += s; /* update the ring while it's off */
292 if (is_on) setworn(obj, mask), Ring_on(obj);
293 /* oartifact: if a touch-sensitive artifact ring is
294 ever created the above will need to be revised */
297 } else if (obj->oclass == TOOL_CLASS) {
298 int rechrg = (int)obj->recharged;
300 if (objects[obj->otyp].oc_charged) {
301 /* tools don't have a limit, but the counter used does */
302 if (rechrg < 7) /* recharge_limit */
306 case BELL_OF_OPENING:
307 if (is_cursed) stripspe(obj);
308 else if (is_blessed) obj->spe += rnd(3);
310 if (obj->spe > 5) obj->spe = 5;
315 case EXPENSIVE_CAMERA:
317 if (is_cursed) stripspe(obj);
318 else if (rechrg && obj->otyp == MAGIC_MARKER) { /* previously recharged */
319 obj->recharged = 1; /* override increment done above */
321 Your("marker seems permanently dried out.");
323 pline(nothing_happens);
324 } else if (is_blessed) {
325 n = rn1(16,15); /* 15..30 */
326 if (obj->spe + n <= 50)
328 else if (obj->spe + n <= 75)
331 int chrg = (int)obj->spe;
332 if ((chrg + n) > 127)
337 p_glow2(obj, NH_BLUE);
339 n = rn1(11,10); /* 10..20 */
340 if (obj->spe + n <= 50)
343 int chrg = (int)obj->spe;
344 if ((chrg + n) > 127)
349 p_glow2(obj, NH_WHITE);
358 pline("%s out!", Tobjnam(obj, "go"));
361 } else if (is_blessed) {
364 p_glow2(obj, NH_BLUE);
368 if (obj->age > 1500) obj->age = 1500;
373 if (is_cursed) stripspe(obj);
374 else if (is_blessed) {
376 p_glow2(obj, NH_BLUE);
381 } else pline(nothing_happens);
387 if (is_cursed) stripspe(obj);
388 else if (is_blessed) {
390 obj->spe += rn1(10, 6);
391 else obj->spe += rn1(5, 6);
392 if (obj->spe > 50) obj->spe = 50;
393 p_glow2(obj, NH_BLUE);
396 if (obj->spe > 50) obj->spe = 50;
404 case DRUM_OF_EARTHQUAKE:
407 } else if (is_blessed) {
409 if (obj->spe > 20) obj->spe = 20;
410 p_glow2(obj, NH_BLUE);
413 if (obj->spe > 20) obj->spe = 20;
425 You("have a feeling of loss.");
430 /* Forget known information about this object class. */
432 forget_single_object(obj_id)
435 objects[obj_id].oc_name_known = 0;
436 objects[obj_id].oc_pre_discovered = 0; /* a discovery when relearned */
437 if (objects[obj_id].oc_uname) {
438 free((genericptr_t)objects[obj_id].oc_uname);
439 objects[obj_id].oc_uname = 0;
441 undiscover_object(obj_id); /* after clearing oc_name_known */
443 /* clear & free object names from matching inventory items too? */
447 #if 0 /* here if anyone wants it.... */
448 /* Forget everything known about a particular object class. */
450 forget_objclass(oclass)
455 for (i=bases[oclass];
456 i < NUM_OBJECTS && objects[i].oc_class==oclass; i++)
457 forget_single_object(i);
462 /* randomize the given list of numbers 0 <= i < count */
464 randomize(indices, count)
470 for (i = count - 1; i > 0; i--) {
471 if ((iswap = rn2(i + 1)) == i) continue;
473 indices[i] = indices[iswap];
474 indices[iswap] = temp;
479 /* Forget % of known objects. */
481 forget_objects(percent)
485 int indices[NUM_OBJECTS];
487 if (percent == 0) return;
488 if (percent <= 0 || percent > 100) {
489 impossible("forget_objects: bad percent %d", percent);
493 for (count = 0, i = 1; i < NUM_OBJECTS; i++)
494 if (OBJ_DESCR(objects[i]) &&
495 (objects[i].oc_name_known || objects[i].oc_uname))
496 indices[count++] = i;
498 randomize(indices, count);
500 /* forget first % of randomized indices */
501 count = ((count * percent) + 50) / 100;
502 for (i = 0; i < count; i++)
503 forget_single_object(indices[i]);
507 /* Forget some or all of map (depends on parameters). */
514 if (In_sokoban(&u.uz))
518 for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
519 if (howmuch & ALL_MAP || rn2(7)) {
520 /* Zonk all memory of this location. */
521 levl[zx][zy].seenv = 0;
522 levl[zx][zy].waslit = 0;
523 levl[zx][zy].glyph = cmap_to_glyph(S_stone);
527 /* Forget all traps on the level. */
531 register struct trap *trap;
533 /* forget all traps (except the one the hero is in :-) */
534 for (trap = ftrap; trap; trap = trap->ntrap)
535 if ((trap->tx != u.ux || trap->ty != u.uy) && (trap->ttyp != HOLE))
540 * Forget given % of all levels that the hero has visited and not forgotten,
544 forget_levels(percent)
548 xchar maxl, this_lev;
549 int indices[MAXLINFO];
551 if (percent == 0) return;
553 if (percent <= 0 || percent > 100) {
554 impossible("forget_levels: bad percent %d", percent);
558 this_lev = ledger_no(&u.uz);
559 maxl = maxledgerno();
561 /* count & save indices of non-forgotten visited levels */
562 /* Sokoban levels are pre-mapped for the player, and should stay
563 * so, or they become nearly impossible to solve. But try to
564 * shift the forgetting elsewhere by fiddling with percent
565 * instead of forgetting fewer levels.
567 for (count = 0, i = 0; i <= maxl; i++)
568 if ((level_info[i].flags & VISITED) &&
569 !(level_info[i].flags & FORGOTTEN) && i != this_lev) {
570 if (ledger_to_dnum(i) == sokoban_dnum)
573 indices[count++] = i;
576 if (percent > 100) percent = 100;
578 randomize(indices, count);
580 /* forget first % of randomized indices */
581 count = ((count * percent) + 50) / 100;
582 for (i = 0; i < count; i++) {
583 level_info[indices[i]].flags |= FORGOTTEN;
588 * Forget some things (e.g. after reading a scroll of amnesia). When called,
589 * the following are always forgotten:
591 * - felt ball & chain
593 * - part (6 out of 7) of the map
595 * Other things are subject to flags:
597 * howmuch & ALL_MAP = forget whole map
598 * howmuch & ALL_SPELLS = forget all spells
605 if (Punished) u.bc_felt = 0; /* forget felt ball&chain */
610 /* 1 in 3 chance of forgetting some levels */
611 if (!rn2(3)) forget_levels(rn2(25));
613 /* 1 in 3 chance of forgeting some objects */
614 if (!rn2(3)) forget_objects(rn2(25));
616 if (howmuch & ALL_SPELLS) losespells();
618 * Make sure that what was seen is restored correctly. To do this,
619 * we need to go blind for an instant --- turn off the display,
620 * then restart it. All this work is needed to correctly handle
621 * walls which are stone on one side and wall on the other. Turning
622 * off the seen bits above will make the wall revert to stone, but
623 * there are cases where we don't want this to happen. The easiest
624 * thing to do is to run it through the vision system again, which
627 docrt(); /* this correctly will reset vision */
630 /* monster is hit by scroll of taming's effect */
632 maybe_tame(mtmp, sobj)
640 make_happy_shk(mtmp, FALSE);
641 else if (!resist(mtmp, sobj->oclass, 0, NOTELL))
642 (void) tamedog(mtmp, (struct obj *) 0);
648 register struct obj *sobj;
651 register boolean confused = (Confusion != 0);
652 register struct obj *otmp;
654 if (objects[sobj->otyp].oc_magic)
655 exercise(A_WIS, TRUE); /* just for trying */
661 pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
662 /* note to the puzzled: the game Larn actually sends you junk
668 case SCR_ENCHANT_ARMOR:
671 boolean special_armor;
674 otmp = some_armor(&youmonst);
676 strange_feeling(sobj,
677 !Blind ? "Your skin glows then fades." :
678 "Your skin feels warm for a moment.");
679 exercise(A_CON, !sobj->cursed);
680 exercise(A_STR, !sobj->cursed);
684 otmp->oerodeproof = !(sobj->cursed);
686 otmp->rknown = FALSE;
687 Your("%s %s warm for a moment.",
688 xname(otmp), otense(otmp, "feel"));
691 Your("%s %s covered by a %s %s %s!",
692 xname(otmp), otense(otmp, "are"),
693 sobj->cursed ? "mottled" : "shimmering",
694 hcolor(sobj->cursed ? NH_BLACK : NH_GOLDEN),
695 sobj->cursed ? "glow" :
696 (is_shield(otmp) ? "layer" : "shield"));
698 if (otmp->oerodeproof &&
699 (otmp->oeroded || otmp->oeroded2)) {
700 otmp->oeroded = otmp->oeroded2 = 0;
701 Your("%s %s as good as new!",
703 otense(otmp, Blind ? "feel" : "look"));
707 /* elven armor vibrates warningly when enchanted beyond a limit */
708 special_armor = is_elven_armor(otmp) ||
709 (Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM);
712 (otmp->otyp == BLACK_DRAGON_SCALE_MAIL ||
713 otmp->otyp == BLACK_DRAGON_SCALES);
716 (otmp->otyp == SILVER_DRAGON_SCALE_MAIL ||
717 otmp->otyp == SILVER_DRAGON_SCALES ||
718 otmp->otyp == SHIELD_OF_REFLECTION);
719 if (Blind) same_color = FALSE;
721 /* KMH -- catch underflow */
722 s = sobj->cursed ? -otmp->spe : otmp->spe;
723 if (s > (special_armor ? 5 : 3) && rn2(s)) {
724 Your("%s violently %s%s%s for a while, then %s.",
726 otense(otmp, Blind ? "vibrate" : "glow"),
727 (!Blind && !same_color) ? " " : nul,
728 (Blind || same_color) ? nul :
729 hcolor(sobj->cursed ? NH_BLACK : NH_SILVER),
730 otense(otmp, "evaporate"));
731 if(is_cloak(otmp)) (void) Cloak_off();
732 if(is_boots(otmp)) (void) Boots_off();
733 if(is_helmet(otmp)) (void) Helmet_off();
734 if(is_gloves(otmp)) (void) Gloves_off();
735 if(is_shield(otmp)) (void) Shield_off();
736 if(otmp == uarm) (void) Armor_gone();
740 s = sobj->cursed ? -1 :
741 otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
742 sobj->blessed ? rnd(3-otmp->spe/3) : 1;
743 if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&
744 otmp->otyp <= YELLOW_DRAGON_SCALES) {
745 /* dragon scales get turned into dragon scale mail */
746 Your("%s merges and hardens!", xname(otmp));
747 setworn((struct obj *)0, W_ARM);
748 /* assumes same order */
749 otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
750 otmp->otyp - GRAY_DRAGON_SCALES;
757 setworn(otmp, W_ARM);
760 Your("%s %s%s%s%s for a %s.",
762 s == 0 ? "violently " : nul,
763 otense(otmp, Blind ? "vibrate" : "glow"),
764 (!Blind && !same_color) ? " " : nul,
765 (Blind || same_color) ? nul : hcolor(sobj->cursed ? NH_BLACK : NH_SILVER),
766 (s*s>1) ? "while" : "moment");
767 otmp->cursed = sobj->cursed;
768 if (!otmp->blessed || sobj->cursed)
769 otmp->blessed = sobj->blessed;
776 if ((otmp->spe > (special_armor ? 5 : 3)) &&
777 (special_armor || !rn2(7)))
778 Your("%s suddenly %s %s.",
779 xname(otmp), otense(otmp, "vibrate"),
780 Blind ? "again" : "unexpectedly");
783 case SCR_DESTROY_ARMOR:
785 otmp = some_armor(&youmonst);
788 strange_feeling(sobj,"Your bones itch.");
789 exercise(A_STR, FALSE);
790 exercise(A_CON, FALSE);
793 otmp->oerodeproof = sobj->cursed;
794 p_glow2(otmp, NH_PURPLE);
797 if(!sobj->cursed || !otmp || !otmp->cursed) {
798 if(!destroy_arm(otmp)) {
799 strange_feeling(sobj,"Your skin itches.");
800 exercise(A_STR, FALSE);
801 exercise(A_CON, FALSE);
805 } else { /* armor and scroll both cursed */
806 Your("%s %s.", xname(otmp), otense(otmp, "vibrate"));
807 if (otmp->spe >= -6) otmp->spe--;
808 make_stunned(HStun + rn1(10, 10), TRUE);
812 case SCR_CONFUSE_MONSTER:
813 case SPE_CONFUSE_MONSTER:
814 if(youmonst.data->mlet != S_HUMAN || sobj->cursed) {
815 if(!HConfusion) You_feel("confused.");
816 make_confused(HConfusion + rnd(100),FALSE);
817 } else if(confused) {
819 Your("%s begin to %s%s.",
820 makeplural(body_part(HAND)),
821 Blind ? "tingle" : "glow ",
822 Blind ? nul : hcolor(NH_PURPLE));
823 make_confused(HConfusion + rnd(100),FALSE);
825 pline("A %s%s surrounds your %s.",
826 Blind ? nul : hcolor(NH_RED),
827 Blind ? "faint buzz" : " glow",
829 make_confused(0L,TRUE);
832 if (!sobj->blessed) {
834 makeplural(body_part(HAND)),
835 Blind ? "" : " begin to glow",
836 Blind ? (const char *)"tingle" : hcolor(NH_RED),
837 u.umconf ? " even more" : "");
841 Your("%s tingle %s sharply.",
842 makeplural(body_part(HAND)),
843 u.umconf ? "even more" : "very");
845 Your("%s glow a%s brilliant %s.",
846 makeplural(body_part(HAND)),
847 u.umconf ? "n even more" : "",
849 /* after a while, repeated uses become less effective */
853 u.umconf += rn1(8, 2);
857 case SCR_SCARE_MONSTER:
859 { register int ct = 0;
860 register struct monst *mtmp;
862 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
863 if (DEADMONSTER(mtmp)) continue;
864 if(cansee(mtmp->mx,mtmp->my)) {
865 if(confused || sobj->cursed) {
866 mtmp->mflee = mtmp->mfrozen = mtmp->msleeping = 0;
869 if (! resist(mtmp, sobj->oclass, 0, NOTELL))
870 monflee(mtmp, 0, FALSE, FALSE);
871 if(!mtmp->mtame) ct++; /* pets don't laugh at you */
875 You_hear("%s in the distance.",
876 (confused || sobj->cursed) ? "sad wailing" :
877 "maniacal laughter");
878 else if(sobj->otyp == SCR_SCARE_MONSTER)
879 You_hear("%s close by.",
880 (confused || sobj->cursed) ? "sad wailing" :
881 "maniacal laughter");
884 case SCR_BLANK_PAPER:
886 You("don't remember there being any magic words on this scroll.");
888 pline("This scroll seems to be blank.");
891 case SCR_REMOVE_CURSE:
892 case SPE_REMOVE_CURSE:
893 { register struct obj *obj;
896 You_feel("the power of the Force against you!");
898 You_feel("like you need some help.");
901 You_feel("in touch with the Universal Oneness.");
903 You_feel("like someone is helping you.");
906 pline_The("scroll disintegrates.");
908 for (obj = invent; obj; obj = obj->nobj) {
911 /* gold isn't subject to cursing and blessing */
912 if (obj->oclass == COIN_CLASS) continue;
914 wornmask = (obj->owornmask & ~(W_BALL|W_ART|W_ARTI));
915 if (wornmask && !sobj->blessed) {
916 /* handle a couple of special cases; we don't
917 allow auxiliary weapon slots to be used to
918 artificially increase number of worn items */
919 if (obj == uswapwep) {
920 if (!u.twoweap) wornmask = 0L;
921 } else if (obj == uquiver) {
922 if (obj->oclass == WEAPON_CLASS) {
923 /* mergeable weapon test covers ammo,
924 missiles, spears, daggers & knives */
925 if (!objects[obj->otyp].oc_merge)
927 } else if (obj->oclass == GEM_CLASS) {
928 /* possibly ought to check whether
929 alternate weapon is a sling... */
930 if (!uslinging()) wornmask = 0L;
932 /* weptools don't merge and aren't
933 reasonable quivered weapons */
938 if (sobj->blessed || wornmask ||
939 obj->otyp == LOADSTONE ||
940 (obj->otyp == LEASH && obj->leashmon)) {
941 if(confused) blessorcurse(obj, 2);
946 if(Punished && !confused) unpunish();
950 case SCR_CREATE_MONSTER:
951 case SPE_CREATE_MONSTER:
952 if (create_critters(1 + ((confused || sobj->cursed) ? 12 : 0) +
953 ((sobj->blessed || rn2(73)) ? 0 : rnd(4)),
954 confused ? &mons[PM_ACID_BLOB] : (struct permonst *)0))
956 /* no need to flush monsters; we ask for identification only if the
957 * monsters are not visible
960 case SCR_ENCHANT_WEAPON:
961 if(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
963 /* oclass check added 10/25/86 GAN */
964 uwep->oerodeproof = !(sobj->cursed);
966 uwep->rknown = FALSE;
967 Your("weapon feels warm for a moment.");
970 Your("%s covered by a %s %s %s!",
971 aobjnam(uwep, "are"),
972 sobj->cursed ? "mottled" : "shimmering",
973 hcolor(sobj->cursed ? NH_PURPLE : NH_GOLDEN),
974 sobj->cursed ? "glow" : "shield");
976 if (uwep->oerodeproof && (uwep->oeroded || uwep->oeroded2)) {
977 uwep->oeroded = uwep->oeroded2 = 0;
978 Your("%s as good as new!",
979 aobjnam(uwep, Blind ? "feel" : "look"));
981 } else return !chwepon(sobj,
984 uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
985 sobj->blessed ? rnd(3-uwep->spe/3) : 1);
988 case SPE_CHARM_MONSTER:
990 maybe_tame(u.ustuck, sobj);
992 int i, j, bd = confused ? 5 : 1;
995 for (i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) {
996 if (!isok(u.ux + i, u.uy + j)) continue;
997 if ((mtmp = m_at(u.ux + i, u.uy + j)) != 0)
998 maybe_tame(mtmp, sobj);
1003 You("have found a scroll of genocide!");
1005 if (sobj->blessed) do_class_genocide();
1006 else do_genocide(!sobj->cursed | (2 * !!Confusion));
1009 if(!Blind) known = TRUE;
1010 litroom(!confused && !sobj->cursed, sobj);
1012 case SCR_TELEPORTATION:
1013 if(confused || sobj->cursed) level_tele();
1015 if (sobj->blessed && !Teleport_control) {
1017 if (yn("Do you wish to teleport?")=='n')
1021 if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
1022 (distu(u.ux0, u.uy0) >= 16))
1026 case SCR_GOLD_DETECTION:
1027 if (confused || sobj->cursed) return(trap_detect(sobj));
1028 else return(gold_detect(sobj));
1029 case SCR_FOOD_DETECTION:
1030 case SPE_DETECT_FOOD:
1031 if (food_detect(sobj))
1032 return(1); /* nothing detected */
1040 You("identify this as an identify scroll.");
1042 pline("This is an identify scroll.");
1043 if (sobj->blessed || (!sobj->cursed && !rn2(5))) {
1045 /* Note: if rn2(5)==0, identify all items */
1046 if (cval == 1 && sobj->blessed && Luck > 0) ++cval;
1048 if(!objects[sobj->otyp].oc_name_known) more_experienced(0,10);
1050 makeknown(SCR_IDENTIFY);
1052 if(invent && !confused) {
1053 identify_pack(cval);
1058 You_feel("charged up!");
1059 if (u.uen < u.uenmax)
1062 u.uen = (u.uenmax += d(5,4));
1067 pline("This is a charging scroll.");
1068 otmp = getobj(all_count, "charge");
1070 recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
1072 case SCR_MAGIC_MAPPING:
1073 if (level.flags.nommap) {
1074 Your("mind is filled with crazy lines!");
1076 pline("Wow! Modern art.");
1078 Your("%s spins in bewilderment.", body_part(HEAD));
1079 make_confused(HConfusion + rnd(30), FALSE);
1082 if (sobj->blessed) {
1085 for (x = 1; x < COLNO; x++)
1086 for (y = 0; y < ROWNO; y++)
1087 if (levl[x][y].typ == SDOOR)
1088 cvt_sdoor_to_door(&levl[x][y]);
1089 /* do_mapping() already reveals secret passages */
1092 case SPE_MAGIC_MAPPING:
1093 if (level.flags.nommap) {
1094 Your("%s spins as %s blocks the spell!", body_part(HEAD), something);
1095 make_confused(HConfusion + rnd(30), FALSE);
1098 pline("A map coalesces in your mind!");
1099 cval = (sobj->cursed && !confused);
1100 if(cval) HConfusion = 1; /* to screw up map */
1103 HConfusion = 0; /* restore */
1104 pline("Unfortunately, you can't grasp the details.");
1109 forget( (!sobj->blessed ? ALL_SPELLS : 0) |
1110 (!confused || sobj->cursed ? ALL_MAP : 0) );
1111 if (Hallucination) /* Ommmmmm! */
1112 Your("mind releases itself from mundane concerns.");
1113 else if (!strncmpi(plname, "Maud", 4))
1114 pline("As your mind turns inward on itself, you forget everything else.");
1116 pline("Who was that Maud person anyway?");
1118 pline("Thinking of Maud you forget everything else.");
1119 exercise(A_WIS, FALSE);
1123 * Note: Modifications have been made as of 3.0 to allow for
1124 * some damage under all potential cases.
1126 cval = bcsign(sobj);
1127 if(!objects[sobj->otyp].oc_name_known) more_experienced(0,10);
1129 makeknown(SCR_FIRE);
1131 if(Fire_resistance) {
1132 shieldeff(u.ux, u.uy);
1134 pline("Oh, look, what a pretty fire in your %s.",
1135 makeplural(body_part(HAND)));
1136 else You_feel("a pleasant warmth in your %s.",
1137 makeplural(body_part(HAND)));
1139 pline_The("scroll catches fire and you burn your %s.",
1140 makeplural(body_part(HAND)));
1141 losehp(1, "scroll of fire", KILLED_BY_AN);
1146 pline_The("water around you vaporizes violently!");
1148 pline_The("scroll erupts in a tower of flame!");
1151 explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,
1152 SCROLL_CLASS, EXPL_FIERY);
1155 /* TODO: handle steeds */
1157 #ifdef REINCARNATION
1158 !Is_rogue_level(&u.uz) &&
1160 (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) {
1163 /* Identify the scroll */
1164 pline_The("%s rumbles %s you!", ceiling(u.ux,u.uy),
1165 sobj->blessed ? "around" : "above");
1167 if (In_sokoban(&u.uz))
1168 change_luck(-1); /* Sokoban guilt */
1170 /* Loop through the surrounding squares */
1171 if (!sobj->cursed) for (x = u.ux-1; x <= u.ux+1; x++) {
1172 for (y = u.uy-1; y <= u.uy+1; y++) {
1174 /* Is this a suitable spot? */
1175 if (isok(x, y) && !closed_door(x, y) &&
1176 !IS_ROCK(levl[x][y].typ) &&
1177 !IS_AIR(levl[x][y].typ) &&
1178 (x != u.ux || y != u.uy)) {
1179 register struct obj *otmp2;
1180 register struct monst *mtmp;
1182 /* Make the object(s) */
1183 otmp2 = mksobj(confused ? ROCK : BOULDER,
1185 if (!otmp2) continue; /* Shouldn't happen */
1186 otmp2->quan = confused ? rn1(5,2) : 1;
1187 otmp2->owt = weight(otmp2);
1189 /* Find the monster here (won't be player) */
1191 if (mtmp && !amorphous(mtmp->data) &&
1192 !passes_walls(mtmp->data) &&
1193 !noncorporeal(mtmp->data) &&
1194 !unsolid(mtmp->data)) {
1195 struct obj *helmet = which_armor(mtmp, W_ARMH);
1198 if (cansee(mtmp->mx, mtmp->my)) {
1199 pline("%s is hit by %s!", Monnam(mtmp),
1201 if (mtmp->minvis && !canspotmon(mtmp))
1202 map_invisible(mtmp->mx, mtmp->my);
1204 mdmg = dmgval(otmp2, mtmp) * otmp2->quan;
1206 if(is_metallic(helmet)) {
1207 if (canspotmon(mtmp))
1208 pline("Fortunately, %s is wearing a hard helmet.", mon_nam(mtmp));
1209 else if (flags.soundok)
1210 You_hear("a clanging sound.");
1211 if (mdmg > 2) mdmg = 2;
1213 if (canspotmon(mtmp))
1214 pline("%s's %s does not protect %s.",
1215 Monnam(mtmp), xname(helmet),
1223 /* Drop the rock/boulder to the floor */
1224 if (!flooreffects(otmp2, x, y, "fall")) {
1225 place_object(otmp2, x, y);
1227 newsym(x, y); /* map the rock */
1232 /* Attack the player */
1233 if (!sobj->blessed) {
1237 /* Okay, _you_ write this without repeating the code */
1238 otmp2 = mksobj(confused ? ROCK : BOULDER,
1241 otmp2->quan = confused ? rn1(5,2) : 1;
1242 otmp2->owt = weight(otmp2);
1243 if (!amorphous(youmonst.data) &&
1245 !noncorporeal(youmonst.data) &&
1246 !unsolid(youmonst.data)) {
1247 You("are hit by %s!", doname(otmp2));
1248 dmg = dmgval(otmp2, &youmonst) * otmp2->quan;
1249 if (uarmh && !sobj->cursed) {
1250 if(is_metallic(uarmh)) {
1251 pline("Fortunately, you are wearing a hard helmet.");
1252 if (dmg > 2) dmg = 2;
1253 } else if (flags.verbose) {
1254 Your("%s does not protect you.",
1260 /* Must be before the losehp(), for bones files */
1261 if (!flooreffects(otmp2, u.ux, u.uy, "fall")) {
1262 place_object(otmp2, u.ux, u.uy);
1266 if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN);
1270 case SCR_PUNISHMENT:
1272 if(confused || sobj->blessed) {
1273 You_feel("guilty.");
1278 case SCR_STINKING_CLOUD: {
1281 You("have found a scroll of stinking cloud!");
1283 pline("Where do you want to center the cloud?");
1286 if (getpos(&cc, TRUE, "the desired position") < 0) {
1290 if (!cansee(cc.x, cc.y) || distu(cc.x, cc.y) >= 32) {
1291 You("smell rotten eggs.");
1294 (void) create_gas_cloud(cc.x, cc.y, 3+bcsign(sobj),
1299 impossible("What weird effect is this? (%u)", sobj->otyp);
1306 register struct obj *obj;
1308 obj->in_use = TRUE; /* in case losehp() is fatal */
1309 Your("%s vibrates violently, and explodes!",xname(obj));
1311 losehp(rnd(2*(u.uhpmax+1)/3), "exploding wand", KILLED_BY_AN);
1313 exercise(A_STR, FALSE);
1317 * Low-level lit-field update routine.
1328 snuff_light_source(x, y);
1334 register boolean on;
1337 char is_lit; /* value is irrelevant; we use its address
1338 as a `not null' flag for set_lit() */
1340 /* first produce the text (provided you're not blind) */
1342 register struct obj *otmp;
1346 pline("It seems even darker in here than before.");
1349 if (uwep && artifact_light(uwep) && uwep->lamplit)
1350 pline("Suddenly, the only light left comes from %s!",
1353 You("are surrounded by darkness!");
1356 /* the magic douses lamps, et al, too */
1357 for(otmp = invent; otmp; otmp = otmp->nobj)
1359 (void) snuff_lit(otmp);
1360 if (Blind) goto do_it;
1362 if (Blind) goto do_it;
1364 if (is_animal(u.ustuck->data))
1365 pline("%s %s is lit.",
1366 s_suffix(Monnam(u.ustuck)),
1367 mbodypart(u.ustuck, STOMACH));
1369 if (is_whirly(u.ustuck->data))
1370 pline("%s shines briefly.",
1373 pline("%s glistens.", Monnam(u.ustuck));
1376 pline("A lit field surrounds you!");
1380 /* No-op in water - can only see the adjacent squares and that's it! */
1381 if (Underwater || Is_waterlevel(&u.uz)) return;
1383 * If we are darkening the room and the hero is punished but not
1384 * blind, then we have to pick up and replace the ball and chain so
1385 * that we don't remember them if they are out of sight.
1387 if (Punished && !on && !Blind)
1388 move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
1390 #ifdef REINCARNATION
1391 if (Is_rogue_level(&u.uz)) {
1392 /* Can't use do_clear_area because MAX_RADIUS is too small */
1393 /* rogue lighting must light the entire room */
1394 int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
1397 for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++)
1398 for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++)
1400 (genericptr_t)(on ? &is_lit : (char *)0));
1401 rooms[rnum].rlit = on;
1403 /* hallways remain dark on the rogue level */
1406 do_clear_area(u.ux,u.uy,
1407 (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,
1408 set_lit, (genericptr_t)(on ? &is_lit : (char *)0));
1411 * If we are not blind, then force a redraw on all positions in sight
1412 * by temporarily blinding the hero. The vision recalculation will
1413 * correctly update all previously seen positions *and* correctly
1414 * set the waslit bit [could be messed up from above].
1419 /* replace ball&chain */
1420 if (Punished && !on)
1421 move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
1424 vision_full_recalc = 1; /* delayed vision recalculation */
1430 int i, j, immunecnt, gonecnt, goodcnt, class, feel_dead = 0;
1432 boolean gameover = FALSE; /* true iff killed self */
1436 pline(thats_enough_tries);
1440 getlin("What class of monsters do you wish to genocide?",
1442 (void)mungspaces(buf);
1443 } while (buf[0]=='\033' || !buf[0]);
1444 /* choosing "none" preserves genocideless conduct */
1445 if (!strcmpi(buf, "none") ||
1446 !strcmpi(buf, "nothing")) return;
1448 if (strlen(buf) == 1) {
1449 if (buf[0] == ILLOBJ_SYM)
1450 buf[0] = def_monsyms[S_MIMIC];
1451 class = def_char_to_monclass(buf[0]);
1456 Strcpy(buf2, makesingular(buf));
1459 immunecnt = gonecnt = goodcnt = 0;
1460 for (i = LOW_PM; i < NUMMONS; i++) {
1462 strstri(monexplain[(int)mons[i].mlet], buf) != 0)
1463 class = mons[i].mlet;
1464 if (mons[i].mlet == class) {
1465 if (!(mons[i].geno & G_GENO)) immunecnt++;
1466 else if(mvitals[i].mvflags & G_GENOD) gonecnt++;
1471 * TODO[?]: If user's input doesn't match any class
1472 * description, check individual species names.
1474 if (!goodcnt && class != mons[urole.malenum].mlet &&
1475 class != mons[urace.malenum].mlet) {
1477 pline("All such monsters are already nonexistent.");
1478 else if (immunecnt ||
1479 (buf[0] == DEF_INVISIBLE && buf[1] == '\0'))
1480 You("aren't permitted to genocide such monsters.");
1482 #ifdef WIZARD /* to aid in topology testing; remove pesky monsters */
1483 if (wizard && buf[0] == '*') {
1484 register struct monst *mtmp, *mtmp2;
1487 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
1489 if (DEADMONSTER(mtmp)) continue;
1493 pline("Eliminated %d monster%s.", gonecnt, plur(gonecnt));
1497 pline("That symbol does not represent any monster.");
1501 for (i = LOW_PM; i < NUMMONS; i++) {
1502 if(mons[i].mlet == class) {
1505 Strcpy(nam, makeplural(mons[i].mname));
1506 /* Although "genus" is Latin for race, the hero benefits
1507 * from both race and role; thus genocide affects either.
1509 if (Your_Own_Role(i) || Your_Own_Race(i) ||
1510 ((mons[i].geno & G_GENO)
1511 && !(mvitals[i].mvflags & G_GENOD))) {
1512 /* This check must be first since player monsters might
1513 * have G_GENOD or !G_GENO.
1515 mvitals[i].mvflags |= (G_GENOD|G_NOCORPSE);
1517 kill_genocided_monsters();
1518 update_inventory(); /* eggs & tins */
1519 pline("Wiped out all %s.", nam);
1520 if (Upolyd && i == u.umonnum) {
1523 if (!feel_dead++) You("die.");
1524 /* finish genociding this class of
1525 monsters before ultimately dying */
1530 /* Self-genocide if it matches either your race
1531 or role. Assumption: male and female forms
1532 share same monster class. */
1533 if (i == urole.malenum || i == urace.malenum) {
1536 if (!feel_dead++) You_feel("dead inside.");
1538 if (!feel_dead++) You("die.");
1542 } else if (mvitals[i].mvflags & G_GENOD) {
1544 pline("All %s are already nonexistent.", nam);
1545 } else if (!gameover) {
1546 /* suppress feedback about quest beings except
1547 for those applicable to our own role */
1548 if ((mons[i].msound != MS_LEADER ||
1549 quest_info(MS_LEADER) == i)
1550 && (mons[i].msound != MS_NEMESIS ||
1551 quest_info(MS_NEMESIS) == i)
1552 && (mons[i].msound != MS_GUARDIAN ||
1553 quest_info(MS_GUARDIAN) == i)
1554 /* non-leader/nemesis/guardian role-specific monster */
1555 && (i != PM_NINJA || /* nuisance */
1556 Role_if(PM_SAMURAI))) {
1557 boolean named, uniq;
1559 named = type_is_pname(&mons[i]) ? TRUE : FALSE;
1560 uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE;
1561 /* one special case */
1562 if (i == PM_HIGH_PRIEST) uniq = FALSE;
1564 You("aren't permitted to genocide %s%s.",
1565 (uniq && !named) ? "the " : "",
1566 (uniq || named) ? mons[i].mname : nam);
1571 if (gameover || u.uhp == -1) {
1572 killer_format = KILLED_BY_AN;
1573 killer = "scroll of genocide";
1574 if (gameover) done(GENOCIDED);
1586 /* 0 = no genocide; create monsters (cursed scroll) */
1587 /* 1 = normal genocide */
1588 /* 3 = forced genocide of player */
1589 /* 5 (4 | 1) = normal genocide from throne */
1592 register int i, killplayer = 0;
1594 register struct permonst *ptr;
1598 mndx = u.umonster; /* non-polymorphed mon num */
1600 Strcpy(buf, ptr->mname);
1605 pline(thats_enough_tries);
1608 getlin("What monster do you want to genocide? [type the name]",
1610 (void)mungspaces(buf);
1611 /* choosing "none" preserves genocideless conduct */
1612 if (!strcmpi(buf, "none") || !strcmpi(buf, "nothing")) {
1613 /* ... but no free pass if cursed */
1614 if (!(how & REALLY)) {
1616 if (!ptr) return; /* no message, like normal case */
1617 mndx = monsndx(ptr);
1618 break; /* remaining checks don't apply */
1622 mndx = name_to_mon(buf);
1623 if (mndx == NON_PM || (mvitals[mndx].mvflags & G_GENOD)) {
1624 pline("Such creatures %s exist in this world.",
1625 (mndx == NON_PM) ? "do not" : "no longer");
1629 /* Although "genus" is Latin for race, the hero benefits
1630 * from both race and role; thus genocide affects either.
1632 if (Your_Own_Role(mndx) || Your_Own_Race(mndx)) {
1636 if (is_human(ptr)) adjalign(-sgn(u.ualign.type));
1637 if (is_demon(ptr)) adjalign(sgn(u.ualign.type));
1639 if(!(ptr->geno & G_GENO)) {
1641 /* fixme: unconditional "caverns" will be silly in some circumstances */
1643 pline("A thunderous voice booms through the caverns:");
1644 verbalize("No, mortal! That will not be done.");
1648 /* KMH -- Unchanging prevents rehumanization */
1649 if (Unchanging && ptr == youmonst.data)
1656 if (Hallucination) {
1658 Strcpy(buf,youmonst.data->mname);
1660 Strcpy(buf, (flags.female && urole.name.f) ?
1661 urole.name.f : urole.name.m);
1662 buf[0] = lowc(buf[0]);
1665 Strcpy(buf, ptr->mname); /* make sure we have standard singular */
1666 if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST])
1667 which = !type_is_pname(ptr) ? "the " : "";
1670 /* setting no-corpse affects wishing and random tin generation */
1671 mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE);
1672 pline("Wiped out %s%s.", which,
1673 (*which != 'a') ? buf : makeplural(buf));
1676 /* might need to wipe out dual role */
1677 if (urole.femalenum != NON_PM && mndx == urole.malenum)
1678 mvitals[urole.femalenum].mvflags |= (G_GENOD | G_NOCORPSE);
1679 if (urole.femalenum != NON_PM && mndx == urole.femalenum)
1680 mvitals[urole.malenum].mvflags |= (G_GENOD | G_NOCORPSE);
1681 if (urace.femalenum != NON_PM && mndx == urace.malenum)
1682 mvitals[urace.femalenum].mvflags |= (G_GENOD | G_NOCORPSE);
1683 if (urace.femalenum != NON_PM && mndx == urace.femalenum)
1684 mvitals[urace.malenum].mvflags |= (G_GENOD | G_NOCORPSE);
1688 killer_format = KILLED_BY;
1689 killer = "genocidal confusion";
1690 } else if (how & ONTHRONE) {
1691 /* player selected while on a throne */
1692 killer_format = KILLED_BY_AN;
1693 killer = "imperious order";
1694 } else { /* selected player deliberately, not confused */
1695 killer_format = KILLED_BY_AN;
1696 killer = "scroll of genocide";
1699 /* Polymorphed characters will die as soon as they're rehumanized. */
1700 /* KMH -- Unchanging prevents rehumanization */
1701 if (Upolyd && ptr != youmonst.data) {
1702 delayed_killer = killer;
1704 You_feel("dead inside.");
1707 } else if (ptr == youmonst.data) {
1710 reset_rndmonst(mndx);
1711 kill_genocided_monsters();
1712 update_inventory(); /* in case identified eggs were affected */
1716 if (!(mons[mndx].geno & G_UNIQ) &&
1717 !(mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT)))
1718 for (i = rn1(3, 4); i > 0; i--) {
1719 if (!makemon(ptr, u.ux, u.uy, NO_MINVENT))
1720 break; /* couldn't make one */
1722 if (mvitals[mndx].mvflags & G_EXTINCT)
1723 break; /* just made last one */
1726 pline("Sent in some %s.", makeplural(buf));
1728 pline(nothing_happens);
1734 register struct obj *sobj;
1736 /* KMH -- Punishment is still okay when you are riding */
1737 You("are being punished for your misbehavior!");
1739 Your("iron ball gets heavier.");
1740 uball->owt += 160 * (1 + sobj->cursed);
1743 if (amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data)) {
1744 pline("A ball and chain appears, then falls away.");
1745 dropy(mkobj(BALL_CLASS, TRUE));
1748 setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
1749 setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
1750 uball->spe = 1; /* special ball (see save) */
1753 * Place ball & chain if not swallowed. If swallowed, the ball &
1754 * chain variables will be set at the next call to placebc().
1758 if (Blind) set_bc(1); /* set up ball and chain variables */
1759 newsym(u.ux,u.uy); /* see ball&chain if can't see self */
1765 { /* remove the ball and chain */
1766 struct obj *savechain = uchain;
1768 obj_extract_self(uchain);
1769 newsym(uchain->ox,uchain->oy);
1770 setworn((struct obj *)0, W_CHAIN);
1771 dealloc_obj(savechain);
1773 setworn((struct obj *)0, W_BALL);
1776 /* some creatures have special data structures that only make sense in their
1777 * normal locations -- if the player tries to create one elsewhere, or to revive
1778 * one, the disoriented creature becomes a zombie
1781 cant_create(mtype, revival)
1786 /* SHOPKEEPERS can be revived now */
1787 if (*mtype==PM_GUARD || (*mtype==PM_SHOPKEEPER && !revival)
1788 || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
1789 *mtype = PM_HUMAN_ZOMBIE;
1791 } else if (*mtype==PM_LONG_WORM_TAIL) { /* for create_particular() */
1792 *mtype = PM_LONG_WORM;
1800 * Make a new monster with the type controlled by the user.
1802 * Note: when creating a monster by class letter, specifying the
1803 * "strange object" (']') symbol produces a random monster rather
1804 * than a mimic; this behavior quirk is useful so don't "fix" it...
1809 char buf[BUFSZ], *bufp, monclass = MAXMCLASSES;
1810 int which, tries, i;
1811 struct permonst *whichpm;
1813 boolean madeany = FALSE;
1814 boolean maketame, makepeaceful, makehostile;
1818 which = urole.malenum; /* an arbitrary index into mons[] */
1819 maketame = makepeaceful = makehostile = FALSE;
1820 getlin("Create what kind of monster? [type the name or symbol]",
1822 bufp = mungspaces(buf);
1823 if (*bufp == '\033') return FALSE;
1824 /* allow the initial disposition to be specified */
1825 if (!strncmpi(bufp, "tame ", 5)) {
1828 } else if (!strncmpi(bufp, "peaceful ", 9)) {
1830 makepeaceful = TRUE;
1831 } else if (!strncmpi(bufp, "hostile ", 8)) {
1835 /* decide whether a valid monster was chosen */
1836 if (strlen(bufp) == 1) {
1837 monclass = def_char_to_monclass(*bufp);
1838 if (monclass != MAXMCLASSES) break; /* got one */
1840 which = name_to_mon(bufp);
1841 if (which >= LOW_PM) break; /* got one */
1843 /* no good; try again... */
1844 pline("I've never heard of such monsters.");
1845 } while (++tries < 5);
1848 pline(thats_enough_tries);
1850 (void) cant_create(&which, FALSE);
1851 whichpm = &mons[which];
1852 for (i = 0; i <= multi; i++) {
1853 if (monclass != MAXMCLASSES)
1854 whichpm = mkclass(monclass, 0);
1856 mtmp = makemon(whichpm, u.ux, u.uy, MM_EDOG);
1862 mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS);
1863 if ((makepeaceful || makehostile) && mtmp) {
1864 mtmp->mtame = 0; /* sanity precaution */
1865 mtmp->mpeaceful = makepeaceful ? 1 : 0;
1869 if (mtmp) madeany = TRUE;