Mercurial > hg > early-roguelike
comparison urogue/scrolls.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children | e52a8a7ad4c5 |
comparison
equal
deleted
inserted
replaced
253:d9badb9c0179 | 256:c495a4f288c6 |
---|---|
1 /* | |
2 scrolls.c - Functions for dealing with scrolls | |
3 | |
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
6 All rights reserved. | |
7 | |
8 Based on "Advanced Rogue" | |
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
10 All rights reserved. | |
11 | |
12 Based on "Rogue: Exploring the Dungeons of Doom" | |
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
14 All rights reserved. | |
15 | |
16 See the file LICENSE.TXT for full copyright and licensing information. | |
17 */ | |
18 | |
19 #include <stdlib.h> | |
20 #include <string.h> | |
21 #include <ctype.h> | |
22 #include "rogue.h" | |
23 | |
24 /* | |
25 read_scroll - read a scroll (or effect a scroll-like spell) | |
26 reader: who does it | |
27 which: which S_SCROLL (-1 means ask from pack) | |
28 flags: ISBLESSED, ISCURSED | |
29 */ | |
30 | |
31 void | |
32 read_scroll(struct thing *reader, int which, int flags) | |
33 { | |
34 struct object *obj; | |
35 struct linked_list *item, *nitem; | |
36 int i, j, charm_power; | |
37 char ch, nch; | |
38 int blessed = flags & ISBLESSED; | |
39 int cursed = flags & ISCURSED; | |
40 int is_scroll = (which < 0 ? TRUE : FALSE); | |
41 char buf[2 * LINELEN]; | |
42 | |
43 if (reader != &player) | |
44 { | |
45 monread(reader, which, flags); | |
46 return; | |
47 } | |
48 | |
49 if (is_scroll) /* A regular scroll */ | |
50 { | |
51 if ((item = get_item("read", SCROLL)) == NULL) | |
52 return; | |
53 | |
54 obj = OBJPTR(item); | |
55 | |
56 if (obj->o_type != SCROLL) | |
57 { | |
58 msg("It says 'Made in Yugoslavia'!"); | |
59 return; | |
60 } | |
61 | |
62 if (on(player, ISBLIND)) | |
63 { | |
64 msg("You can't see to read anything."); | |
65 return; | |
66 } | |
67 | |
68 /* Calculate its effect */ | |
69 | |
70 cursed = obj->o_flags & ISCURSED; | |
71 blessed = obj->o_flags & ISBLESSED; | |
72 flags = obj->o_flags; | |
73 which = obj->o_which; | |
74 | |
75 /* remove it from the pack */ | |
76 | |
77 rem_pack(obj); | |
78 discard(item); | |
79 updpack(); | |
80 } | |
81 | |
82 switch (which) | |
83 { | |
84 case S_CONFUSE: /* Touch causes monster confusion. */ | |
85 if (cursed) | |
86 quaff(reader, P_CLEAR, ISCURSED); | |
87 else | |
88 { | |
89 msg("Your hands begin to glow red."); | |
90 turn_on(player, CANHUH); | |
91 /* if blessed... */ | |
92 } | |
93 break; | |
94 | |
95 case S_CURING: /* A cure disease spell */ | |
96 if (on(player, HASINFEST) || on(player, HASDISEASE)) | |
97 { | |
98 if (!cursed && on(player, HASDISEASE)) | |
99 { | |
100 extinguish_fuse(FUSE_CURE_DISEASE); | |
101 cure_disease(NULL); | |
102 } | |
103 | |
104 if (on(player, HASINFEST)) | |
105 { | |
106 msg("You begin to feel yourself improving again."); | |
107 turn_off(player, HASINFEST); | |
108 infest_dam = 0; | |
109 } | |
110 | |
111 if (is_scroll) | |
112 know_items[TYP_SCROLL][S_CURING] = TRUE; | |
113 } | |
114 else | |
115 nothing_message(flags); | |
116 break; | |
117 | |
118 case S_LIGHT: | |
119 if (blue_light(flags) && is_scroll) | |
120 know_items[TYP_SCROLL][S_LIGHT] = TRUE; | |
121 break; | |
122 | |
123 case S_HOLD: | |
124 if (cursed) | |
125 { | |
126 /* | |
127 * This scroll aggravates all the monsters on the | |
128 * current level and sets them running towards the | |
129 * hero | |
130 */ | |
131 aggravate(); | |
132 hearmsg("You hear a high pitched humming noise."); | |
133 } | |
134 else if (blessed) /* Hold all monsters on level */ | |
135 { | |
136 if (mlist == NULL) | |
137 nothing_message(flags); | |
138 else | |
139 { | |
140 struct linked_list *mon; | |
141 struct thing *th; | |
142 | |
143 for (mon = mlist; mon != NULL; mon = next(mon)) | |
144 { | |
145 th = THINGPTR(mon); | |
146 turn_off(*th, ISRUN); | |
147 turn_on(*th, ISHELD); | |
148 } | |
149 msg("A sudden peace comes over the dungeon."); | |
150 } | |
151 } | |
152 else | |
153 { | |
154 /* | |
155 * Hold monster scroll. Stop all monsters within two | |
156 * spaces from chasing after the hero. | |
157 */ | |
158 int x, y; | |
159 struct linked_list *mon; | |
160 int gotone = FALSE; | |
161 | |
162 for (x = hero.x - 2; x <= hero.x + 2; x++) | |
163 { | |
164 for (y = hero.y - 2; y <= hero.y + 2; y++) | |
165 { | |
166 if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) | |
167 { | |
168 if ((mon = find_mons(y, x)) != NULL) | |
169 { | |
170 struct thing *th; | |
171 | |
172 gotone = TRUE; | |
173 th = THINGPTR(mon); | |
174 turn_off(*th, ISRUN); | |
175 turn_on(*th, ISHELD); | |
176 } | |
177 } | |
178 } | |
179 } | |
180 | |
181 if (gotone) | |
182 msg("A sudden peace surrounds you."); | |
183 else | |
184 nothing_message(flags); | |
185 } | |
186 break; | |
187 | |
188 case S_SLEEP: | |
189 | |
190 /* if cursed, you fall asleep */ | |
191 | |
192 if (cursed) | |
193 { | |
194 if (is_wearing(R_ALERT)) | |
195 msg("You feel drowsy for a moment."); | |
196 else | |
197 { | |
198 msg("You fall asleep."); | |
199 no_command += 4 + rnd(SLEEPTIME); | |
200 } | |
201 } | |
202 else | |
203 { | |
204 /* | |
205 * sleep monster scroll. puts all monsters within 2 | |
206 * spaces asleep | |
207 */ | |
208 int x, y; | |
209 struct linked_list *mon; | |
210 int gotone = FALSE; | |
211 | |
212 for (x = hero.x - 2; x <= hero.x + 2; x++) | |
213 { | |
214 for (y = hero.y - 2; y <= hero.y + 2; y++) | |
215 { | |
216 if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) | |
217 { | |
218 if ((mon = find_mons(y, x)) != NULL) | |
219 { | |
220 struct thing *th; | |
221 th = THINGPTR(mon); | |
222 | |
223 if (on(*th, ISUNDEAD)) | |
224 continue; | |
225 | |
226 gotone = TRUE; | |
227 th->t_no_move += SLEEPTIME; | |
228 } | |
229 } | |
230 } | |
231 } | |
232 | |
233 if (gotone) | |
234 msg("The monster(s) around you seem to have fallen asleep."); | |
235 else | |
236 nothing_message(flags); | |
237 } | |
238 break; | |
239 | |
240 case S_CREATE: | |
241 { | |
242 /* | |
243 * Create a monster. First look in a circle around | |
244 * him, next try his room otherwise give up | |
245 */ | |
246 | |
247 struct thing *tp; | |
248 struct linked_list *ip; | |
249 | |
250 if (blessed) | |
251 summon_monster((short) 0, NOFAMILIAR, MESSAGE); | |
252 else if (cursed) | |
253 { | |
254 i = rnd(4) + 3; | |
255 for (j = 0; j < i; j++) | |
256 { | |
257 if ((ip = creat_mons(&player, (short) 0, MESSAGE)) != NULL) | |
258 { | |
259 tp = THINGPTR(ip); | |
260 turn_off(*tp, ISFRIENDLY); | |
261 } | |
262 } | |
263 } | |
264 else if ((ip = creat_mons(&player, (short) 0, MESSAGE)) != NULL) | |
265 { | |
266 tp = THINGPTR(ip); | |
267 turn_off(*tp, ISFRIENDLY); | |
268 } | |
269 } | |
270 break; | |
271 | |
272 case S_IDENTIFY: | |
273 if (cursed) | |
274 msg("You identify this scroll as an identify scroll"); | |
275 else if (blessed) /* identify everything in the pack */ | |
276 { | |
277 msg("You feel more Knowledgeable!"); | |
278 idenpack(); | |
279 } | |
280 else | |
281 { | |
282 /* Identify, let the rogue figure something out */ | |
283 | |
284 if (is_scroll && know_items[TYP_SCROLL][S_IDENTIFY] != TRUE) | |
285 { | |
286 msg("This scroll is an identify scroll."); | |
287 know_items[TYP_SCROLL][S_IDENTIFY] = TRUE; | |
288 } | |
289 whatis(NULL); | |
290 } | |
291 break; | |
292 | |
293 case S_MAP: | |
294 | |
295 /* Scroll of magic mapping. */ | |
296 | |
297 if (cursed) | |
298 { | |
299 msg("Your mind goes blank for a moment."); | |
300 wclear(cw); | |
301 light(&hero); | |
302 status(TRUE); | |
303 break; | |
304 } | |
305 | |
306 if (is_scroll && know_items[TYP_SCROLL][S_MAP] != TRUE) | |
307 { | |
308 msg("Oh! This scroll has a map on it!!"); | |
309 know_items[TYP_SCROLL][S_MAP] = TRUE; | |
310 } | |
311 | |
312 if (blessed) | |
313 turn_on(player, BLESSMAP); | |
314 | |
315 overwrite(stdscr, hw); | |
316 | |
317 /* Take all the things we want to keep hidden out of the window */ | |
318 | |
319 for (i = 0; i < LINES; i++) | |
320 for (j = 0; j < COLS; j++) | |
321 { | |
322 switch (nch = ch = CCHAR(mvwinch(hw, i, j))) | |
323 { | |
324 case SECRETDOOR: | |
325 nch = DOOR; | |
326 mvaddch(i, j, nch); | |
327 break; | |
328 | |
329 case '-': | |
330 case '|': | |
331 case DOOR: | |
332 case PASSAGE: | |
333 case ' ': | |
334 case STAIRS: | |
335 if (mvwinch(mw, i, j) != ' ') | |
336 { | |
337 struct thing *it; | |
338 struct linked_list *lit; | |
339 | |
340 lit = find_mons(i, j); | |
341 | |
342 if (lit) { | |
343 it = THINGPTR(lit); | |
344 | |
345 if (it && it->t_oldch == ' ') | |
346 it->t_oldch = nch; | |
347 } | |
348 } | |
349 break; | |
350 | |
351 default: | |
352 if (!blessed || !isatrap(ch)) | |
353 nch = ' '; | |
354 else | |
355 { | |
356 struct trap *tp; | |
357 struct room *rp; | |
358 | |
359 tp = trap_at(i, j); | |
360 rp = roomin(hero); | |
361 | |
362 if (tp->tr_type == FIRETRAP && rp != NULL) | |
363 { | |
364 rp->r_flags &= ~ISDARK; | |
365 light(&hero); | |
366 } | |
367 | |
368 tp->tr_flags |= ISFOUND; | |
369 } | |
370 } | |
371 if (nch != ch) | |
372 waddch(hw, nch); | |
373 } | |
374 | |
375 /* Copy in what he has discovered */ | |
376 overlay(cw, hw); | |
377 | |
378 /* And set up for display */ | |
379 overwrite(hw, cw); | |
380 | |
381 break; | |
382 | |
383 case S_GFIND: | |
384 /* Scroll of gold detection */ | |
385 | |
386 if (cursed) | |
387 { | |
388 int n = roll(3, 6); | |
389 int k; | |
390 struct room *rp; | |
391 coord pos; | |
392 | |
393 msg("You begin to feel greedy and you sense gold."); | |
394 wclear(hw); | |
395 | |
396 for (k = 1; k < n; k++) | |
397 { | |
398 rp = &rooms[rnd_room()]; | |
399 rnd_pos(rp, &pos); | |
400 mvwaddch(hw, pos.y, pos.x, GOLD); | |
401 } | |
402 overlay(hw, cw); | |
403 | |
404 break; | |
405 } | |
406 | |
407 if (blessed) | |
408 turn_on(player, BLESSGOLD); | |
409 | |
410 if (gsense() && is_scroll) | |
411 know_items[TYP_SCROLL][S_GFIND] = TRUE; | |
412 | |
413 break; | |
414 | |
415 case S_SELFTELEP: | |
416 | |
417 /* Scroll of teleportation: Make him disappear and reappear */ | |
418 | |
419 if (cursed) | |
420 { | |
421 level += 5 + rnd(5); | |
422 new_level(NORMLEV,0); | |
423 mpos = 0; | |
424 msg("You are banished to the lower regions."); | |
425 } | |
426 else if (blessed) | |
427 { | |
428 level -= rnd(3) + 1; | |
429 | |
430 if (level < 1) | |
431 level = 1; | |
432 | |
433 mpos = 0; | |
434 new_level(NORMLEV,0); /* change levels */ | |
435 status(TRUE); | |
436 msg("You are whisked away to another region."); | |
437 } | |
438 else | |
439 { | |
440 teleport(); | |
441 | |
442 if (is_scroll) | |
443 know_items[TYP_SCROLL][S_SELFTELEP] = TRUE; | |
444 } | |
445 | |
446 if (off(player, ISCLEAR)) | |
447 { | |
448 if (on(player, ISHUH)) | |
449 lengthen_fuse(FUSE_UNCONFUSE, rnd(4) + 4); | |
450 else | |
451 { | |
452 light_fuse(FUSE_UNCONFUSE, 0, rnd(4) + 4, AFTER); | |
453 turn_on(player, ISHUH); | |
454 } | |
455 } | |
456 else | |
457 msg("You feel dizzy for a moment, but it quickly passes."); | |
458 | |
459 break; | |
460 | |
461 case S_SCARE: | |
462 | |
463 /* | |
464 * A blessed scroll of scare monster automatically transports | |
465 * itself to the hero's feet | |
466 * | |
467 */ | |
468 | |
469 if (blessed) | |
470 { | |
471 ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) ); | |
472 | |
473 if (ch != FLOOR && ch != PASSAGE) | |
474 { | |
475 msg("Your feet tickle for a moment"); | |
476 return; | |
477 } | |
478 | |
479 item = spec_item(SCROLL, S_SCARE, 0, 0); | |
480 | |
481 obj = OBJPTR(item); | |
482 obj->o_flags = ISCURSED; | |
483 obj->o_pos = hero; | |
484 add_obj(item, hero.y, hero.x); | |
485 msg("A wave of terror sweeps throughout the room"); | |
486 } | |
487 else | |
488 { | |
489 /* | |
490 * A monster will refuse to step on a scare monster | |
491 * scroll if it is dropped. Thus reading it is a | |
492 * mistake and produces laughter at the poor rogue's | |
493 * boo boo. | |
494 */ | |
495 | |
496 msg("You hear maniacal laughter in the distance."); | |
497 | |
498 if (cursed) /* If cursed, monsters get mad */ | |
499 aggravate(); | |
500 } | |
501 break; | |
502 | |
503 case S_REMOVECURSE: | |
504 if (cursed) /* curse a player's possession */ | |
505 { | |
506 for (nitem = pack; nitem != NULL; nitem = next(nitem)) | |
507 { | |
508 obj = OBJPTR(nitem); | |
509 | |
510 if (rnd(5) == 0) | |
511 if (obj->o_flags & ISBLESSED) | |
512 obj->o_flags &= ~ISBLESSED; | |
513 else | |
514 obj->o_flags |= ISCURSED; | |
515 } | |
516 msg("The smell of fire and brimstone comes from your pack."); | |
517 } | |
518 else if (blessed) | |
519 { | |
520 for (nitem = pack; nitem != NULL; nitem = next(nitem)) | |
521 (OBJPTR(nitem))->o_flags &= ~ISCURSED; | |
522 | |
523 msg("Your pack glistens brightly."); | |
524 } | |
525 else | |
526 { | |
527 if ((nitem = get_item("remove the curse on", 0)) != NULL) | |
528 { | |
529 obj = OBJPTR(nitem); | |
530 msg("Removed the curse from %s.", inv_name(obj, LOWERCASE)); | |
531 obj->o_flags &= ~ISCURSED; | |
532 | |
533 if (is_scroll) | |
534 know_items[TYP_SCROLL][S_REMOVECURSE] = TRUE; | |
535 } | |
536 } | |
537 break; | |
538 | |
539 case S_PETRIFY: | |
540 switch(CCHAR(mvinch(hero.y, hero.x))) | |
541 { | |
542 case TRAPDOOR: | |
543 case DARTTRAP: | |
544 case TELTRAP: | |
545 case ARROWTRAP: | |
546 case SLEEPTRAP: | |
547 case BEARTRAP: | |
548 case FIRETRAP: | |
549 { | |
550 int n; | |
551 | |
552 /* Find the right trap */ | |
553 for (n = 0; n < ntraps && !ce(traps[n].tr_pos, hero); n++) | |
554 ; | |
555 | |
556 ntraps--; | |
557 | |
558 if (!ce(traps[n].tr_pos, hero)) | |
559 msg("What a strange trap!"); | |
560 else | |
561 { | |
562 while (n < ntraps) | |
563 { | |
564 traps[n] = traps[n + 1]; | |
565 n++; | |
566 } | |
567 } | |
568 | |
569 msg("The dungeon begins to rumble and shake!"); | |
570 addch(WALL); | |
571 | |
572 if (on(player, CANINWALL)) | |
573 { | |
574 extinguish_fuse(FUSE_UNPHASE); | |
575 turn_off(player, CANINWALL); | |
576 msg("Your dizzy feeling leaves you."); | |
577 } | |
578 | |
579 turn_on(player, ISINWALL); | |
580 } | |
581 break; | |
582 | |
583 case DOOR: | |
584 case SECRETDOOR: | |
585 { | |
586 struct room *rp = roomin(hero); | |
587 short n; | |
588 | |
589 /* Find the right door */ | |
590 | |
591 for (n=0; n<rp->r_nexits && !ce(rp->r_exit[n], hero); n++) | |
592 /* do nothing */ ; | |
593 | |
594 rp->r_nexits--; | |
595 | |
596 if (!ce(rp->r_exit[n], hero)) | |
597 msg("What a strange door!"); | |
598 else | |
599 { | |
600 while (n < rp->r_nexits) | |
601 { | |
602 rp->r_exit[n] = rp->r_exit[n + 1]; | |
603 n++; | |
604 } | |
605 } | |
606 /* No break - fall through */ | |
607 } | |
608 case FLOOR: | |
609 case PASSAGE: | |
610 msg("The dungeon begins to rumble and shake!"); | |
611 addch(WALL); | |
612 | |
613 if (on(player, CANINWALL)) | |
614 { | |
615 extinguish_fuse(FUSE_UNPHASE); | |
616 turn_off(player, CANINWALL); | |
617 msg("Your dizzy feeling leaves you."); | |
618 } | |
619 | |
620 turn_on(player, ISINWALL); | |
621 break; | |
622 | |
623 default: | |
624 nothing_message(flags); | |
625 break; | |
626 } | |
627 break; | |
628 | |
629 case S_GENOCIDE: | |
630 msg("You have been granted the boon of genocide!--More--"); | |
631 | |
632 wait_for(' '); | |
633 msg(""); | |
634 | |
635 genocide(flags); | |
636 | |
637 if (is_scroll) | |
638 know_items[TYP_SCROLL][S_GENOCIDE] = TRUE; | |
639 | |
640 break; | |
641 | |
642 case S_PROTECT: | |
643 if (is_scroll && know_items[TYP_SCROLL][S_PROTECT] == FALSE) | |
644 { | |
645 msg("You can protect something from rusting or theft."); | |
646 know_items[TYP_SCROLL][S_PROTECT] = TRUE; | |
647 } | |
648 | |
649 if ((item = get_item("protect", 0)) != NULL) | |
650 { | |
651 struct object *lb = OBJPTR(item); | |
652 | |
653 if (cursed) | |
654 { | |
655 lb->o_flags &= ~ISPROT; | |
656 mpos = 0; | |
657 msg("Unprotected %s.", inv_name(lb, LOWERCASE)); | |
658 } | |
659 else | |
660 { | |
661 lb->o_flags |= ISPROT; | |
662 mpos = 0; | |
663 msg("Protected %s.", inv_name(lb, LOWERCASE)); | |
664 } | |
665 } | |
666 break; | |
667 | |
668 case S_MAKEITEMEM: | |
669 if (!is_scroll || rnd(luck)) | |
670 feel_message(); | |
671 else | |
672 { | |
673 char itemtype; | |
674 | |
675 if (is_scroll) | |
676 know_items[TYP_SCROLL][S_MAKEITEMEM] = TRUE; | |
677 | |
678 msg("You have been endowed with the power of creation."); | |
679 | |
680 if (blessed) | |
681 itemtype = '\0'; | |
682 else | |
683 switch (rnd(6)) | |
684 { | |
685 case 0: itemtype = RING; break; | |
686 case 1: itemtype = POTION; break; | |
687 case 2: itemtype = SCROLL; break; | |
688 case 3: itemtype = ARMOR; break; | |
689 case 4: itemtype = WEAPON; break; | |
690 case 5: itemtype = STICK; break; | |
691 } | |
692 | |
693 flags |= SCR_MAGIC; | |
694 buy_it(itemtype, flags); | |
695 } | |
696 break; | |
697 | |
698 case S_ENCHANT: | |
699 { | |
700 struct linked_list *ll; | |
701 struct object *lb; | |
702 int howmuch, flg=0; | |
703 | |
704 if (is_scroll && know_items[TYP_SCROLL][S_ENCHANT] == FALSE) | |
705 { | |
706 msg("You are granted the power of enchantment."); | |
707 msg("You may enchant anything(weapon,ring,armor,scroll,potion)"); | |
708 know_items[TYP_SCROLL][S_ENCHANT] = TRUE; | |
709 } | |
710 | |
711 if ((ll = get_item("enchant", 0)) != NULL) | |
712 { | |
713 lb = OBJPTR(ll); | |
714 lb->o_flags &= ~ISCURSED; | |
715 | |
716 if (blessed) | |
717 howmuch = 2; | |
718 else if (cursed) | |
719 howmuch = -1; | |
720 else | |
721 { | |
722 howmuch = 1; | |
723 flg |= ISBLESSED; | |
724 } | |
725 | |
726 switch (lb->o_type) | |
727 { | |
728 case RING: | |
729 lb->o_ac += howmuch; | |
730 | |
731 if (lb->o_ac > 5 && rnd(5) == 0) | |
732 { | |
733 msg("Your ring explodes in a cloud of smoke."); | |
734 lb->o_flags &= ~ISCURSED; | |
735 dropcheck(lb); | |
736 | |
737 switch (lb->o_which) | |
738 { | |
739 case R_ADDSTR: | |
740 chg_str(-2, TRUE, FALSE); | |
741 break; | |
742 case R_ADDHIT: | |
743 chg_dext(-2, TRUE, FALSE); | |
744 break; | |
745 case R_ADDINTEL: | |
746 pstats.s_intel -= 2; | |
747 max_stats.s_intel -= 2; | |
748 break; | |
749 case R_ADDWISDOM: | |
750 pstats.s_wisdom -= 2; | |
751 max_stats.s_wisdom -= 2; | |
752 break; | |
753 } | |
754 | |
755 del_pack(ll); | |
756 lb = NULL; | |
757 } | |
758 else if (is_r_on(lb)) | |
759 switch (lb->o_which) | |
760 { | |
761 case R_ADDSTR: | |
762 pstats.s_str += howmuch; | |
763 break; | |
764 case R_ADDHIT: | |
765 pstats.s_dext += howmuch; | |
766 break; | |
767 case R_ADDINTEL: | |
768 pstats.s_intel += howmuch; | |
769 break; | |
770 case R_ADDWISDOM: | |
771 pstats.s_wisdom += howmuch; | |
772 break; | |
773 case R_CARRYING: | |
774 updpack(); | |
775 break; | |
776 } | |
777 | |
778 break; | |
779 | |
780 case ARMOR: | |
781 lb->o_ac -= howmuch; | |
782 | |
783 if (armors[lb->o_which].a_class - lb->o_ac > 5 && rnd(5) == 0) | |
784 { | |
785 msg("Your %s explodes in a cloud of dust.", | |
786 inv_name(lb, LOWERCASE)); | |
787 | |
788 lb->o_flags &= ~ISCURSED; | |
789 | |
790 if (lb == cur_armor) | |
791 pstats.s_hpt /= 2; | |
792 | |
793 dropcheck(lb); | |
794 del_pack(ll); | |
795 lb = NULL; | |
796 } | |
797 break; | |
798 | |
799 case STICK: | |
800 if (wizard || howmuch != 1 && rnd(5) == 0) | |
801 lb->o_flags |= flg; | |
802 | |
803 lb->o_charges += howmuch + 10; | |
804 | |
805 if (lb->o_charges < 0) | |
806 lb->o_charges = 0; | |
807 | |
808 if (lb->o_charges > 50 && rnd(5) == 0) | |
809 { | |
810 msg("Your %s explodes into splinters.", | |
811 inv_name(lb, LOWERCASE)); | |
812 | |
813 lb->o_flags &= ~ISCURSED; | |
814 dropcheck(lb); | |
815 del_pack(ll); | |
816 lb = NULL; | |
817 } | |
818 break; | |
819 | |
820 case WEAPON: | |
821 if (rnd(100) < 50) | |
822 lb->o_hplus += howmuch; | |
823 else | |
824 lb->o_dplus += howmuch; | |
825 | |
826 if (lb->o_hplus + lb->o_dplus > 10 && rnd(5) == 0) | |
827 { | |
828 msg("Your %s explodes in a cloud of shrapnel", | |
829 inv_name(lb, LOWERCASE)); | |
830 | |
831 lb->o_flags &= ~ISCURSED; | |
832 | |
833 if (lb == cur_weapon) | |
834 chg_dext(-2, FALSE, TRUE); | |
835 | |
836 dropcheck(lb); | |
837 del_pack(ll); | |
838 lb = NULL; | |
839 | |
840 } | |
841 break; | |
842 | |
843 case POTION: | |
844 case SCROLL: | |
845 default: | |
846 lb->o_flags |= flg; | |
847 break; | |
848 } | |
849 | |
850 mpos = 0; | |
851 | |
852 if (lb != NULL) | |
853 msg("Enchanted %s.", inv_name(lb, LOWERCASE)); | |
854 } | |
855 } | |
856 break; | |
857 | |
858 case S_NOTHING: | |
859 nothing_message(flags); | |
860 break; | |
861 | |
862 case S_SILVER: | |
863 { | |
864 struct object *lb; | |
865 | |
866 if (is_scroll && know_items[TYP_SCROLL][S_SILVER] == FALSE) | |
867 { | |
868 msg("You are granted the power of magic hitting."); | |
869 know_items[TYP_SCROLL][S_SILVER] = TRUE; | |
870 } | |
871 | |
872 if ((item = get_item("annoint", WEAPON)) != NULL) | |
873 { | |
874 lb = OBJPTR(item); | |
875 | |
876 if (blessed && !(lb->o_flags & ISSILVER)) | |
877 { | |
878 lb->o_hplus += rnd(3) + 1; | |
879 lb->o_flags |= ISSILVER; | |
880 lb->o_flags |= ISMETAL; | |
881 msg("Your weapon has turned to silver!"); | |
882 } | |
883 else if (cursed && (lb->o_flags & ISSILVER)) | |
884 { | |
885 lb->o_hplus -= (rnd(3) + 1); | |
886 lb->o_flags &= ~ISSILVER; | |
887 msg("Your silver weapon has turned to steel."); | |
888 } | |
889 else if (lb->o_flags & ISSILVER) | |
890 { | |
891 msg("Your silver weapon glitters briefly."); | |
892 lb->o_hplus += rnd(2); | |
893 } | |
894 else | |
895 { | |
896 lb->o_hplus += rnd(3); | |
897 lb->o_flags |= ISSILVER; | |
898 lb->o_flags |= ISMETAL; | |
899 msg("Your weapon has turned to silver."); | |
900 } | |
901 } | |
902 } | |
903 break; | |
904 case S_OWNERSHIP: | |
905 { | |
906 struct linked_list *ll; | |
907 struct object *lb; | |
908 | |
909 if (is_scroll && know_items[TYP_SCROLL][S_OWNERSHIP] == FALSE) | |
910 { | |
911 msg("You are granted the power of ownership."); | |
912 know_items[TYP_SCROLL][S_OWNERSHIP] = TRUE; | |
913 } | |
914 | |
915 if ((ll = get_item("claim", 0)) != NULL) | |
916 { | |
917 lb = OBJPTR(ll); | |
918 | |
919 if (cursed && lb->o_flags & (ISOWNED | CANRETURN)) | |
920 { | |
921 lb->o_flags &= ~(ISOWNED | CANRETURN); | |
922 msg("The gods seem to have forgotten you."); | |
923 } | |
924 else if (cursed && !(lb->o_flags & ISLOST)) | |
925 { | |
926 lb->o_flags |= ISLOST; | |
927 msg("The gods look the other way."); | |
928 } | |
929 else if (blessed && lb->o_flags & ISLOST) | |
930 { | |
931 lb->o_flags |= CANRETURN; | |
932 msg("The gods seem to have remembered you."); | |
933 } | |
934 else if (blessed && !(lb->o_flags & ISOWNED)) | |
935 { | |
936 lb->o_flags |= (ISOWNED | CANRETURN); | |
937 msg("The gods smile upon you."); | |
938 } | |
939 else if (blessed | cursed) | |
940 { | |
941 nothing_message(flags); | |
942 } | |
943 else | |
944 { | |
945 lb->o_flags |= CANRETURN; | |
946 msg("The gods look upon you."); | |
947 } | |
948 } | |
949 } | |
950 break; | |
951 | |
952 case S_FOODDET: | |
953 | |
954 /* Scroll of food detection */ | |
955 | |
956 if (cursed) | |
957 { | |
958 int n = roll(3, 6); | |
959 int k; | |
960 struct room *rp; | |
961 coord pos; | |
962 | |
963 msg("You begin to feel hungry and you smell food."); | |
964 wclear(hw); | |
965 | |
966 for (k = 1; k < n; k++) | |
967 { | |
968 rp = &rooms[rnd_room()]; | |
969 rnd_pos(rp, &pos); | |
970 mvwaddch(hw, pos.y, pos.x, FOOD); | |
971 } | |
972 | |
973 overlay(hw, cw); | |
974 | |
975 if (is_scroll) | |
976 know_items[TYP_SCROLL][S_FOODDET] = TRUE; | |
977 | |
978 break; | |
979 } | |
980 | |
981 if (blessed) | |
982 turn_on(player, BLESSFOOD); | |
983 | |
984 if (off(player, ISUNSMELL) && lvl_obj != NULL) | |
985 { | |
986 struct linked_list *itm; | |
987 struct object *cur; | |
988 struct thing *th; | |
989 int fcount = 0; | |
990 int same_room = FALSE; | |
991 struct room *rp = roomin(hero); | |
992 | |
993 wclear(hw); | |
994 | |
995 for (itm = lvl_obj; itm != NULL; itm = next(itm)) | |
996 { | |
997 cur = OBJPTR(itm); | |
998 | |
999 if (cur->o_type == FOOD) | |
1000 { | |
1001 fcount += cur->o_count; | |
1002 mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, FOOD); | |
1003 | |
1004 if (roomin(cur->o_pos) == rp) | |
1005 same_room = TRUE; | |
1006 } | |
1007 } | |
1008 | |
1009 for (itm = mlist; itm != NULL; itm = next(itm)) | |
1010 { | |
1011 struct linked_list *pitem; | |
1012 | |
1013 th = THINGPTR(itm); | |
1014 | |
1015 for (pitem = th->t_pack; pitem != NULL; pitem = next(pitem)) | |
1016 { | |
1017 cur = OBJPTR(pitem); | |
1018 | |
1019 if (cur->o_type == FOOD) | |
1020 { | |
1021 fcount += cur->o_count; | |
1022 mvwaddch(hw, th->t_pos.y, th->t_pos.x, FOOD); | |
1023 | |
1024 if (roomin(th->t_pos) == rp) | |
1025 same_room = TRUE; | |
1026 } | |
1027 } | |
1028 } | |
1029 | |
1030 if (fcount) | |
1031 { | |
1032 if (is_scroll) | |
1033 know_items[TYP_SCROLL][S_FOODDET] = TRUE; | |
1034 | |
1035 if (same_room) | |
1036 msg("FOOOOD!!"); | |
1037 else | |
1038 msg("You begin to feel hungry and you smell food."); | |
1039 | |
1040 overlay(hw, cw); | |
1041 break; | |
1042 } | |
1043 } | |
1044 | |
1045 if (off(player, ISUNSMELL)) | |
1046 msg("You can't smell anything."); | |
1047 else | |
1048 nothing_message(flags); | |
1049 | |
1050 break; | |
1051 | |
1052 case S_ELECTRIFY: | |
1053 if (on(player, ISELECTRIC)) | |
1054 { | |
1055 msg("Your violet glow brightens for an instant."); | |
1056 lengthen_fuse(FUSE_UNELECTRIFY, 4 + rnd(8)); | |
1057 } | |
1058 else | |
1059 { | |
1060 msg("Your body begins to glow violet and shoot sparks."); | |
1061 turn_on(player, ISELECTRIC); | |
1062 light_fuse(FUSE_UNELECTRIFY,0,(blessed?3:1)*WANDERTIME, AFTER); | |
1063 light(&hero); | |
1064 } | |
1065 | |
1066 if (is_scroll) | |
1067 know_items[TYP_SCROLL][S_ELECTRIFY] = TRUE; | |
1068 | |
1069 break; | |
1070 | |
1071 case S_CHARM: | |
1072 | |
1073 /* | |
1074 * Beauty, brains and experience make a person charming. | |
1075 * Unique monsters can never be charmed. | |
1076 */ | |
1077 | |
1078 charm_power = pstats.s_charisma / 2 + pstats.s_lvl / 3 + max(0, pstats.s_intel - 15); | |
1079 | |
1080 if (cursed) | |
1081 { | |
1082 msg("You hear harsh, dissonant twanging throughout the dungeon."); | |
1083 aggravate(); | |
1084 } | |
1085 else if (blessed) /* Charm entire level */ | |
1086 { | |
1087 struct linked_list *mon; | |
1088 | |
1089 msg("You hear ringingly meliflous music all around you."); | |
1090 | |
1091 for (mon = mlist; mon != NULL; mon = next(mon)) | |
1092 { | |
1093 struct thing *th = THINGPTR(mon); | |
1094 | |
1095 if (th->t_stats.s_intel < charm_power && off(*th, ISUNIQUE)) | |
1096 { | |
1097 turn_on(*th, ISCHARMED); | |
1098 chase_it(&th->t_pos, &player); | |
1099 } | |
1100 } | |
1101 } | |
1102 else /* Charm all monsters within two spaces of the hero */ | |
1103 { | |
1104 int x, y; | |
1105 struct linked_list *mon; | |
1106 | |
1107 msg("You hear soft, lyrical music all around you."); | |
1108 | |
1109 for (x = hero.x - 2; x <= hero.x + 2; x++) | |
1110 for (y = hero.y - 2; y <= hero.y + 2; y++) | |
1111 if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) | |
1112 { | |
1113 if ((mon = find_mons(y, x)) != NULL) | |
1114 { | |
1115 struct thing *th; | |
1116 | |
1117 th = THINGPTR(mon); | |
1118 | |
1119 if (th->t_stats.s_intel < charm_power && off(*th, ISUNIQUE)) | |
1120 { | |
1121 turn_on(*th, ISCHARMED); | |
1122 chase_it(&th->t_pos, &player); | |
1123 } | |
1124 } | |
1125 } | |
1126 } | |
1127 break; | |
1128 | |
1129 case S_SUMMON: | |
1130 { | |
1131 struct linked_list *llp; | |
1132 struct thing *tp; | |
1133 int mon_type; | |
1134 | |
1135 if (on(player, HASSUMMONED)) | |
1136 { | |
1137 nothing_message(flags); | |
1138 break; | |
1139 } | |
1140 | |
1141 if (cursed) | |
1142 { | |
1143 creat_mons(&player, (short) 0, MESSAGE); | |
1144 break; | |
1145 } | |
1146 | |
1147 if (blessed) /* Summon a possibly very high monster */ | |
1148 { | |
1149 int nsides = max(2, max(pstats.s_lvl, 12) - luck); | |
1150 | |
1151 mon_type = roll(nsides, rnd(pstats.s_charisma + 15) + 8); | |
1152 mon_type = min(mon_type, nummonst); | |
1153 } | |
1154 else | |
1155 mon_type = 0; | |
1156 | |
1157 llp = summon_monster((short) mon_type, NOFAMILIAR, NOMESSAGE); | |
1158 | |
1159 if (llp) | |
1160 { | |
1161 tp = THINGPTR(llp); | |
1162 turn_on(*tp, WASSUMMONED); | |
1163 turn_on(player, HASSUMMONED); | |
1164 msg("You have summoned a %s.", monsters[tp->t_index].m_name); | |
1165 light_fuse(FUSE_UNSUMMON, llp, WANDERTIME + rnd(pstats.s_lvl), AFTER); | |
1166 } | |
1167 } | |
1168 break; | |
1169 | |
1170 case S_REFLECT: | |
1171 if (on(player, CANREFLECT)) | |
1172 { | |
1173 msg("The sparkling around you brightens momentarily."); | |
1174 lengthen_fuse(FUSE_UNGAZE, 5 + rnd(10)); | |
1175 } | |
1176 else | |
1177 { | |
1178 msg("Shiny particles sparkle all around you."); | |
1179 turn_on(player, CANREFLECT); | |
1180 light_fuse(FUSE_UNGAZE, 0, (blessed ? 3 : 1) * WANDERTIME, AFTER); | |
1181 } | |
1182 break; | |
1183 | |
1184 case S_SUMFAMILIAR: | |
1185 { | |
1186 int type = 0; | |
1187 | |
1188 if (on(player, HASFAMILIAR)) | |
1189 { | |
1190 msg("But you already have a familiar - somewhere..."); | |
1191 return; | |
1192 } | |
1193 | |
1194 if (wizard) | |
1195 type = get_monster_number("be your familiar"); | |
1196 else if (blessed) /* Summon a possibly very high monster */ | |
1197 { | |
1198 int nsides = max(2, max(pstats.s_lvl, 12) - luck); | |
1199 | |
1200 type = roll(nsides, rnd(pstats.s_charisma + 15) + 8); | |
1201 type = min(type, nummonst); | |
1202 } | |
1203 else if (cursed) /* Summon a bat, maggot, eye, etc */ | |
1204 { | |
1205 type = rnd(20) + 1; | |
1206 | |
1207 if (summon_monster(type, FAMILIAR, MESSAGE)) | |
1208 turn_on(player, HASFAMILIAR); | |
1209 } | |
1210 } | |
1211 break; | |
1212 | |
1213 case S_FEAR: | |
1214 | |
1215 /* if cursed, you get frightened */ | |
1216 | |
1217 if (cursed) | |
1218 { | |
1219 if (off(player, SUPERHERO) && (player.t_ctype != C_PALADIN) && !save(VS_DEATH)) | |
1220 msg("A momentary wave of panic sweeps over you."); | |
1221 else | |
1222 { | |
1223 msg("Panicstricken, you fall into a coma."); | |
1224 no_command += roll(2, SLEEPTIME); | |
1225 } | |
1226 } | |
1227 else | |
1228 { | |
1229 /* | |
1230 * terrify monster scroll. frightens all monsters | |
1231 * within 2 spaces | |
1232 */ | |
1233 int x, y; | |
1234 struct linked_list *mon; | |
1235 int gotone = FALSE; | |
1236 | |
1237 for (x = hero.x - 2; x <= hero.x + 2; x++) | |
1238 { | |
1239 for (y = hero.y - 2; y <= hero.y + 2; y++) | |
1240 { | |
1241 if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) | |
1242 { | |
1243 if ((mon = find_mons(y, x)) != NULL) | |
1244 { | |
1245 struct thing *th; | |
1246 | |
1247 th = THINGPTR(mon); | |
1248 | |
1249 if (on(*th, ISUNDEAD) || on(*th, ISUNIQUE)) | |
1250 continue; | |
1251 | |
1252 gotone = TRUE; | |
1253 turn_on(*th, ISFLEE); | |
1254 th->t_chasee = &player; | |
1255 th->t_ischasing = FALSE; | |
1256 th->t_horde = NULL; | |
1257 } | |
1258 } | |
1259 } | |
1260 } | |
1261 | |
1262 if (gotone) | |
1263 seemsg("The monster(s) around you recoil in horror."); | |
1264 else | |
1265 nothing_message(flags); | |
1266 } | |
1267 break; | |
1268 | |
1269 case S_MSHIELD: /* deal with blessed/cursed later */ | |
1270 if (on(player, HASMSHIELD)) | |
1271 { | |
1272 seemsg("The fog around you thickens."); | |
1273 lengthen_fuse(FUSE_UNMSHIELD, (blessed ? 3 : 1) * HEROTIME); | |
1274 } | |
1275 else | |
1276 { | |
1277 seemsg("A fog forms around you."); | |
1278 turn_on(player, HASMSHIELD); | |
1279 light_fuse(FUSE_UNMSHIELD, 0, (blessed ? 3 : 1) * HEROTIME, AFTER); | |
1280 } | |
1281 | |
1282 if (is_scroll) | |
1283 know_items[TYP_SCROLL][S_MSHIELD] = TRUE; | |
1284 | |
1285 break; | |
1286 | |
1287 default: | |
1288 msg("What a puzzling scroll!"); | |
1289 return; | |
1290 } | |
1291 | |
1292 look(TRUE); /* put the result of the scroll on the screen */ | |
1293 status(FALSE); | |
1294 | |
1295 if (is_scroll) | |
1296 { | |
1297 if (know_items[TYP_SCROLL][which] && guess_items[TYP_SCROLL][which]) | |
1298 { | |
1299 ur_free(guess_items[TYP_SCROLL][which]); | |
1300 guess_items[TYP_SCROLL][which] = NULL; | |
1301 } | |
1302 else if (askme && !know_items[TYP_SCROLL][which] && guess_items[TYP_SCROLL][which] == NULL) | |
1303 { | |
1304 msg("What do you want to call it? "); | |
1305 | |
1306 if (get_string(buf, cw) == NORM) | |
1307 { | |
1308 guess_items[TYP_SCROLL][which] = new_alloc(strlen(buf) + 1); | |
1309 strcpy(guess_items[TYP_SCROLL][which], buf); | |
1310 } | |
1311 } | |
1312 } | |
1313 } | |
1314 | |
1315 /* | |
1316 creat_mons() | |
1317 creates the specified monster -- any if 0 | |
1318 */ | |
1319 | |
1320 struct linked_list * | |
1321 creat_mons(struct thing *person, int monster, int message) | |
1322 { | |
1323 coord mp; | |
1324 | |
1325 /* Search for an open place */ | |
1326 | |
1327 debug("Creator @(%d, %d) ", person->t_pos.y, person->t_pos.x); | |
1328 | |
1329 if ((place_mons(person->t_pos.y, person->t_pos.x, &mp)) != FALSE) | |
1330 { | |
1331 struct linked_list *nitem; | |
1332 | |
1333 nitem = new_item(sizeof(struct thing)); | |
1334 new_monster(nitem, monster == 0 ? randmonster(NOWANDER, NOGRAB) | |
1335 : monster, &mp, MAXSTATS); | |
1336 chase_it(&mp, &player); | |
1337 | |
1338 /* If the monster is on a trap, trap it */ | |
1339 | |
1340 if (isatrap(mvinch(mp.y, mp.x))) | |
1341 { | |
1342 debug("Monster trapped during creat_mons."); | |
1343 be_trapped(THINGPTR(nitem), mp); | |
1344 } | |
1345 | |
1346 light(&hero); | |
1347 return(nitem); | |
1348 } | |
1349 | |
1350 if (message) | |
1351 hearmsg("You hear a faint cry of anguish in the distance."); | |
1352 | |
1353 return(NULL); | |
1354 } | |
1355 | |
1356 /* | |
1357 place_mons() | |
1358 finds a place to put the monster | |
1359 */ | |
1360 | |
1361 int | |
1362 place_mons(int y, int x, coord *pos) | |
1363 { | |
1364 int distance, xx, yy, appears; | |
1365 | |
1366 for (distance = 1; distance <= 10; distance++) | |
1367 { | |
1368 appears = 0; | |
1369 | |
1370 for (yy = y - distance; yy <= y + distance; yy++) | |
1371 for (xx = x - distance; xx <= x + distance; xx++) | |
1372 { | |
1373 /* Don't put a monster in top of the creator or player */ | |
1374 | |
1375 if (xx < 0 || yy < 0) | |
1376 continue; | |
1377 | |
1378 if (yy == y && xx == x) | |
1379 continue; | |
1380 | |
1381 if (yy == hero.y && xx == hero.x) | |
1382 continue; | |
1383 | |
1384 /* Or anything else nasty */ | |
1385 | |
1386 if (step_ok(yy, xx, NOMONST, FALSE)) | |
1387 { | |
1388 if (rnd(max(1, (10 * distance - ++appears))) == 0) | |
1389 { | |
1390 pos->y = yy; | |
1391 pos->x = xx; | |
1392 debug("Make monster dist %d appear %d @(%d, %d) ", | |
1393 distance, appears, pos->y, pos->x); | |
1394 return(TRUE); | |
1395 } | |
1396 } | |
1397 } | |
1398 } | |
1399 return(FALSE); | |
1400 } | |
1401 | |
1402 /* | |
1403 is_t_on() | |
1404 This subroutine determines if an object that is a ring is being | |
1405 worn by the hero by Bruce Dautrich 4/3/84 | |
1406 */ | |
1407 | |
1408 int | |
1409 is_r_on(struct object *obj) | |
1410 { | |
1411 if (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] || | |
1412 obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4] || | |
1413 obj == cur_ring[LEFT_5] || | |
1414 obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] || | |
1415 obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4] || | |
1416 obj == cur_ring[RIGHT_5]) | |
1417 { | |
1418 return(TRUE); | |
1419 } | |
1420 | |
1421 return(FALSE); | |
1422 } | |
1423 | |
1424 /* | |
1425 monread() | |
1426 monster gets the effect | |
1427 */ | |
1428 | |
1429 void | |
1430 monread(struct thing *reader, int which, int flags) | |
1431 { | |
1432 struct stats *curp = &(reader->t_stats); | |
1433 struct stats *maxp = &(reader->maxstats); | |
1434 int blessed = flags & ISBLESSED; | |
1435 int cursed = flags & ISCURSED; | |
1436 | |
1437 switch (which) | |
1438 { | |
1439 case S_SELFTELEP: | |
1440 /* If monster was suffocating, stop it */ | |
1441 if (on(*reader, DIDSUFFOCATE)) | |
1442 { | |
1443 turn_off(*reader, DIDSUFFOCATE); | |
1444 extinguish_fuse(FUSE_SUFFOCATE); | |
1445 } | |
1446 | |
1447 /* If monster held us, stop it */ | |
1448 | |
1449 if (on(*reader, DIDHOLD) && (hold_count == 0)) | |
1450 turn_off(player, ISHELD); | |
1451 | |
1452 turn_off(*reader, DIDHOLD); | |
1453 | |
1454 if (cursed) | |
1455 reader->t_no_move++; | |
1456 else | |
1457 { | |
1458 int rm; | |
1459 | |
1460 if (blessed) /* Give him his hit points */ | |
1461 curp->s_hpt = maxp->s_hpt; | |
1462 | |
1463 /* Erase the monster from the old position */ | |
1464 | |
1465 if (isalpha(mvwinch(cw, reader->t_pos.y, reader->t_pos.x))) | |
1466 mvwaddch(cw, reader->t_pos.y, reader->t_pos.x, reader->t_oldch); | |
1467 | |
1468 mvwaddch(mw, reader->t_pos.y, reader->t_pos.x, ' '); | |
1469 | |
1470 /* Get a new position */ | |
1471 | |
1472 do | |
1473 { | |
1474 rm = rnd_room(); | |
1475 rnd_pos(&rooms[rm], &reader->t_pos); | |
1476 } | |
1477 while (winat(reader->t_pos.y, reader->t_pos.x) != FLOOR); | |
1478 | |
1479 /* Put it there */ | |
1480 | |
1481 mvwaddch(mw, reader->t_pos.y, reader->t_pos.x, reader->t_type); | |
1482 reader->t_oldch = CCHAR( mvwinch(cw, reader->t_pos.y, reader->t_pos.x) ); | |
1483 } | |
1484 break; | |
1485 | |
1486 default: | |
1487 debug("'%s' is a strange scroll for a monster to read!", | |
1488 r_magic[which].mi_name); | |
1489 break; | |
1490 } | |
1491 } |