Mercurial > hg > early-roguelike
comparison arogue7/scrolls.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 125:adfa37e67084 |
---|---|
1 /* | |
2 * scrolls.c - Functions for dealing with scrolls | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T | |
6 * All rights reserved. | |
7 * | |
8 * Based on "Rogue: Exploring the Dungeons of Doom" | |
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
10 * All rights reserved. | |
11 * | |
12 * See the file LICENSE.TXT for full copyright and licensing information. | |
13 */ | |
14 | |
15 /* | |
16 * Read a scroll and let it happen | |
17 * | |
18 */ | |
19 | |
20 #include "curses.h" | |
21 #include <ctype.h> | |
22 #include "rogue.h" | |
23 | |
24 /* | |
25 * let the hero get rid of some type of monster (but not a UNIQUE!) | |
26 */ | |
27 genocide() | |
28 { | |
29 register struct linked_list *ip; | |
30 register struct thing *mp; | |
31 register struct linked_list *nip; | |
32 register int num_monst = NUMMONST-NUMUNIQUE-1, /* cannot genocide uniques */ | |
33 pres_monst=1, | |
34 num_lines=2*(lines-3); | |
35 register int which_monst; | |
36 | |
37 which_monst = makemonster(FALSE, "Genocide", "wipe out"); | |
38 if (which_monst <= 0) { | |
39 msg(""); | |
40 return; | |
41 } | |
42 | |
43 /* Remove this monster from the present level */ | |
44 for (ip = mlist; ip; ip = nip) { | |
45 mp = THINGPTR(ip); | |
46 nip = next(ip); | |
47 if (mp->t_index == which_monst) { | |
48 killed(ip, FALSE, FALSE, TRUE); | |
49 } | |
50 } | |
51 | |
52 /* Remove from available monsters */ | |
53 monsters[which_monst].m_normal = FALSE; | |
54 monsters[which_monst].m_wander = FALSE; | |
55 mpos = 0; | |
56 msg("You have wiped out the %s.", monsters[which_monst].m_name); | |
57 } | |
58 | |
59 read_scroll(which, flag, is_scroll) | |
60 register int which; | |
61 int flag; | |
62 bool is_scroll; | |
63 { | |
64 register struct object *obj, *nobj; | |
65 register struct linked_list *item, *nitem; | |
66 register int i,j; | |
67 register char ch, nch; | |
68 bool cursed, blessed; | |
69 | |
70 blessed = FALSE; | |
71 cursed = FALSE; | |
72 item = NULL; | |
73 | |
74 if (which < 0) { | |
75 if (on(player, ISBLIND)) { | |
76 msg("You can't see to read anything"); | |
77 return; | |
78 } | |
79 if (on(player, ISINWALL)) { | |
80 msg("You can't see the scroll while inside rock!"); | |
81 return; | |
82 } | |
83 | |
84 /* This is a scroll or book. */ | |
85 if (player.t_action != C_READ) { | |
86 int units; | |
87 | |
88 item = get_item(pack, "read", READABLE, FALSE, FALSE); | |
89 | |
90 /* | |
91 * Make certain that it is somethings that we want to read | |
92 */ | |
93 if (item == NULL) | |
94 return; | |
95 | |
96 /* How long does it take to read? */ | |
97 units = usage_time(item); | |
98 if (units < 0) return; | |
99 | |
100 player.t_using = item; /* Remember what it is */ | |
101 player.t_no_move = units * movement(&player); | |
102 if ((OBJPTR(item))->o_type == SCROLL) player.t_action = C_READ; | |
103 else player.t_action = C_USE; | |
104 return; | |
105 } | |
106 | |
107 /* We have waited our time, let's quaff the potion */ | |
108 item = player.t_using; | |
109 player.t_using = NULL; | |
110 player.t_action = A_NIL; | |
111 | |
112 obj = OBJPTR(item); | |
113 /* remove it from the pack */ | |
114 inpack--; | |
115 detach(pack, item); | |
116 | |
117 msg("As you read the scroll, it vanishes."); | |
118 cursed = (obj->o_flags & ISCURSED) != 0; | |
119 blessed = (obj->o_flags & ISBLESSED) != 0; | |
120 | |
121 which = obj->o_which; | |
122 } | |
123 else { | |
124 cursed = flag & ISCURSED; | |
125 blessed = flag & ISBLESSED; | |
126 } | |
127 | |
128 | |
129 switch (which) { | |
130 case S_CONFUSE: | |
131 /* | |
132 * Scroll of monster confusion. Give him that power. | |
133 */ | |
134 msg("Your hands begin to glow red"); | |
135 turn_on(player, CANHUH); | |
136 when S_CURING: | |
137 /* | |
138 * A cure disease spell | |
139 */ | |
140 if (on(player, HASINFEST) || | |
141 on(player, HASDISEASE)|| | |
142 on(player, DOROT)) { | |
143 if (on(player, HASDISEASE)) { | |
144 extinguish(cure_disease); | |
145 cure_disease(); | |
146 } | |
147 if (on(player, HASINFEST)) { | |
148 msg(terse ? "You feel yourself improving." | |
149 : "You begin to feel yourself improving again."); | |
150 turn_off(player, HASINFEST); | |
151 infest_dam = 0; | |
152 } | |
153 if (on(player, DOROT)) { | |
154 msg("You feel your skin returning to normal."); | |
155 turn_off(player, DOROT); | |
156 } | |
157 } | |
158 else { | |
159 msg(nothing); | |
160 break; | |
161 } | |
162 if (is_scroll) s_know[S_CURING] = TRUE; | |
163 when S_LIGHT: | |
164 if (blue_light(blessed, cursed) && is_scroll) | |
165 s_know[S_LIGHT] = TRUE; | |
166 when S_HOLD: | |
167 if (cursed) { | |
168 /* | |
169 * This scroll aggravates all the monsters on the current | |
170 * level and sets them running towards the hero | |
171 */ | |
172 aggravate(TRUE, TRUE); | |
173 msg("You hear a high pitched humming noise."); | |
174 } | |
175 else if (blessed) { /* Hold all monsters on level */ | |
176 if (mlist == NULL) msg(nothing); | |
177 else { | |
178 register struct linked_list *mon; | |
179 register struct thing *th; | |
180 | |
181 for (mon = mlist; mon != NULL; mon = next(mon)) { | |
182 th = THINGPTR(mon); | |
183 turn_off(*th, ISRUN); | |
184 turn_on(*th, ISHELD); | |
185 } | |
186 msg("A sudden peace comes over the dungeon."); | |
187 } | |
188 } | |
189 else { | |
190 /* | |
191 * Hold monster scroll. Stop all monsters within two spaces | |
192 * from chasing after the hero. | |
193 */ | |
194 register int x,y; | |
195 register struct linked_list *mon; | |
196 bool gotone=FALSE; | |
197 | |
198 for (x = hero.x-2; x <= hero.x+2; x++) { | |
199 for (y = hero.y-2; y <= hero.y+2; y++) { | |
200 if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1) | |
201 continue; | |
202 if (isalpha(mvwinch(mw, y, x))) { | |
203 if ((mon = find_mons(y, x)) != NULL) { | |
204 register struct thing *th; | |
205 | |
206 gotone = TRUE; | |
207 th = THINGPTR(mon); | |
208 turn_off(*th, ISRUN); | |
209 turn_on(*th, ISHELD); | |
210 } | |
211 } | |
212 } | |
213 } | |
214 if (gotone) msg("A sudden peace surrounds you."); | |
215 else msg(nothing); | |
216 } | |
217 when S_SLEEP: | |
218 /* | |
219 * if cursed, you fall asleep | |
220 */ | |
221 if (is_scroll) s_know[S_SLEEP] = TRUE; | |
222 if (cursed) { | |
223 if (ISWEARING(R_ALERT)) | |
224 msg("You feel drowsy for a moment."); | |
225 else { | |
226 msg("You fall asleep."); | |
227 player.t_no_move += movement(&player)*(4 + rnd(SLEEPTIME)); | |
228 player.t_action = A_FREEZE; | |
229 } | |
230 } | |
231 else { | |
232 /* | |
233 * sleep monster scroll. | |
234 * puts all monsters within 2 spaces asleep | |
235 */ | |
236 register int x,y; | |
237 register struct linked_list *mon; | |
238 bool gotone=FALSE; | |
239 | |
240 for (x = hero.x-2; x <= hero.x+2; x++) { | |
241 for (y = hero.y-2; y <= hero.y+2; y++) { | |
242 if (y < 1 || x < 0 || y > lines - 3 || x > cols - 1) | |
243 continue; | |
244 if (isalpha(mvwinch(mw, y, x))) { | |
245 if ((mon = find_mons(y, x)) != NULL) { | |
246 register struct thing *th; | |
247 | |
248 th = THINGPTR(mon); | |
249 if (on(*th, ISUNDEAD)) | |
250 continue; | |
251 th->t_no_move += movement(th)*(SLEEPTIME+4); | |
252 th->t_action = A_FREEZE; | |
253 gotone = TRUE; | |
254 } | |
255 } | |
256 } | |
257 } | |
258 if (gotone) | |
259 msg("The monster(s) around you seem to have fallen asleep"); | |
260 else | |
261 msg(nothing); | |
262 } | |
263 when S_CREATE: | |
264 /* | |
265 * Create a monster | |
266 * First look in a circle around him, next try his room | |
267 * otherwise give up | |
268 */ | |
269 creat_mons(&player, (short) 0, TRUE); | |
270 light(&hero); | |
271 when S_IDENT: | |
272 /* | |
273 * if its blessed then identify everything in the pack | |
274 */ | |
275 if (blessed) { | |
276 msg("You feel more Knowledgeable!"); | |
277 idenpack(); | |
278 } | |
279 else { | |
280 /* | |
281 * Identify, let the rogue figure something out | |
282 */ | |
283 if (is_scroll && s_know[S_IDENT] != TRUE) { | |
284 msg("This scroll is an identify scroll"); | |
285 } | |
286 whatis(NULL); | |
287 } | |
288 if (is_scroll) s_know[S_IDENT] = TRUE; | |
289 when S_MAP: | |
290 /* | |
291 * Scroll of magic mapping. | |
292 */ | |
293 if (is_scroll && s_know[S_MAP] != TRUE) { | |
294 msg("Oh, now this scroll has a map on it."); | |
295 s_know[S_MAP] = TRUE; | |
296 } | |
297 overwrite(stdscr, hw); | |
298 /* | |
299 * Take all the things we want to keep hidden out of the window | |
300 */ | |
301 for (i = 1; i < lines-2; i++) | |
302 for (j = 0; j < cols; j++) | |
303 { | |
304 switch (nch = ch = CCHAR( mvwinch(hw, i, j) )) | |
305 { | |
306 case SECRETDOOR: | |
307 nch = secretdoor (i, j); | |
308 break; | |
309 case '-': | |
310 case '|': | |
311 case DOOR: | |
312 case PASSAGE: | |
313 case ' ': | |
314 case STAIRS: | |
315 if (mvwinch(mw, i, j) != ' ') | |
316 { | |
317 register struct thing *it; | |
318 | |
319 it = THINGPTR(find_mons(i, j)); | |
320 if (it && it->t_oldch == ' ') | |
321 it->t_oldch = nch; | |
322 } | |
323 break; | |
324 default: | |
325 nch = ' '; | |
326 } | |
327 if (nch != ch) | |
328 waddch(hw, nch); | |
329 } | |
330 /* | |
331 * Copy in what he has discovered | |
332 */ | |
333 overlay(cw, hw); | |
334 /* | |
335 * And set up for display | |
336 */ | |
337 overwrite(hw, cw); | |
338 when S_GFIND: | |
339 /* | |
340 * Scroll of gold detection | |
341 */ | |
342 { | |
343 int gtotal = 0; | |
344 | |
345 wclear(hw); | |
346 for (nitem = lvl_obj; nitem != NULL; nitem = next(nitem)) { | |
347 nobj = OBJPTR(nitem); | |
348 if (nobj->o_type == GOLD) { | |
349 gtotal += nobj->o_count; | |
350 mvwaddch(hw, nobj->o_pos.y, nobj->o_pos.x, GOLD); | |
351 } | |
352 } | |
353 for (nitem = mlist; nitem != NULL; nitem = next(nitem)) { | |
354 register struct linked_list *gitem; | |
355 register struct thing *th; | |
356 | |
357 th = THINGPTR(nitem); | |
358 if (on(*th, NODETECT)) continue; | |
359 for(gitem = th->t_pack; gitem != NULL; gitem = next(gitem)){ | |
360 nobj = OBJPTR(gitem); | |
361 if (nobj->o_type == GOLD) { | |
362 gtotal += nobj->o_count; | |
363 mvwaddch(hw, th->t_pos.y, th->t_pos.x, GOLD); | |
364 } | |
365 } | |
366 } | |
367 if (gtotal) { | |
368 if (is_scroll) s_know[S_GFIND] = TRUE; | |
369 msg("You begin to feel greedy and you sense gold."); | |
370 waddstr(msgw, morestr); | |
371 clearok(msgw, FALSE); | |
372 draw(msgw); | |
373 overlay(hw, cw); | |
374 draw(cw); | |
375 wait_for(' '); | |
376 msg(""); | |
377 break; | |
378 } | |
379 } | |
380 msg("You begin to feel a pull downward"); | |
381 when S_TELEP: | |
382 /* | |
383 * Scroll of teleportation: | |
384 * Make him disappear and reappear | |
385 */ | |
386 if (cursed) { | |
387 int old_max = cur_max; | |
388 | |
389 turns = (vlevel * 3) * LEVEL; | |
390 level = nfloors; | |
391 new_level(NORMLEV); | |
392 status(TRUE); | |
393 mpos = 0; | |
394 msg("You are banished to the lower regions."); | |
395 if (old_max == cur_max) /* if he's been here, make it harder */ | |
396 aggravate(TRUE, TRUE); | |
397 } | |
398 else if (blessed) { | |
399 int old_level, | |
400 much = rnd(4) - 4; | |
401 | |
402 old_level = level; | |
403 if (much != 0) { | |
404 level += much; | |
405 if (level < 1) | |
406 level = 1; | |
407 mpos = 0; | |
408 cur_max = level; | |
409 turns += much*LEVEL; | |
410 if (turns < 0) | |
411 turns = 0; | |
412 new_level(NORMLEV); /* change levels */ | |
413 if (level == old_level) | |
414 status(TRUE); | |
415 msg("You are whisked away to another region."); | |
416 } | |
417 } | |
418 else { | |
419 teleport(); | |
420 } | |
421 if (is_scroll) s_know[S_TELEP] = TRUE; | |
422 when S_SCARE: | |
423 /* | |
424 * A monster will refuse to step on a scare monster scroll | |
425 * if it is dropped. Thus reading it is a mistake and produces | |
426 * laughter at the poor rogue's boo boo. | |
427 */ | |
428 msg("You hear maniacal laughter in the distance."); | |
429 when S_REMOVE: | |
430 if (cursed) { /* curse all player's possessions */ | |
431 for (nitem = pack; nitem != NULL; nitem = next(nitem)) { | |
432 nobj = OBJPTR(nitem); | |
433 if (nobj->o_flags & ISBLESSED) | |
434 nobj->o_flags &= ~ISBLESSED; | |
435 else | |
436 nobj->o_flags |= ISCURSED; | |
437 } | |
438 msg("The smell of fire and brimstone fills the air."); | |
439 } | |
440 else if (blessed) { | |
441 for (nitem = pack; nitem != NULL; nitem = next(nitem)) { | |
442 nobj = OBJPTR(nitem); | |
443 nobj->o_flags &= ~ISCURSED; | |
444 } | |
445 msg("Your pack glistens brightly"); | |
446 } | |
447 else { | |
448 nitem = get_item(pack, "remove the curse on",ALL,FALSE,FALSE); | |
449 if (nitem != NULL) { | |
450 nobj = OBJPTR(nitem); | |
451 nobj->o_flags &= ~ISCURSED; | |
452 msg("Removed the curse from %s",inv_name(nobj,TRUE)); | |
453 } | |
454 } | |
455 if (is_scroll) s_know[S_REMOVE] = TRUE; | |
456 when S_PETRIFY: | |
457 switch (mvinch(hero.y, hero.x)) { | |
458 case TRAPDOOR: | |
459 case DARTTRAP: | |
460 case TELTRAP: | |
461 case ARROWTRAP: | |
462 case SLEEPTRAP: | |
463 case BEARTRAP: | |
464 { | |
465 register int i; | |
466 | |
467 /* Find the right trap */ | |
468 for (i=0; i<ntraps && !ce(traps[i].tr_pos, hero); i++); | |
469 ntraps--; | |
470 | |
471 if (!ce(traps[i].tr_pos, hero)) | |
472 msg("What a strange trap!"); | |
473 else { | |
474 while (i < ntraps) { | |
475 traps[i] = traps[i + 1]; | |
476 i++; | |
477 } | |
478 } | |
479 } | |
480 goto pet_message; | |
481 case DOOR: | |
482 case SECRETDOOR: | |
483 case FLOOR: | |
484 case PASSAGE: | |
485 pet_message: msg("The dungeon begins to rumble and shake!"); | |
486 addch(WALL); | |
487 | |
488 /* If the player is phased, unphase him */ | |
489 if (on(player, CANINWALL)) { | |
490 extinguish(unphase); | |
491 turn_off(player, CANINWALL); | |
492 msg("Your dizzy feeling leaves you."); | |
493 } | |
494 | |
495 /* Mark the player as in a wall */ | |
496 turn_on(player, ISINWALL); | |
497 break; | |
498 default: | |
499 msg(nothing); | |
500 } | |
501 when S_GENOCIDE: | |
502 msg("You have been granted the boon of genocide!--More--"); | |
503 wait_for(' '); | |
504 msg(""); | |
505 genocide(); | |
506 if (is_scroll) s_know[S_GENOCIDE] = TRUE; | |
507 when S_PROTECT: { | |
508 struct linked_list *ll; | |
509 struct object *lb; | |
510 bool did_it = FALSE; | |
511 msg("You are granted the power of protection."); | |
512 if ((ll=get_item(pack,"protect",PROTECTABLE,FALSE,FALSE)) != NULL) { | |
513 lb = OBJPTR(ll); | |
514 mpos = 0; | |
515 if (cursed) { | |
516 switch(lb->o_type) { /* ruin it completely */ | |
517 case RING: if (lb->o_ac > 0) { | |
518 if (is_current(lb)) { | |
519 switch (lb->o_which) { | |
520 case R_ADDWISDOM: | |
521 pstats.s_wisdom -= lb->o_ac; | |
522 when R_ADDINTEL: | |
523 pstats.s_intel -= lb->o_ac; | |
524 when R_ADDSTR: | |
525 pstats.s_str -= lb->o_ac; | |
526 when R_ADDHIT: | |
527 pstats.s_dext -= lb->o_ac; | |
528 } | |
529 } | |
530 did_it = TRUE; | |
531 lb->o_ac = 0; | |
532 } | |
533 when ARMOR: if (lb->o_ac > 10) { | |
534 did_it = TRUE; | |
535 lb->o_ac = 10; | |
536 } | |
537 when STICK: if (lb->o_charges > 0) { | |
538 did_it = TRUE; | |
539 lb->o_charges = 0; | |
540 } | |
541 when WEAPON:if (lb->o_hplus > 0) { | |
542 did_it = TRUE; | |
543 lb->o_hplus = 0; | |
544 } | |
545 if (lb->o_dplus > 0) { | |
546 did_it = TRUE; | |
547 lb->o_dplus = 0; | |
548 } | |
549 } | |
550 if (lb->o_flags & ISPROT) { | |
551 did_it = TRUE; | |
552 lb->o_flags &= ~ISPROT; | |
553 } | |
554 if (lb->o_flags & ISBLESSED) { | |
555 did_it = TRUE; | |
556 lb->o_flags &= ~ISBLESSED; | |
557 } | |
558 if (did_it) | |
559 msg("Your %s glows red for a moment",inv_name(lb,TRUE)); | |
560 else { | |
561 msg(nothing); | |
562 break; | |
563 } | |
564 } | |
565 else { | |
566 lb->o_flags |= ISPROT; | |
567 msg("Protected %s.",inv_name(lb,TRUE)); | |
568 } | |
569 } | |
570 if (is_scroll) s_know[S_PROTECT] = TRUE; | |
571 } | |
572 when S_MAKEIT: | |
573 msg("You have been endowed with the power of creation."); | |
574 if (is_scroll) s_know[S_MAKEIT] = TRUE; | |
575 create_obj(TRUE, 0, 0); | |
576 when S_ALLENCH: { | |
577 struct linked_list *ll; | |
578 struct object *lb; | |
579 int howmuch, flags; | |
580 if (is_scroll && s_know[S_ALLENCH] == FALSE) { | |
581 msg("You are granted the power of enchantment."); | |
582 msg("You may enchant anything(weapon,ring,armor,scroll,potion)"); | |
583 } | |
584 if ((ll = get_item(pack, "enchant", ALL, FALSE, FALSE)) != NULL) { | |
585 lb = OBJPTR(ll); | |
586 lb->o_flags &= ~ISCURSED; | |
587 if (blessed) { | |
588 howmuch = 2; | |
589 flags = ISBLESSED; | |
590 } | |
591 else if (cursed) { | |
592 howmuch = -1; | |
593 flags = ISCURSED; | |
594 } | |
595 else { | |
596 howmuch = 1; | |
597 flags = ISBLESSED; | |
598 } | |
599 switch(lb->o_type) { | |
600 case RING: | |
601 if (lb->o_ac + howmuch > MAXENCHANT) { | |
602 msg("The enchantment doesn't seem to work!"); | |
603 break; | |
604 } | |
605 lb->o_ac += howmuch; | |
606 if (lb==cur_ring[LEFT_1] || lb==cur_ring[LEFT_2] || | |
607 lb==cur_ring[LEFT_3] || lb==cur_ring[LEFT_4] || | |
608 lb==cur_ring[RIGHT_1] || lb==cur_ring[RIGHT_2] || | |
609 lb==cur_ring[RIGHT_3] || lb==cur_ring[RIGHT_4]) { | |
610 switch (lb->o_which) { | |
611 case R_ADDWISDOM: pstats.s_wisdom += howmuch; | |
612 when R_ADDINTEL: pstats.s_intel += howmuch; | |
613 when R_ADDSTR: pstats.s_str += howmuch; | |
614 when R_ADDHIT: pstats.s_dext += howmuch; | |
615 } | |
616 } | |
617 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
618 when ARMOR: | |
619 if ((armors[lb->o_which].a_class - lb->o_ac) + | |
620 howmuch > MAXENCHANT) { | |
621 msg("The enchantment doesn't seem to work!"); | |
622 break; | |
623 } | |
624 else | |
625 lb->o_ac -= howmuch; | |
626 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
627 when STICK: | |
628 lb->o_charges += (howmuch * 10) + rnd(5); | |
629 if (lb->o_charges < 0) | |
630 lb->o_charges = 0; | |
631 if (EQUAL(ws_type[lb->o_which], "staff")) { | |
632 if (lb->o_charges > 100) | |
633 lb->o_charges = 100; | |
634 } | |
635 else { | |
636 if (lb->o_charges > 50) | |
637 lb->o_charges = 50; | |
638 } | |
639 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
640 when WEAPON: | |
641 if(lb->o_hplus+lb->o_dplus+howmuch > MAXENCHANT * 2){ | |
642 msg("The enchantment doesn't seem to work!"); | |
643 break; | |
644 } | |
645 if (rnd(100) < 50) | |
646 lb->o_hplus += howmuch; | |
647 else | |
648 lb->o_dplus += howmuch; | |
649 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
650 when MM: | |
651 switch (lb->o_which) { | |
652 case MM_BRACERS: | |
653 if (lb->o_ac + howmuch > MAXENCHANT) { | |
654 msg("The enchantment doesn't seem to work!"); | |
655 break; | |
656 } | |
657 else lb->o_ac += howmuch; | |
658 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
659 when MM_PROTECT: | |
660 if (lb->o_ac + howmuch > MAXENCHANT/2) { | |
661 msg("The enchantment doesn't seem to work!"); | |
662 break; | |
663 } | |
664 else lb->o_ac += howmuch; | |
665 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
666 } | |
667 lb->o_flags |= flags; | |
668 when POTION: | |
669 case SCROLL: | |
670 default: | |
671 lb->o_flags |= flags; | |
672 msg("Enchanted %s.",inv_name(lb,TRUE)); | |
673 } | |
674 } | |
675 if (is_scroll) s_know[S_ALLENCH] = TRUE; | |
676 if (!is_scroll) { | |
677 pstats.s_const--; | |
678 max_stats.s_const--; | |
679 if (pstats.s_const <= 0) | |
680 death(D_CONSTITUTION); | |
681 msg("You feel less healthy now"); | |
682 } | |
683 } | |
684 when S_FINDTRAPS: | |
685 for (i=0; i<ntraps; i++) { | |
686 if (!(traps[i].tr_flags & ISFOUND)) { | |
687 traps[i].tr_flags |= ISFOUND; | |
688 if (cansee(traps[i].tr_pos.y, traps[i].tr_pos.x)) | |
689 mvwaddch(cw,traps[i].tr_pos.y,traps[i].tr_pos.x, | |
690 traps[i].tr_type); | |
691 } | |
692 } | |
693 if (ntraps > 0) { | |
694 msg("You sense the presence of traps"); | |
695 if (is_scroll) s_know[S_FINDTRAPS] = TRUE; | |
696 } | |
697 else | |
698 msg(nothing); | |
699 | |
700 when S_RUNES: | |
701 { | |
702 register struct linked_list *sitem; | |
703 | |
704 msg("The scroll explodes in a ball of fire!"); | |
705 if (on(player, NOFIRE)) { | |
706 msg("The fire does not seem to affect you"); | |
707 break; | |
708 } | |
709 explode(&player); | |
710 if (pstats.s_hpt <= 0) | |
711 death(D_SCROLL); | |
712 for (sitem = pack; sitem != NULL; sitem = nitem) { | |
713 nitem = next(sitem); /* in case we delete it */ | |
714 nobj = OBJPTR(sitem); | |
715 /* | |
716 * check for loss of all scrolls and give them | |
717 * a save versus fire | |
718 */ | |
719 if (nobj->o_type == SCROLL && roll(1,20) < 19) { | |
720 msg("%s burns up!", inv_name(nobj, TRUE)); | |
721 inpack--; | |
722 detach(pack, sitem); | |
723 o_discard(sitem); | |
724 } | |
725 } | |
726 } | |
727 | |
728 when S_CHARM: | |
729 { | |
730 bool spots[9]; | |
731 int x, y, spot, count, numcharmed, something, bonus; | |
732 struct linked_list *item; | |
733 register struct thing *tp; | |
734 | |
735 /* Initialize the places where we look around us */ | |
736 for (i=0; i<9; i++) spots[i] = FALSE; | |
737 count = 0; /* No spots tried yet */ | |
738 numcharmed = 0; /* Nobody charmed yet */ | |
739 something = 0; /* Nothing has been seen yet */ | |
740 bonus = 0; /* no bonus yet */ | |
741 | |
742 /* Now look around us randomly for a charmee */ | |
743 while (count < 9) { | |
744 do { | |
745 spot = rnd(9); | |
746 } while (spots[spot] == TRUE); | |
747 | |
748 /* We found a place */ | |
749 count++; | |
750 spots[spot] = TRUE; | |
751 y = hero.y - 1 + (spot / 3); | |
752 x = hero.x - 1 + (spot % 3); | |
753 | |
754 /* Be sure to stay on the board! */ | |
755 if (x < 0 || x >= cols || (y < 1) || (y >= lines - 2)) | |
756 continue; | |
757 | |
758 /* Is there a monster here? */ | |
759 if (!isalpha(mvwinch(mw, y, x))) continue; | |
760 | |
761 /* What kind is it? */ | |
762 item = find_mons(y, x); | |
763 if (item == NULL) continue; | |
764 | |
765 tp = THINGPTR(item); | |
766 if (on(*tp,ISCHARMED) || on(*tp,ISUNIQUE) || on(*tp,ISUNDEAD)) | |
767 continue; | |
768 | |
769 /* Will the monster be charmed? */ | |
770 if (blessed) bonus -= 3; | |
771 bonus -= (pstats.s_charisma - 13) / 3; | |
772 if ((player.t_ctype==C_PALADIN || player.t_ctype==C_RANGER) && | |
773 off(*tp, ISMEAN)) | |
774 bonus -= 3; | |
775 if (save(VS_MAGIC, tp, bonus)) continue; | |
776 | |
777 /* We got him! */ | |
778 numcharmed++; | |
779 | |
780 /* Let the player know (maybe) */ | |
781 if ((off(*tp, ISINVIS) || on(player, CANSEE)) && | |
782 (off(*tp, ISSHADOW) || on(player, CANSEE)) && | |
783 cansee(y, x)) { | |
784 if (on(*tp, CANSURPRISE)) { | |
785 turn_off(*tp, CANSURPRISE); | |
786 msg("Woah!"); | |
787 } | |
788 msg("The eyes of %s glaze over!", | |
789 prname(monster_name(tp), FALSE)); | |
790 something++; | |
791 } | |
792 | |
793 /* Charm him and turn off any side effects */ | |
794 turn_on(*tp, ISCHARMED); | |
795 runto(tp, &hero); | |
796 tp->t_action = A_NIL; | |
797 | |
798 /* If monster was suffocating us, stop it */ | |
799 if (on(*tp, DIDSUFFOCATE)) { | |
800 turn_off(*tp, DIDSUFFOCATE); | |
801 extinguish(suffocate); | |
802 } | |
803 | |
804 /* If monster held us, stop it */ | |
805 if (on(*tp, DIDHOLD) && (--hold_count == 0)) | |
806 turn_off(player, ISHELD); | |
807 turn_off(*tp, DIDHOLD); | |
808 | |
809 /* If frightened of this monster, stop */ | |
810 if (on(player, ISFLEE) && | |
811 player.t_dest == &tp->t_pos) turn_off(player, ISFLEE); | |
812 | |
813 if ((blessed && numcharmed >= 2) || numcharmed > 0) break; | |
814 } | |
815 | |
816 if (something == 0) msg(nothing); | |
817 } | |
818 | |
819 otherwise: | |
820 msg("What a puzzling scroll!"); | |
821 return; | |
822 } | |
823 look(TRUE, FALSE); /* put the result of the scroll on the screen */ | |
824 status(FALSE); | |
825 if (is_scroll && item && s_know[which] && s_guess[which]) | |
826 { | |
827 free(s_guess[which]); | |
828 s_guess[which] = NULL; | |
829 } | |
830 else if (is_scroll && | |
831 !s_know[which] && | |
832 item && | |
833 askme && | |
834 (obj->o_flags & ISKNOW) == 0 && | |
835 (obj->o_flags & ISPOST) == 0 && | |
836 s_guess[which] == NULL) { | |
837 nameitem(item, FALSE); | |
838 } | |
839 if (item != NULL) o_discard(item); | |
840 updpack(TRUE, &player); | |
841 } |