Annotation of early-roguelike/urogue/move.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: move.c - Hero movement commands
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 <ctype.h>
21: #include "rogue.h"
22:
23: /*
24: do_run()
25: Start the hero running
26: */
27:
28: void
29: do_run(char ch)
30: {
31: running = TRUE;
32: after = FALSE;
33: runch = ch;
34:
35: if (doorstop && !on(player, ISBLIND))
36: {
37: door_stop = TRUE;
38: firstmove = TRUE;
39: }
40: }
41:
42: /*
43: step_ok()
44: returns true if it is ok for type to step on ch flgptr will be
45: NULL if we don't know what the monster is yet!
46: */
47:
48: int
49: step_ok(int y, int x, int can_on_monst, struct thing *flgptr)
50: {
51: struct linked_list *item;
52: char ch;
53:
54: /* What is here? Don't check monster window if MONSTOK is set */
55:
56: if (can_on_monst == MONSTOK)
57: ch = CCHAR( mvinch(y, x) );
58: else
59: ch = winat(y, x);
60:
61: switch (ch)
62: {
63: case ' ':
64: case '|':
65: case '-':
66: case SECRETDOOR:
67: if (flgptr && on(*flgptr, CANINWALL))
68: return(TRUE);
69:
70: return(FALSE);
71:
72: case SCROLL:
73: /*
74: * If it is a scroll, it might be a scare monster scroll so
75: * we need to look it up to see what type it is.
76: */
77:
78: if (flgptr && flgptr->t_ctype == C_MONSTER)
79: {
80: item = find_obj(y, x);
81:
82: if (item != NULL && (OBJPTR(item))->o_type == SCROLL
83: && (OBJPTR(item))->o_which == S_SCARE
84: && rnd(flgptr->t_stats.s_intel) < 12)
85: return(FALSE); /* All but smart ones are scared */
86: }
87: return(TRUE);
88:
89: default:
90: return(!isalpha(ch));
91: }
92: }
93:
94: /*
95: corr_move()
96: Check to see that a move is legal. If so, return correct
97: character. If not, if player came from a legal place, then try to turn
98: him.
99: */
100:
101: void
102: corr_move(int dy, int dx)
103: {
104: char ch;
105: short legal = 0; /* Number of legal alternatives */
106: int y = 0, x = 0; /* Holds legal new position */
107: int *ny, *nx; /* Point to which direction to change */
108:
109: /* New position */
110:
111: player.t_nxtpos.y = hero.y + dy;
112: player.t_nxtpos.x = hero.x + dx;
113:
114: /* A bad diagonal move is illegal */
115:
116: if (!diag_ok(&hero, &player.t_nxtpos, &player))
117: return;
118:
119: /* If it is a legal move, just return */
120:
121: if (player.t_nxtpos.x >= 0 && player.t_nxtpos.x < COLS && player.t_nxtpos.y > 0 && player.t_nxtpos.y < LINES - 2)
122: {
123: ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
124:
125: switch (ch)
126: {
127: case ' ':
128: case '|':
129: case '-':
130: break;
131: default:
132: return;
133: }
134: }
135:
136: /* Check the legal alternatives */
137:
138: if (dy == 0)
139: {
140: ny = &dy;
141: nx = &dx;
142: }
143: else
144: {
145: ny = &dx;
146: nx = &dy;
147: }
148:
149: for (*nx = 0, *ny = -1; *ny < 2; *ny += 2)
150: {
151: /* New position */
152: player.t_nxtpos.y = hero.y + dy;
153: player.t_nxtpos.x = hero.x + dx;
154:
155: if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y > LINES - 3)
156: continue;
157:
158: ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
159:
160: switch (ch)
161: {
162: case ' ':
163: case '|':
164: case '-':
165: break;
166: default:
167: legal++;
168: y = dy;
169: x = dx;
170: }
171: }
172:
173: /* If we have 2 legal moves, make no change */
174:
175: if (legal != 1)
176: return;
177:
178: /* Make the change */
179:
180: if (y == 0) /* Move horizontally */
181: {
182: if (x == 1)
183: runch = 'l';
184: else
185: runch = 'h';
186: }
187: else /* Move vertically */
188: {
189: if (y == 1)
190: runch = 'j';
191: else
192: runch = 'k';
193: }
194:
195: return;
196: }
197:
198:
199: /*
200: do_move()
201: Check to see that a move is legal. If it is handle the
202: consequences (fighting, picking up, etc.)
203: */
204:
205: void
206: do_move(int dy, int dx)
207: {
208: char ch;
209: coord old_hero;
210: char hch;
211:
212: firstmove = FALSE;
213:
214: if (player.t_no_move)
215: {
216: player.t_no_move--;
217: msg("You are still stuck in the bear trap.");
218: return;
219: }
220:
221: /* Do a confused move (maybe) */
222:
223: if ((rnd(100) < 80 && on(player, ISHUH)) ||
224: (is_wearing(R_DELUSION) && rnd(100) < 25) ||
225: on(player, STUMBLER) && rnd(40) == 0)
226: player.t_nxtpos = rndmove(&player);
227: else
228: {
229: player.t_nxtpos.y = hero.y + dy;
230: player.t_nxtpos.x = hero.x + dx;
231: }
232:
233: /*
234: * Check if he tried to move off the screen or make an illegal
235: * diagonal move, and stop him if he did.
236: */
237:
238: if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y >= LINES - 2
239: || !diag_ok(&hero, &player.t_nxtpos, &player))
240: {
241: after = fighting = running = FALSE;
242: return;
243: }
244:
245: if (running && ce(hero, player.t_nxtpos))
246: after = running = FALSE;
247:
248: ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
249:
250: if (isalpha(ch))
251: debug("Moving onto monster %c",ch);
252:
253: /* Take care of hero trying to move close to something frightening */
254:
255: if (on(player, ISFLEE))
256: {
257: if (rnd(10) < 1)
258: {
259: turn_off(player, ISFLEE);
260: msg("You regain your composure.");
261: }
262: else if (DISTANCE(player.t_nxtpos, player.t_chasee->t_pos) <
263: DISTANCE(hero,player.t_chasee->t_pos))
264: return;
265: }
266:
267: /* Take care of hero being held */
268:
269: if (on(player, ISHELD) && !isalpha(ch))
270: {
271: if (rnd(pstats.s_str) > 14)
272: {
273: msg("You break free of the hold.");
274:
275: if (--hold_count == 0)
276: turn_off(player, ISHELD);
277: }
278: else
279: {
280: msg("You are being held.");
281: return;
282: }
283: }
284:
285: /* Might lose disguise */
286:
287: if (on(player, ISDISGUISE) && rnd(11 * pstats.s_dext) == 0)
288: {
289: extinguish_fuse(FUSE_UNDISGUISE);
290: undisguise(NULL);
291: }
292:
293: /* assume he's not in a wall */
294:
295: if (!isalpha(ch))
296: turn_off(player, ISINWALL);
297:
298: hch = CCHAR( mvinch(hero.y, hero.x) ); /* Where hero was */
299: old_hero = hero; /* Save hero's old position */
300:
301: switch (ch)
302: {
303: case ' ':
304: case '|':
305: case '-':
306: case SECRETDOOR:
307: if (off(player, CANINWALL))
308: {
309: after = running = FALSE;
310: return;
311: }
312: else if (running)
313: {
314: after = running = FALSE;
315: return;
316: }
317: turn_on(player, ISINWALL);
318: break;
319:
320: case TRAPDOOR:
321: case TELTRAP:
322: case BEARTRAP:
323: case SLEEPTRAP:
324: case ARROWTRAP:
325: case DARTTRAP:
326: case POOL:
327: case MAZETRAP:
328: case FIRETRAP:
329: case POISONTRAP:
330: case LAIR:
331: case RUSTTRAP:
332: ch = be_trapped(&player, player.t_nxtpos);
333:
334: if (!is_wearing(R_LEVITATION) && off(player, CANFLY) &&
335: (old_hero.x != hero.x || old_hero.y != hero.y
336: || pool_teleport))
337: {
338: pool_teleport = FALSE;
339: return;
340: }
341:
342: break;
343:
344: case GOLD:
345: case POTION:
346: case SCROLL:
347: case FOOD:
348: case WEAPON:
349: case ARMOR:
350: case RING:
351: case ARTIFACT:
352: case STICK:
353: running = FALSE;
354: take = ch;
355: break;
356:
357: default:
358: break;
359: }
360:
361: if (ch == FIRETRAP)
362: light(&hero);
363:
364: hero = player.t_nxtpos; /* Move the hero */
365:
366: /* adjust lighting */
367:
368: if (roomin(hero) == NULL && (hch == '-' || hch == '|' ||
369: hch == DOOR || hch == SECRETDOOR))
370: {
371: /* Leaving a room -- darken it */
372: struct room *rp = roomin(old_hero);
373: int is_lit = FALSE;
374:
375: if (!(rp->r_flags & ISDARK))
376: is_lit = TRUE;
377:
378: rp->r_flags |= ISDARK; /* Fake darkness */
379: light(&old_hero);
380:
381: if (is_lit)
382: rp->r_flags &= ~ISDARK; /* Restore light state */
383: }
384: else if (ch == DOOR || ch == SECRETDOOR || ch == '|' || ch == '-')
385: {
386: /* Entering a room */
387: running = FALSE;
388: if (hch != '|' && hch != '-')
389: light(&hero); /* knows whether the hero can see things in */
390: }
391:
392: /* handle other situations */
393:
394: if (ch == STAIRS)
395: running = FALSE;
396: else if (ch == POST)
397: {
398: running = FALSE;
399: new_level(POSTLEV,0);
400: return;
401: }
402: else if (isalpha(ch))
403: {
404: struct linked_list *mp;
405: struct thing *tp;
406: char t;
407:
408: running = FALSE;
409:
410: mp = find_mons(hero.y, hero.x);
411:
412: if (mp == NULL)
413: return;
414:
415: tp = THINGPTR(mp);
416:
417: if (good_monster(*tp)) /* Exchange places with your buddy */
418: {
419: mvwaddch(cw, old_hero.y, old_hero.x, ch);
420: mvwaddch(mw, old_hero.y, old_hero.x, ch);
421: mvwaddch(mw, hero.y, hero.x, ' ');
422: mvwaddch(cw, hero.y, hero.x, tp->t_oldch);
423:
424: (*tp).t_pos.x = old_hero.x; /* Update monster position variables */
425: (*tp).t_pos.y = old_hero.y;
426: (*tp).t_oldpos.x = old_hero.x;
427: (*tp).t_oldpos.y = old_hero.y;
428:
429: t = (*tp).t_oldch;
430: (*tp).t_oldch = player.t_oldch;
431: player.t_oldch = t;
432:
433: turn_on(*tp, ISRUN);
434:
435: mvwaddch(cw, hero.y, hero.x, PLAYER);
436:
437: /* make sure that the room shows OK */
438:
439: light(&hero);
440:
441: wrefresh(cw);
442: return;
443: }
444: else
445: {
446: hero = old_hero; /* Restore hero -- we'll fight instead of move */
447:
448: /* make sure that the room shows OK */
449: light(&hero);
450:
451: fight(&player.t_nxtpos, cur_weapon, NOTHROWN);
452:
453: return;
454: }
455: }
456: else
457: fighting = FALSE;
458:
459: ch = winat(old_hero.y, old_hero.x);
460: mvwaddch(cw, old_hero.y, old_hero.x, ch);
461: mvwaddch(cw, hero.y, hero.x, PLAYER);
462: }
463:
464: /*
465: light()
466: Called to illuminate a room. If it is dark, remove anything that might
467: move.
468: */
469:
470: void
471: light(coord *cp)
472: {
473: struct room *rp;
474: int j, k, x, y;
475: char ch, rch;
476: struct linked_list *item;
477: int jlow, jhigh, klow, khigh; /* Boundaries of lit area */
478:
479: if ((rp = roomin(*cp)) != NULL && !on(player, ISBLIND))
480: {
481:
482: /* is he wearing ring of illumination and in same room? */
483:
484: if ((is_wearing(R_LIGHT) || on(player, ISELECTRIC)) &&
485: cp == &hero)
486: rp->r_flags &= ~ISDARK;
487:
488: /* If we are in a maze, don't look at the whole room (level) */
489:
490: if (levtype == MAZELEV)
491: {
492: jlow = max(0, hero.y - 2 - rp->r_pos.y);
493: jhigh = min(rp->r_max.y, hero.y + 2 - rp->r_pos.y + 1);
494: klow = max(0, hero.x - 2 - rp->r_pos.x);
495: khigh = min(rp->r_max.x, hero.x + 2 - rp->r_pos.x + 1);
496: }
497: else
498: {
499: jlow = klow = 0;
500: jhigh = rp->r_max.y;
501: khigh = rp->r_max.x;
502: }
503:
504: for (j = 0; j < rp->r_max.y; j++)
505: {
506: for (k = 0; k < rp->r_max.x; k++)
507: {
508: /* Is this in the given area -- needed for maze */
509:
510: if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh))
511: continue;
512:
513: y = rp->r_pos.y + j;
514: x = rp->r_pos.x + k;
515:
516: ch = show(y, x);
517: wmove(cw, y, x);
518:
519: /* Figure out how to display a secret door */
520:
521: if (ch == SECRETDOOR)
522: {
523: if (j == 0 || j == rp->r_max.y - 1)
524: ch = '-';
525: else
526: ch = '|';
527: }
528:
529: /*
530: * For monsters, if they were previously not
531: * seen and now can be seen, or vice-versa,
532: * make sure that will happen.
533: */
534:
535: if (isalpha(ch))
536: {
537: struct thing *tp;
538:
539: item = wake_monster(y, x);
540:
541: if (item == NULL)
542: continue;
543:
544: tp = THINGPTR(item);
545:
546: /* Previously not seen -- now can see it */
547:
548: if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x))
549: tp->t_oldch = CCHAR( mvinch(y, x) );
550:
551: /* Previously seen -- now can't see it */
552:
553: else if (off(player, ISBLIND) && tp->t_oldch != ' ' &&
554: !cansee(tp->t_pos.y, tp->t_pos.x))
555: tp->t_oldch = ' ';
556: }
557:
558: /*
559: * If the room is a dark room, we might want
560: * to remove monsters and the like from it
561: * (since they might move). A dark room or
562: * not in line-of-sight in a maze.
563: */
564:
565: if (((rp->r_flags & ISDARK) &&
566: !(rp->r_flags & HASFIRE)) ||
567: (levtype == MAZELEV &&
568: !maze_view(y, x)))
569: {
570: rch = CCHAR( mvwinch(cw, y, x) );
571:
572: switch (rch)
573: {
574: case DOOR:
575: case STAIRS:
576: case TRAPDOOR:
577: case TELTRAP:
578: case BEARTRAP:
579: case SLEEPTRAP:
580: case ARROWTRAP:
581: case DARTTRAP:
582: case POOL:
583: case MAZETRAP:
584: case FIRETRAP:
585: case POISONTRAP:
586: case LAIR:
587: case RUSTTRAP:
588: case POST:
589: case '|':
590: case '-':
591: case ' ':
592: ch = rch;
593: break;
594:
595: case FLOOR:
596: ch = (on(player, ISBLIND) ? FLOOR : ' ');
597: break;
598: default:
599: ch = ' ';
600: break;
601: }
602: }
603: mvwaddch(cw, y, x, ch);
604: }
605: }
606: }
607: }
608:
609: /*
610: blue_light()
611: magically light up a room (or level or make it dark)
612: */
613:
614: int
615: blue_light(int flags)
616: {
617: struct room *rp;
618: int blessed = (flags & ISBLESSED);
619: int cursed = (flags & ISCURSED);
620: int ret_val = FALSE; /* Whether or not affect is known */
621:
622: rp = roomin(hero); /* What room is hero in? */
623:
624: /* Darken the room if the magic is cursed */
625:
626: if (cursed)
627: {
628: if ((rp == NULL) || (rp->r_flags & ISDARK))
629: nothing_message(flags);
630: else
631: {
632: if (!(rp->r_flags & HASFIRE))
633: msg("The room suddenly goes dark.");
634: else
635: nothing_message(flags);
636:
637: rp->r_flags |= ISDARK;
638: ret_val = TRUE;
639: }
640: }
641: else
642: {
643: ret_val = TRUE;
644:
645: if (rp && (rp->r_flags & ISDARK) && !(rp->r_flags & HASFIRE))
646: {
647: msg("The room is lit by a %s blue light.",
648: blessed ? "bright" : "shimmering");
649: }
650: else if (winat(hero.y, hero.x) == PASSAGE)
651: msg("The corridor glows %sand then fades.", blessed ? "brightly " : "");
652: else
653: {
654: ret_val = FALSE;
655: nothing_message(flags);
656: }
657:
658: if (blessed)
659: {
660: short i; /* Index through rooms */
661:
662: for (i = 0; i < MAXROOMS; i++)
663: rooms[i].r_flags &= ~ISDARK;
664: }
665: else if (rp)
666: rp->r_flags &= ~ISDARK;
667: }
668:
669: /* Light the room and put the player back up */
670:
671: light(&hero);
672: mvwaddch(cw, hero.y, hero.x, PLAYER);
673:
674: return (ret_val);
675: }
676:
677: /*
678: show()
679: returns what a certain thing will display as to the un-initiated
680: */
681:
682: char
683: show(int y, int x)
684: {
685: char ch = winat(y, x);
686: struct linked_list *it;
687: struct thing *tp;
688:
689: if (isatrap(ch))
690: {
691: struct trap *trp = trap_at(y, x);
692: return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show;
693: }
694: else if (isalpha(ch))
695: {
696: if ((it = find_mons(y, x)) == NULL)
697: {
698: debug("Can't find monster in move.");
699: return ' ';
700: }
701: tp = THINGPTR(it);
702:
703: if (on(*tp, ISDISGUISE))
704: ch = tp->t_disguise; /* As a mimic */
705: else if (on(*tp, ISINVIS) || (on(*tp, ISSHADOW) &&
706: rnd(100) < 90) || on(*tp, CANSURPRISE))
707: {
708: if (off(player, CANSEE) || on(*tp, CANSURPRISE))
709: ch = CCHAR( mvwinch(stdscr, y, x) ); /* Invisible */
710: }
711: else if (on(*tp, CANINWALL))
712: {
713: char tch;
714:
715: tch = CCHAR( mvwinch(stdscr, y, x) );
716:
717: if (tch == WALL || tch == '-' || tch == '|')
718: ch = CCHAR( winch(stdscr) ); /* As Xorn */
719: }
720: }
721: return(ch);
722: }
723:
724: /*
725: be_trapped()
726: The guy stepped on a trap.... Make him pay.
727: */
728:
729: char
730: be_trapped(struct thing *th, coord tc)
731: {
732: struct trap *tp;
733: char ch, *mname = NULL;
734: int is_player = (th == &player), can_see = cansee(tc.y, tc.x);
735: struct linked_list *mitem = NULL;
736:
737: tp = trap_at(tc.y, tc.x);
738: ch = tp->tr_type;
739:
740: if (!is_player)
741: {
742: mitem = find_mons(th->t_pos.y, th->t_pos.x);
743: mname = monsters[th->t_index].m_name;
744:
745: /* Flying monsters do not set off traps */
746:
747: if (!mitem || (on(*th, CANFLY) &&
748: (ch == BEARTRAP || ch == MAZETRAP || ch == TRAPDOOR
749: || ch == ARROWTRAP || ch == DARTTRAP)))
750: {
751: debug("%s avoided trap.", mname);
752: return(ch);
753: }
754: }
755: else
756: {
757: short thief_bonus = -50;
758:
759: count = running = FALSE;
760: mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type);
761:
762: if (no_command)
763: return(ch);
764:
765: if (player.t_ctype == C_THIEF || player.t_ctype == C_NINJA)
766: thief_bonus = 10;
767:
768: if (((is_wearing(R_LEVITATION) || on(player, CANFLY)) &&
769: (ch != FIRETRAP ||
770: (ch == FIRETRAP && !(tp->tr_flags & ISFOUND))))
771: || (moving && (tp->tr_flags & ISFOUND) && rnd(100) <
772: thief_bonus + 2 * pstats.s_dext + 5 * pstats.s_lvl) &&
773: (ch == BEARTRAP || ch == MAZETRAP || ch == TRAPDOOR
774: || ch == ARROWTRAP || ch == DARTTRAP))
775: {
776: static char trname[1024];
777: msg(tr_name(ch,trname));
778: tp->tr_flags |= ISFOUND;
779: return(ch);
780: }
781:
782: if (moving)
783: msg("Your attempt fails.");
784: }
785:
786: tp->tr_flags |= ISFOUND;
787:
788: switch(ch)
789: {
790: case TRAPDOOR:
791: if (is_player)
792: {
793: level++;
794: new_level(NORMLEV,0);
795: addmsg("You fell into a trap");
796:
797: if (player.t_ctype != C_THIEF
798: && player.t_ctype != C_ASSASIN
799: && player.t_ctype != C_NINJA
800: && rnd(pstats.s_dext) < 4)
801: {
802: addmsg(" and were damaged by the fall");
803:
804: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
805: {
806: addmsg("! The fall killed you.");
807: endmsg();
808: death(D_FALL);
809:
810: return(ch);
811: }
812: }
813:
814: addmsg("!");
815: endmsg();
816:
817: if (off(player, ISCLEAR) && rnd(4) < 3)
818: {
819: if (on(player, ISHUH))
820: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
821: else
822: light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION, AFTER);
823:
824: turn_on(player, ISHUH);
825: }
826: else
827: msg("You feel dizzy for a moment, but it quickly passes.");
828: }
829: else
830: {
831: if (can_see)
832: msg("The %s fell into a trap!", mname);
833:
834: if (on(*th, ISFAMILIAR))
835: turn_off(player, HASFAMILIAR);
836:
837: killed(NULL,mitem,NOMESSAGE,NOPOINTS);
838: }
839: break;
840:
841: case BEARTRAP:
842: if (is_stealth(th))
843: {
844: if (is_player)
845: msg("You pass a bear trap.");
846: else if (can_see)
847: msg("The %s passes a bear trap.", mname);
848: }
849: else
850: {
851: th->t_no_move += BEARTIME;
852:
853: if (is_player)
854: msg("You are caught in a bear trap.");
855: else if (can_see)
856: msg("The %s is caught in a bear trap.", mname);
857: }
858: break;
859:
860: case SLEEPTRAP:
861: if (is_player)
862: {
863: msg("A strange white mist envelops you.");
864:
865: if (!is_wearing(R_ALERT))
866: {
867: if (!is_wearing(R_BREATHE) && off(player, HASOXYGEN))
868: {
869: msg("You fall asleep.");
870: no_command += SLEEPTIME;
871: }
872: }
873: }
874: else
875: {
876: if (can_see)
877: msg("A strange white mist envelops the %s.", mname);
878:
879: if (on(*th, ISUNDEAD))
880: {
881: if (can_see)
882: msg("The mist doesn't seem to affect the %s.", mname);
883: }
884:
885: if (on(*th, ISUNDEAD) || on(*th, HASOXYGEN))
886: {
887: if (can_see)
888: msg("The mist doesn't seem to affect the %s.", mname);
889: }
890: else
891: {
892: th->t_no_move += SLEEPTIME;
893: }
894: }
895: break;
896:
897: case ARROWTRAP:
898: if (swing(th->t_ctype, th->t_stats.s_lvl - 1, th->t_stats.s_arm, 1))
899: {
900: if (is_player)
901: {
902: msg("Oh no! An arrow shot you.");
903:
904: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
905: {
906: msg("The arrow killed you.");
907: death(D_ARROW);
908: return(ch);
909: }
910: }
911: else
912: {
913: if (can_see)
914: msg("An arrow shot the %s.", mname);
915:
916: if (on(*th, NOSHARP))
917: {
918: if (can_see)
919: msg("The arrow has no effect!");
920: }
921: else
922: {
923: if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0)
924: {
925: if (can_see)
926: msg("The arrow killed the %s.", mname);
927:
928: if (on(*th, ISFAMILIAR))
929: turn_off(player, HASFAMILIAR);
930:
931: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
932: }
933: }
934: }
935: }
936: else
937: {
938: struct linked_list *itm;
939: struct object *an_arrow;
940:
941: if (is_player)
942: msg("An arrow shoots past you.");
943: else if (can_see)
944: msg("An arrow shoots by the %s.", mname);
945:
946: itm = new_item(sizeof *an_arrow);
947: an_arrow = OBJPTR(itm);
948: an_arrow->o_type = WEAPON;
949: an_arrow->o_which = ARROW;
950: an_arrow->o_hplus = rnd(3) - 1;
951: an_arrow->o_dplus = rnd(3) - 1;
952: init_weapon(an_arrow, ARROW);
953: an_arrow->o_count = 1;
954: an_arrow->o_pos = tc;
955: an_arrow->o_mark[0] = '\0';
956: fall(&player, itm, FALSE, FALSE);
957: }
958: break;
959:
960: case TELTRAP:
961: if (is_player)
962: {
963: teleport();
964:
965: if (off(player, ISCLEAR))
966: {
967: msg("Wait, what's going on here. Huh? What? Who?");
968:
969: if (on(player, ISHUH))
970: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
971: else
972: light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION, AFTER);
973:
974: turn_on(player, ISHUH);
975: }
976: else
977: msg("You feel dizzy for a moment, but it quickly passes.");
978: }
979: else
980: {
981: int rm;
982:
983: /* Erase the monster from the old position */
984:
985: if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
986: mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
987:
988: mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
989:
990: /* Get a new position */
991:
992: do
993: {
994: rm = rnd_room();
995: rnd_pos(&rooms[rm], &th->t_pos);
996: }
997: while(winat(th->t_pos.y, th->t_pos.x) != FLOOR);
998:
999: /* Put it there */
1000:
1001: mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
1002: th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) );
1003:
1004: if (can_see)
1005: msg("The %s seems to have disappeared!", mname);
1006: }
1007: break;
1008:
1009: case DARTTRAP:
1010:
1011: if (swing(th->t_ctype, th->t_stats.s_lvl + 1,th->t_stats.s_arm, 1))
1012: {
1013: if (is_player)
1014: {
1015: msg("A small dart just hit you in the shoulder.");
1016:
1017: if ((pstats.s_hpt -= roll(1, 4)) <= 0)
1018: {
1019: msg("The dart killed you.");
1020: death(D_DART);
1021: return(ch);
1022: }
1023:
1024: /* Now the poison */
1025:
1026: if (player.t_ctype != C_PALADIN
1027: && !(player.t_ctype == C_NINJA &&
1028: pstats.s_lvl > 12) && !save(VS_POISON))
1029: {
1030:
1031: /*
1032: * 75% chance it will do point
1033: * damage - else strength
1034: */
1035:
1036: if (rnd(100) < 75)
1037: {
1038: pstats.s_hpt /= 2;
1039:
1040: if (pstats.s_hpt == 0)
1041: {
1042: death(D_POISON);
1043: return(ch);
1044: }
1045: }
1046: else if (!is_wearing(R_SUSABILITY))
1047: chg_str(-1, FALSE, FALSE);
1048: }
1049: }
1050: else
1051: {
1052: int orig_hp = th->t_stats.s_hpt;
1053:
1054: if (can_see)
1055: msg("A small dart just hit the %s.", mname);
1056:
1057: /*
1058: * Poison has no effect on poisonous or
1059: * undead monsters
1060: */
1061:
1062: if (off(*th, CANPOISON) &&
1063: off(*th, ISUNDEAD) &&
1064: !save_throw(VS_POISON, th))
1065: th->t_stats.s_hpt /= 2;
1066:
1067: /* Now the dart damage */
1068:
1069: if (off(*th, NOSHARP))
1070: th->t_stats.s_hpt -= roll(1, 4);
1071:
1072: if (orig_hp == th->t_stats.s_hpt)
1073: if (can_see)
1074: msg("The dart has not effect!");
1075: else if (th->t_stats.s_hpt < 0)
1076: {
1077: if (can_see)
1078: msg("The dart killed the %s.", mname);
1079:
1080: if (on(*th, ISFAMILIAR))
1081: turn_off(player, HASFAMILIAR);
1082:
1083: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1084: }
1085: }
1086: }
1087: else
1088: {
1089: if (is_player)
1090: msg("A small dart whizzes by your ear and vanishes.");
1091: else if (can_see)
1092: msg("A small dart whizzes by the %s and vanishes.", mname);
1093: }
1094: break;
1095:
1096: case POOL:
1097: {
1098: int i;
1099:
1100: i = rnd(100);
1101:
1102: if (is_player)
1103: {
1104: if (on(player, ISELECTRIC))
1105: {
1106: msg("Oh no!!! The water shorts you out");
1107: extinguish_fuse(FUSE_UNELECTRIFY);
1108: turn_off(player, ISELECTRIC);
1109:
1110: if (!is_wearing(R_ELECTRESIST))
1111: {
1112: if ((pstats.s_hpt -= roll(1, 10)) <= 0)
1113: {
1114: addmsg("! The shock killed you.");
1115: endmsg();
1116: death(D_DROWN);
1117: return(ch);
1118: }
1119: }
1120: }
1121:
1122: if ((tp->tr_flags & ISGONE))
1123: {
1124: if (i < 30)
1125: {
1126: teleport(); /* teleport away */
1127:
1128: if (off(player, ISCLEAR))
1129: {
1130: if (on(player, ISHUH))
1131: lengthen_fuse(FUSE_UNCONFUSE,rnd(8)+HUHDURATION);
1132: else
1133: light_fuse(FUSE_UNCONFUSE,0,rnd(8)+HUHDURATION,AFTER);
1134: turn_on(player, ISHUH);
1135: }
1136: else
1137: msg("You feel dizzy for a moment, but it quickly passes.");
1138:
1139: pool_teleport = TRUE;
1140: }
1141: else if ((i < 45) && level > 2)
1142: {
1143: level -= rnd(2) + 1;
1144: new_level(NORMLEV,0);
1145: pool_teleport = TRUE;
1146: msg("You here a faint groan from below.");
1147:
1148: if (off(player, ISCLEAR))
1149: {
1150: if (on(player, ISHUH))
1151: lengthen_fuse(FUSE_UNCONFUSE,rnd(8)+HUHDURATION);
1152: else
1153: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
1154:
1155: turn_on(player, ISHUH);
1156: }
1157: else
1158: msg("You feel dizzy for a moment, but it quickly passes.");
1159: }
1160: else if (i < 70)
1161: {
1162: level += rnd(4) + 1;
1163: new_level(NORMLEV,0);
1164: pool_teleport = TRUE;
1165: msg("You find yourself in strange surroundings.");
1166:
1167: if (off(player, ISCLEAR))
1168: {
1169: if (on(player, ISHUH))
1170: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
1171: else
1172: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
1173:
1174: turn_on(player, ISHUH);
1175: }
1176: else
1177: msg("You feel dizzy for a moment, but it quickly passes.");
1178: }
1179: else if (i > 95)
1180: {
1181: if (is_wearing(R_BREATHE) || on(player, HASOXYGEN))
1182: msg("You splash in the pool unharmed.");
1183: else
1184: {
1185: msg("Oh no!!! You drown in the pool!!! --More--");
1186: wait_for(' ');
1187: death(D_DROWN);
1188: return(ch);
1189: }
1190: }
1191: }
1192: }
1193: else
1194: {
1195: if (can_see)
1196: msg("The %s fell into the pool!", mname);
1197:
1198: if (i < 15)
1199: {
1200: if (off(*th, HASOXYGEN))
1201: {
1202: if (can_see)
1203: msg("The %s has drowned!", mname);
1204:
1205: if (on(*th, ISFAMILIAR))
1206: turn_off(player, HASFAMILIAR);
1207:
1208: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1209: }
1210: }
1211: }
1212: }
1213: break;
1214:
1215: case MAZETRAP:
1216:
1217: if (is_player)
1218: {
1219: level++;
1220: new_level(MAZELEV,0);
1221: addmsg("You are surrounded by twisty passages");
1222:
1223: if (rnd(4) < 1)
1224: {
1225: addmsg(" and were damaged by the fall");
1226:
1227: if ((pstats.s_hpt -= roll(1, 6)) <= 0)
1228: {
1229: addmsg("! The fall killed you.");
1230: endmsg();
1231: death(D_FALL);
1232: return(ch);
1233: }
1234: }
1235:
1236: addmsg("!");
1237: endmsg();
1238:
1239: if (off(player, ISCLEAR))
1240: {
1241: if (on(player, ISHUH))
1242: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
1243: else
1244: {
1245: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
1246: turn_on(player, ISHUH);
1247: }
1248: }
1249: else
1250: msg("You feel dizzy for a moment, but it quickly passes.");
1251: }
1252: else
1253: {
1254: if (can_see)
1255: msg("The %s fell into a trap!", mname);
1256:
1257: if (on(*th, ISFAMILIAR))
1258: turn_off(player, HASFAMILIAR);
1259:
1260: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1261: }
1262: break;
1263:
1264: case FIRETRAP:
1265: {
1266: struct room *rp = roomin(hero);
1267:
1268: if (is_player)
1269: {
1270: if (is_wearing(R_FIRERESIST) || on(player, NOFIRE))
1271: msg("You pass through the flames unharmed.");
1272: else
1273: {
1274: addmsg("You are burned by the flames");
1275:
1276: if ((pstats.s_hpt -= roll(pstats.s_lvl, 2)) <= 0)
1277: {
1278: addmsg("! The flames killed you.");
1279: endmsg();
1280: death(D_FIRE);
1281: return(ch);
1282: }
1283:
1284: addmsg("!");
1285:
1286: endmsg();
1287: }
1288: }
1289: else
1290: {
1291: if (on(*th, CANBBURN))
1292: {
1293: if (can_see)
1294: msg("The %s is burned to death by the flames.", mname);
1295:
1296: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1297: }
1298: else if (on(*th, NOFIRE))
1299: {
1300: if (can_see)
1301: msg("The %s passes through the flames unharmed.", mname);
1302: }
1303: else
1304: {
1305: if (can_see)
1306: msg("The %s is burned by the flames.", mname);
1307:
1308: if ((th->t_stats.s_hpt -= roll(th->t_stats.s_lvl, 3)) < 0)
1309: {
1310: if (can_see)
1311: msg("The %s is burned to death by the flames.", mname);
1312:
1313: if (on(*th, ISFAMILIAR))
1314: turn_off(player, HASFAMILIAR);
1315:
1316: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1317: }
1318: else if (th->t_stats.s_intel < rnd(20))
1319: {
1320: if (can_see)
1321: msg("The %s turns and runs away in fear.", mname);
1322:
1323: turn_on(*th, ISFLEE);
1324: }
1325: }
1326: }
1327:
1328: if (rp != NULL)
1329: {
1330: rp->r_flags &= ~ISDARK;
1331: light(&hero);
1332: }
1333: }
1334: break;
1335:
1336: case POISONTRAP:
1337: if (is_player)
1338: {
1339: msg("You fall into a pool of poison.");
1340:
1341: if (rnd(4) > 0)
1342: {
1343: msg("You swallow some of the liquid and feel very sick.");
1344: pstats.s_hpt -= pstats.s_hpt / 3;
1345:
1346: if (player.t_ctype != C_PALADIN
1347: && !(player.t_ctype == C_NINJA &&
1348: pstats.s_lvl > 12)
1349: && !is_wearing(R_SUSABILITY))
1350: chg_str(-2, FALSE, FALSE);
1351: }
1352: else
1353: msg("The stuff tastes horrible.");
1354: }
1355: else
1356: {
1357: if (can_see)
1358: msg("The %s falls into the pool of poison.", mname);
1359:
1360: if (rnd(4) > 0 && off(*th, ISUNDEAD))
1361: if (th->t_stats.s_hpt *= 2.0 / 3.0 < 0)
1362: {
1363: if (can_see)
1364: msg("The %s dies from the poison.", mname);
1365:
1366: if (on(*th, ISFAMILIAR))
1367: turn_off(player, HASFAMILIAR);
1368:
1369: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1370: }
1371: }
1372: break;
1373:
1374: case LAIR:
1375: if (is_player)
1376: {
1377: msg("You found a monster lair!");
1378: mpos = 0;
1379: new_level(THRONE,0);
1380: }
1381: else
1382: {
1383: if (can_see)
1384: msg("The %s fell into a trap!", mname);
1385:
1386: if (on(*th, ISFAMILIAR))
1387: turn_off(player, HASFAMILIAR);
1388:
1389: killed(NULL, mitem, NOMESSAGE, NOPOINTS);
1390: }
1391: break;
1392:
1393: case RUSTTRAP:
1394: if (is_player)
1395: {
1396: msg("You are splashed by water.");
1397:
1398: if (cur_armor != NULL &&
1399: cur_armor->o_which != SOFT_LEATHER &&
1400: cur_armor->o_which != HEAVY_LEATHER &&
1401: cur_armor->o_which != CUIRBOLILLI &&
1402: cur_armor->o_which != PADDED_ARMOR &&
1403: cur_armor->o_which != CRYSTAL_ARMOR &&
1404: cur_armor->o_which != MITHRIL &&
1405: !(cur_armor->o_flags & ISPROT) &&
1406: cur_armor->o_ac < pstats.s_arm + 1)
1407: {
1408: msg("Your armor weakens!");
1409: cur_armor->o_ac++;
1410: }
1411: else if (cur_armor != NULL && (cur_armor->o_flags & ISPROT))
1412: msg("The rust vanishes instantly!");
1413: }
1414: else
1415: {
1416: if (can_see)
1417: msg("The %s is splashed by water.", mname);
1418: }
1419: }
1420:
1421: return(ch);
1422: }
1423:
1424: /*
1425: dip_it()
1426: Dip an object into a magic pool
1427: */
1428:
1429: void
1430: dip_it(void)
1431: {
1432: struct linked_list *what;
1433: struct object *ob;
1434: struct trap *tp;
1435: int wh, i;
1436:
1437: tp = trap_at(hero.y, hero.x);
1438:
1439: if (tp == NULL || !(tp->tr_type == POOL || tp->tr_type == POISONTRAP))
1440: {
1441: msg("I see no pools here.");
1442: return;
1443: }
1444:
1445: if (tp->tr_flags & ISGONE)
1446: {
1447: msg("This %s appears to have been used once already.",
1448: (tp->tr_type == POOL ? "shimmering pool" : "poison pool"));
1449: return;
1450: }
1451:
1452: if ((what = get_item("dip", 0)) == NULL)
1453: {
1454: msg("");
1455: after = FALSE;
1456: return;
1457: }
1458:
1459: ob = OBJPTR(what);
1460: mpos = 0;
1461:
1462: if (ob == cur_armor)
1463: {
1464: msg("You have to take off your armor before you can dip it.");
1465: return;
1466: }
1467: else if (ob == cur_ring[LEFT_1] || ob == cur_ring[LEFT_2] ||
1468: ob == cur_ring[LEFT_3] || ob == cur_ring[LEFT_4] ||
1469: ob == cur_ring[RIGHT_1] || ob == cur_ring[RIGHT_2] ||
1470: ob == cur_ring[RIGHT_3] || ob == cur_ring[RIGHT_4])
1471: {
1472: msg("You have to take that ring off before you can dip it.");
1473: return;
1474: }
1475:
1476: tp->tr_flags |= ISGONE;
1477:
1478: if (ob != NULL && tp->tr_type == POOL)
1479: {
1480: wh = ob->o_which;
1481: ob->o_flags |= ISKNOW;
1482: i = rnd(100);
1483:
1484: switch (ob->o_type)
1485: {
1486: case WEAPON:
1487: if (i < 50)
1488: {
1489: if (!(ob->o_flags & ISCURSED))
1490: {
1491: ob->o_hplus += 1;
1492: ob->o_dplus += 1;
1493: }
1494: else
1495: {
1496: ob->o_hplus = rnd(2);
1497: ob->o_dplus = rnd(2);
1498: }
1499:
1500: ob->o_flags &= ~ISCURSED;
1501: msg("The %s glows blue for a moment.", weaps[wh].w_name);
1502: }
1503: else if (i < 70) /* curse weapon here */
1504: {
1505: if (!(ob->o_flags & ISCURSED))
1506: {
1507: ob->o_hplus = -(rnd(2) + 1);
1508: ob->o_dplus = -(rnd(2) + 1);
1509: }
1510: else /* if already cursed */
1511: {
1512: ob->o_hplus--;
1513: ob->o_dplus--;
1514: }
1515:
1516: ob->o_flags |= ISCURSED;
1517: msg("The %s glows red for a moment.", weaps[wh].w_name);
1518: }
1519: else
1520: msg("Nothing seems to happen.");
1521: break;
1522:
1523: case ARMOR:
1524:
1525: if (i < 50) /* enchant armor */
1526: {
1527: if (!(ob->o_flags & ISCURSED))
1528: ob->o_ac -= rnd(2) + 1;
1529: else
1530: ob->o_ac = -rnd(3) + armors[wh].a_class;
1531:
1532: ob->o_flags &= ~ISCURSED;
1533: msg("The %s glows blue for a moment.", armors[wh].a_name);
1534: }
1535: else if (i < 75) /* curse armor */
1536: {
1537: if (!(ob->o_flags & ISCURSED))
1538: ob->o_ac = rnd(3) + armors[wh].a_class;
1539: else
1540: ob->o_ac += rnd(2) + 1;
1541:
1542: ob->o_flags |= ISCURSED;
1543: msg("The %s glows red for a moment.", armors[wh].a_name);
1544: }
1545: else
1546: msg("Nothing seems to happen");
1547: break;
1548:
1549: case STICK:
1550: {
1551: int j;
1552:
1553: j = rnd(8) + 1;
1554:
1555: if (i < 50) /* add charges */
1556: {
1557: ob->o_charges += j;
1558: know_items[TYP_STICK][wh] = TRUE;
1559:
1560: if (ob->o_flags & ISCURSED)
1561: ob->o_flags &= ~ISCURSED;
1562:
1563: msg("The %s %s glows blue for a moment.",
1564: ws_made[wh], ws_type[wh]);
1565: }
1566: else if (i < 65) /* remove charges */
1567: {
1568: if ((ob->o_charges -= i) < 0)
1569: ob->o_charges = 0;
1570:
1571: know_items[TYP_STICK][wh] = TRUE;
1572:
1573: if (ob->o_flags & ISBLESSED)
1574: ob->o_flags &= ~ISBLESSED;
1575: else
1576: ob->o_flags |= ISCURSED;
1577:
1578: msg("The %s %s glows red for a moment.",
1579: ws_made[wh], ws_type[wh]);
1580: }
1581: else
1582: msg("Nothing seems to happen.");
1583: }
1584: break;
1585:
1586: case SCROLL:
1587:
1588: know_items[TYP_SCROLL][wh] = TRUE;
1589: msg("The '%s' scroll unfurls.", s_names[wh]);
1590: break;
1591:
1592: case POTION:
1593:
1594: know_items[TYP_POTION][wh] = TRUE;
1595: msg("The %s potion bubbles for a moment.", p_colors[wh]);
1596: break;
1597:
1598: case RING:
1599: if (i < 50) /* enchant ring */
1600: {
1601: if (!(ob->o_flags & ISCURSED))
1602: ob->o_ac += rnd(2) + 1;
1603: else
1604: ob->o_ac = rnd(2) + 1;
1605:
1606: ob->o_flags &= ~ISCURSED;
1607: }
1608: else if (i < 80) /* curse ring */
1609: {
1610: if (!(ob->o_flags & ISCURSED))
1611: ob->o_ac = -(rnd(2) + 1);
1612: else
1613: ob->o_ac -= (rnd(2) + 1);
1614:
1615: ob->o_flags |= ISCURSED;
1616: }
1617:
1618: know_items[TYP_RING][wh] = TRUE;
1619: msg("The %s ring vibrates for a moment.", r_stones[wh]);
1620: break;
1621:
1622: default:
1623: msg("The pool bubbles for a moment.");
1624: }
1625: }
1626: else if (ob != NULL && tp->tr_type == POISONTRAP)
1627: {
1628: if ((player.t_ctype == C_PALADIN) ||
1629: (player.t_ctype == C_CLERIC && rnd(2)))
1630: {
1631: msg("Trying to use poison is evil.");
1632: luck += 2;
1633: }
1634:
1635: if (ob->o_type != WEAPON || rnd(10) > 0)
1636: msg("Nothing seems to happen.");
1637: else
1638: {
1639: msg("Your %s is covered with a black sticky liquid.",
1640: weaps[ob->o_which].w_name);
1641: ob->o_flags |= ISPOISON;
1642: }
1643: }
1644: else
1645: msg("Nothing seems to happen.");
1646: }
1647:
1648: /*
1649: trap_at()
1650: find the trap at (y,x) on screen.
1651: */
1652:
1653: struct trap *
1654: trap_at(int y, int x)
1655: {
1656: struct trap *tp, *ep;
1657:
1658: ep = &traps[ntraps];
1659:
1660: for (tp = traps; tp < ep; tp++)
1661: if (tp->tr_pos.y == y && tp->tr_pos.x == x)
1662: break;
1663:
1664: if (tp == ep)
1665: {
1666: debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf));
1667: tp = NULL;
1668: }
1669:
1670: return(tp);
1671: }
1672:
1673: /*
1674: set_trap()
1675: set a trap at (y, x) on screen.
1676: */
1677:
1678: void
1679: set_trap(struct thing *tp, int y, int x)
1680: {
1681: int is_player = (tp == &player);
1682: int selection = rnd(7) + 1;
1683: char ch = 0, och;
1684: int thief_bonus = 0;
1685:
1686: switch(och = CCHAR( mvinch(y, x) ))
1687: {
1688: case WALL:
1689: case FLOOR:
1690: case PASSAGE:
1691: break;
1692: default:
1693: msg("The trap failed!");
1694: return;
1695: }
1696:
1697: if (is_player && (player.t_ctype == C_THIEF ||
1698: player.t_ctype == C_NINJA))
1699: thief_bonus = 10;
1700:
1701: if (ntraps >= 2 * MAXTRAPS || ++trap_tries >= MAXTRPTRY ||
1702: rnd(60) >= (tp->t_stats.s_dext + tp->t_stats.s_lvl / 2 +
1703: thief_bonus))
1704: {
1705: if (is_player)
1706: msg("The trap failed!");
1707:
1708: return;
1709: }
1710:
1711: /* Set up for redraw */
1712:
1713: clearok(cw, TRUE);
1714: touchwin(cw);
1715:
1716: if (is_player)
1717: {
1718: add_line("[1] Trap Door");
1719: add_line("[2] Bear Trap");
1720: add_line("[3] Sleep Trap");
1721: add_line("[4] Arrow Trap");
1722: add_line("[5] Teleport Trap");
1723: add_line("[6] Dart Trap");
1724: add_line("[7] Fire Trap");
1725: end_line();
1726: msg("Which trap? ");
1727:
1728: selection = (short) ((readchar() & 0177) - '0');
1729:
1730: while (selection < 1 || selection > 7)
1731: {
1732: if (selection == (short) ESCAPE - (short) '0')
1733: {
1734: after = FALSE;
1735: return;
1736: }
1737:
1738: msg("");
1739: msg("Please enter a selection between 1 and 7: ");
1740: selection = (short) ((readchar() & 0177) - '0');
1741: }
1742: }
1743:
1744: switch (selection)
1745: {
1746: case 1: ch = TRAPDOOR; break;
1747: case 2: ch = BEARTRAP; break;
1748: case 3: ch = SLEEPTRAP;break;
1749: case 4: ch = ARROWTRAP;break;
1750: case 5: ch = TELTRAP; break;
1751: case 6: ch = DARTTRAP; break;
1752: case 7: ch = FIRETRAP; break;
1753: }
1754:
1755: mvaddch(y, x, ch);
1756:
1757: traps[ntraps].tr_type = ch;
1758: traps[ntraps].tr_flags = ISTHIEFSET;
1759: traps[ntraps].tr_show = och;
1760: traps[ntraps].tr_pos.y = y;
1761: traps[ntraps++].tr_pos.x = x;
1762: }
1763:
1764:
1765: /*
1766: rndmove()
1767: move in a random direction if the monster/person is confused
1768: */
1769:
1770: coord
1771: rndmove(struct thing *who)
1772: {
1773: int x, y;
1774: int ex, ey, nopen = 0;
1775: coord ret; /* what we will be returning */
1776: coord dest;
1777:
1778: ret = who->t_pos;
1779:
1780: /*
1781: * Now go through the spaces surrounding the player and set that
1782: * place in the array to true if the space can be moved into
1783: */
1784:
1785: ey = ret.y + 1;
1786: ex = ret.x + 1;
1787:
1788: for (y = who->t_pos.y - 1; y <= ey; y++)
1789: if (y > 0 && y < LINES - 2)
1790: for (x = who->t_pos.x - 1; x <= ex; x++)
1791: {
1792: if (x < 0 || x >= COLS)
1793: continue;
1794:
1795: if (step_ok(y, x, NOMONST, who))
1796: {
1797: dest.y = y;
1798: dest.x = x;
1799:
1800: if (!diag_ok(&who->t_pos, &dest, who))
1801: continue;
1802:
1803: if (rnd(++nopen) == 0)
1804: ret = dest;
1805: }
1806: }
1807:
1808: return(ret);
1809: }
1810:
1811: /*
1812: isatrap()
1813: Returns TRUE if this character is some kind of trap
1814: */
1815:
1816: int
1817: isatrap(int ch)
1818: {
1819: switch(ch)
1820: {
1821: case DARTTRAP:
1822: case TELTRAP:
1823: case TRAPDOOR:
1824: case ARROWTRAP:
1825: case SLEEPTRAP:
1826: case POOL:
1827: case MAZETRAP:
1828: case FIRETRAP:
1829: case POISONTRAP:
1830: case LAIR:
1831: case RUSTTRAP:
1832: case BEARTRAP:
1833: return (TRUE);
1834: default:
1835: return (FALSE);
1836: }
1837: }
CVSweb