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