|
|
1.1 root 1: /*
2: * Copyright (c) 1988 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Timothy C. Stoehr.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)monster.c 5.3 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*
28: * monster.c
29: *
30: * This source herein may be modified and/or distributed by anybody who
31: * so desires, with the following restrictions:
32: * 1.) No portion of this notice shall be removed.
33: * 2.) Credit shall not be taken for the creation of this source.
34: * 3.) This code is not to be traded, sold, or used for personal
35: * gain or profit.
36: *
37: */
38:
39: #include "rogue.h"
40:
41: object level_monsters;
42: boolean mon_disappeared;
43:
44: char *m_names[] = {
45: "aquator",
46: "bat",
47: "centaur",
48: "dragon",
49: "emu",
50: "venus fly-trap",
51: "griffin",
52: "hobgoblin",
53: "ice monster",
54: "jabberwock",
55: "kestrel",
56: "leprechaun",
57: "medusa",
58: "nymph",
59: "orc",
60: "phantom",
61: "quagga",
62: "rattlesnake",
63: "snake",
64: "troll",
65: "black unicorn",
66: "vampire",
67: "wraith",
68: "xeroc",
69: "yeti",
70: "zombie"
71: };
72:
73: object mon_tab[MONSTERS] = {
74: {(ASLEEP|WAKENS|WANDERS|RUSTS),"0d0",25,'A',20,9,18,100,0,0,0,0,0},
75: {(ASLEEP|WANDERS|FLITS|FLIES),"1d3",10,'B',2,1,8,60,0,0,0,0,0},
76: {(ASLEEP|WANDERS),"3d3/2d5",32,'C',15,7,16,85,0,10,0,0,0},
77: {(ASLEEP|WAKENS|FLAMES),"4d6/4d9",145,'D',5000,21,126,100,0,90,0,0,0},
78: {(ASLEEP|WAKENS),"1d3",11,'E',2,1,7,65,0,0,0,0,0},
79: {(HOLDS|STATIONARY),"5d5",73,'F',91,12,126,80,0,0,0,0,0},
80: {(ASLEEP|WAKENS|WANDERS|FLIES),"5d5/5d5",115,'G',
81: 2000,20,126,85,0,10,0,0,0},
82: {(ASLEEP|WAKENS|WANDERS),"1d3/1d2",15,'H',3,1,10,67,0,0,0,0,0},
83: {(ASLEEP|FREEZES),"0d0",15,'I',5,2,11,68,0,0,0,0,0},
84: {(ASLEEP|WANDERS),"3d10/4d5",132,'J',3000,21,126,100,0,0,0,0,0},
85: {(ASLEEP|WAKENS|WANDERS|FLIES),"1d4",10,'K',2,1,6,60,0,0,0,0,0},
86: {(ASLEEP|STEALS_GOLD),"0d0",25,'L',21,6,16,75,0,0,0,0,0},
87: {(ASLEEP|WAKENS|WANDERS|CONFUSES),"4d4/3d7",97,'M',
88: 250,18,126,85,0,25,0,0,0},
89: {(ASLEEP|STEALS_ITEM),"0d0",25,'N',39,10,19,75,0,100,0,0,0},
90: {(ASLEEP|WANDERS|WAKENS|SEEKS_GOLD),"1d6",25,'O',5,4,13,70,0,10,0,0,0},
91: {(ASLEEP|INVISIBLE|WANDERS|FLITS),"5d4",76,'P',120,15,24,80,0,50,0,0,0},
92: {(ASLEEP|WAKENS|WANDERS),"3d5",30,'Q',20,8,17,78,0,20,0,0,0},
93: {(ASLEEP|WAKENS|WANDERS|STINGS),"2d5",19,'R',10,3,12,70,0,0,0,0,0},
94: {(ASLEEP|WAKENS|WANDERS),"1d3",8,'S',2,1,9,50,0,0,0,0,0},
95: {(ASLEEP|WAKENS|WANDERS),"4d6/1d4",75,'T',125,13,22,75,0,33,0,0,0},
96: {(ASLEEP|WAKENS|WANDERS),"4d10",90,'U',
97: 200,17,26,85,0,33,0,0,0},
98: {(ASLEEP|WAKENS|WANDERS|DRAINS_LIFE),"1d14/1d4",55,'V',
99: 350,19,126,85,0,18,0,0,0},
100: {(ASLEEP|WANDERS|DROPS_LEVEL),"2d8",45,'W',55,14,23,75,0,0,0,0,0},
101: {(ASLEEP|IMITATES),"4d6",42,'X',110,16,25,75,0,0,0,0,0},
102: {(ASLEEP|WANDERS),"3d6",35,'Y',50,11,20,80,0,20,0,0,0},
103: {(ASLEEP|WAKENS|WANDERS),"1d7",21,'Z',8,5,14,69,0,0,0,0,0}
104: };
105:
106: extern short cur_level;
107: extern short cur_room, party_room;
108: extern short blind, halluc, haste_self;
109: extern boolean detect_monster, see_invisible, r_see_invisible;
110: extern short stealthy;
111:
112: put_mons()
113: {
114: short i;
115: short n;
116: object *monster;
117: short row, col;
118:
119: n = get_rand(4, 6);
120:
121: for (i = 0; i < n; i++) {
122: monster = gr_monster((object *) 0, 0);
123: if ((monster->m_flags & WANDERS) && coin_toss()) {
124: wake_up(monster);
125: }
126: gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
127: put_m_at(row, col, monster);
128: }
129: }
130:
131: object *
132: gr_monster(monster, mn)
133: register object *monster;
134: register mn;
135: {
136: if (!monster) {
137: monster = alloc_object();
138:
139: for (;;) {
140: mn = get_rand(0, MONSTERS-1);
141: if ((cur_level >= mon_tab[mn].first_level) &&
142: (cur_level <= mon_tab[mn].last_level)) {
143: break;
144: }
145: }
146: }
147: *monster = mon_tab[mn];
148: if (monster->m_flags & IMITATES) {
149: monster->disguise = gr_obj_char();
150: }
151: if (cur_level > (AMULET_LEVEL + 2)) {
152: monster->m_flags |= HASTED;
153: }
154: monster->trow = NO_ROOM;
155: return(monster);
156: }
157:
158: mv_mons()
159: {
160: register object *monster, *next_monster;
161: boolean flew;
162:
163: if (haste_self % 2) {
164: return;
165: }
166:
167: monster = level_monsters.next_monster;
168:
169: while (monster) {
170: next_monster = monster->next_monster;
171: mon_disappeared = 0;
172: if (monster->m_flags & HASTED) {
173: mv_1_monster(monster, rogue.row, rogue.col);
174: if (mon_disappeared) {
175: goto NM;
176: }
177: } else if (monster->m_flags & SLOWED) {
178: monster->slowed_toggle = !monster->slowed_toggle;
179: if (monster->slowed_toggle) {
180: goto NM;
181: }
182: }
183: if ((monster->m_flags & CONFUSED) && move_confused(monster)) {
184: goto NM;
185: }
186: flew = 0;
187: if ( (monster->m_flags & FLIES) &&
188: !(monster->m_flags & NAPPING) &&
189: !mon_can_go(monster, rogue.row, rogue.col)) {
190: flew = 1;
191: mv_1_monster(monster, rogue.row, rogue.col);
192: if (mon_disappeared) {
193: goto NM;
194: }
195: }
196: if (!(flew && mon_can_go(monster, rogue.row, rogue.col))) {
197: mv_1_monster(monster, rogue.row, rogue.col);
198: }
199: NM: monster = next_monster;
200: }
201: }
202:
203: party_monsters(rn, n)
204: int rn, n;
205: {
206: short i, j;
207: short row, col;
208: object *monster;
209: boolean found;
210:
211: n += n;
212:
213: for (i = 0; i < MONSTERS; i++) {
214: mon_tab[i].first_level -= (cur_level % 3);
215: }
216: for (i = 0; i < n; i++) {
217: if (no_room_for_monster(rn)) {
218: break;
219: }
220: for (j = found = 0; ((!found) && (j < 250)); j++) {
221: row = get_rand(rooms[rn].top_row+1,
222: rooms[rn].bottom_row-1);
223: col = get_rand(rooms[rn].left_col+1,
224: rooms[rn].right_col-1);
225: if ((!(dungeon[row][col] & MONSTER)) &&
226: (dungeon[row][col] & (FLOOR | TUNNEL))) {
227: found = 1;
228: }
229: }
230: if (found) {
231: monster = gr_monster((object *) 0, 0);
232: if (!(monster->m_flags & IMITATES)) {
233: monster->m_flags |= WAKENS;
234: }
235: put_m_at(row, col, monster);
236: }
237: }
238: for (i = 0; i < MONSTERS; i++) {
239: mon_tab[i].first_level += (cur_level % 3);
240: }
241: }
242:
243: gmc_row_col(row, col)
244: register row, col;
245: {
246: register object *monster;
247:
248: if (monster = object_at(&level_monsters, row, col)) {
249: if ((!(detect_monster || see_invisible || r_see_invisible) &&
250: (monster->m_flags & INVISIBLE)) || blind) {
251: return(monster->trail_char);
252: }
253: if (monster->m_flags & IMITATES) {
254: return(monster->disguise);
255: }
256: return(monster->m_char);
257: } else {
258: return('&'); /* BUG if this ever happens */
259: }
260: }
261:
262: gmc(monster)
263: object *monster;
264: {
265: if ((!(detect_monster || see_invisible || r_see_invisible) &&
266: (monster->m_flags & INVISIBLE))
267: || blind) {
268: return(monster->trail_char);
269: }
270: if (monster->m_flags & IMITATES) {
271: return(monster->disguise);
272: }
273: return(monster->m_char);
274: }
275:
276: mv_1_monster(monster, row, col)
277: register object *monster;
278: short row, col;
279: {
280: short i, n;
281: boolean tried[6];
282:
283: if (monster->m_flags & ASLEEP) {
284: if (monster->m_flags & NAPPING) {
285: if (--monster->nap_length <= 0) {
286: monster->m_flags &= (~(NAPPING | ASLEEP));
287: }
288: return;
289: }
290: if ((monster->m_flags & WAKENS) &&
291: rogue_is_around(monster->row, monster->col) &&
292: rand_percent(((stealthy > 0) ?
293: (WAKE_PERCENT / (STEALTH_FACTOR + stealthy)) :
294: WAKE_PERCENT))) {
295: wake_up(monster);
296: }
297: return;
298: } else if (monster->m_flags & ALREADY_MOVED) {
299: monster->m_flags &= (~ALREADY_MOVED);
300: return;
301: }
302: if ((monster->m_flags & FLITS) && flit(monster)) {
303: return;
304: }
305: if ((monster->m_flags & STATIONARY) &&
306: (!mon_can_go(monster, rogue.row, rogue.col))) {
307: return;
308: }
309: if (monster->m_flags & FREEZING_ROGUE) {
310: return;
311: }
312: if ((monster->m_flags & CONFUSES) && m_confuse(monster)) {
313: return;
314: }
315: if (mon_can_go(monster, rogue.row, rogue.col)) {
316: mon_hit(monster);
317: return;
318: }
319: if ((monster->m_flags & FLAMES) && flame_broil(monster)) {
320: return;
321: }
322: if ((monster->m_flags & SEEKS_GOLD) && seek_gold(monster)) {
323: return;
324: }
325: if ((monster->trow == monster->row) &&
326: (monster->tcol == monster->col)) {
327: monster->trow = NO_ROOM;
328: } else if (monster->trow != NO_ROOM) {
329: row = monster->trow;
330: col = monster->tcol;
331: }
332: if (monster->row > row) {
333: row = monster->row - 1;
334: } else if (monster->row < row) {
335: row = monster->row + 1;
336: }
337: if ((dungeon[row][monster->col] & DOOR) &&
338: mtry(monster, row, monster->col)) {
339: return;
340: }
341: if (monster->col > col) {
342: col = monster->col - 1;
343: } else if (monster->col < col) {
344: col = monster->col + 1;
345: }
346: if ((dungeon[monster->row][col] & DOOR) &&
347: mtry(monster, monster->row, col)) {
348: return;
349: }
350: if (mtry(monster, row, col)) {
351: return;
352: }
353:
354: for (i = 0; i <= 5; i++) tried[i] = 0;
355:
356: for (i = 0; i < 6; i++) {
357: NEXT_TRY: n = get_rand(0, 5);
358: switch(n) {
359: case 0:
360: if (!tried[n] && mtry(monster, row, monster->col-1)) {
361: goto O;
362: }
363: break;
364: case 1:
365: if (!tried[n] && mtry(monster, row, monster->col)) {
366: goto O;
367: }
368: break;
369: case 2:
370: if (!tried[n] && mtry(monster, row, monster->col+1)) {
371: goto O;
372: }
373: break;
374: case 3:
375: if (!tried[n] && mtry(monster, monster->row-1, col)) {
376: goto O;
377: }
378: break;
379: case 4:
380: if (!tried[n] && mtry(monster, monster->row, col)) {
381: goto O;
382: }
383: break;
384: case 5:
385: if (!tried[n] && mtry(monster, monster->row+1, col)) {
386: goto O;
387: }
388: break;
389: }
390: if (!tried[n]) {
391: tried[n] = 1;
392: } else {
393: goto NEXT_TRY;
394: }
395: }
396: O:
397: if ((monster->row == monster->o_row) && (monster->col == monster->o_col)) {
398: if (++(monster->o) > 4) {
399: if ((monster->trow == NO_ROOM) &&
400: (!mon_sees(monster, rogue.row, rogue.col))) {
401: monster->trow = get_rand(1, (DROWS - 2));
402: monster->tcol = get_rand(0, (DCOLS - 1));
403: } else {
404: monster->trow = NO_ROOM;
405: monster->o = 0;
406: }
407: }
408: } else {
409: monster->o_row = monster->row;
410: monster->o_col = monster->col;
411: monster->o = 0;
412: }
413: }
414:
415: mtry(monster, row, col)
416: register object *monster;
417: register short row, col;
418: {
419: if (mon_can_go(monster, row, col)) {
420: move_mon_to(monster, row, col);
421: return(1);
422: }
423: return(0);
424: }
425:
426: move_mon_to(monster, row, col)
427: register object *monster;
428: register short row, col;
429: {
430: short c;
431: register mrow, mcol;
432:
433: mrow = monster->row;
434: mcol = monster->col;
435:
436: dungeon[mrow][mcol] &= ~MONSTER;
437: dungeon[row][col] |= MONSTER;
438:
439: c = mvinch(mrow, mcol);
440:
441: if ((c >= 'A') && (c <= 'Z')) {
442: if (!detect_monster) {
443: mvaddch(mrow, mcol, monster->trail_char);
444: } else {
445: if (rogue_can_see(mrow, mcol)) {
446: mvaddch(mrow, mcol, monster->trail_char);
447: } else {
448: if (monster->trail_char == '.') {
449: monster->trail_char = ' ';
450: }
451: mvaddch(mrow, mcol, monster->trail_char);
452: }
453: }
454: }
455: monster->trail_char = mvinch(row, col);
456: if (!blind && (detect_monster || rogue_can_see(row, col))) {
457: if ((!(monster->m_flags & INVISIBLE) ||
458: (detect_monster || see_invisible || r_see_invisible))) {
459: mvaddch(row, col, gmc(monster));
460: }
461: }
462: if ((dungeon[row][col] & DOOR) &&
463: (get_room_number(row, col) != cur_room) &&
464: (dungeon[mrow][mcol] == FLOOR) && !blind) {
465: mvaddch(mrow, mcol, ' ');
466: }
467: if (dungeon[row][col] & DOOR) {
468: dr_course(monster, ((dungeon[mrow][mcol] & TUNNEL) ? 1 : 0),
469: row, col);
470: } else {
471: monster->row = row;
472: monster->col = col;
473: }
474: }
475:
476: mon_can_go(monster, row, col)
477: register object *monster;
478: register short row, col;
479: {
480: object *obj;
481: short dr, dc;
482:
483: dr = monster->row - row; /* check if move distance > 1 */
484: if ((dr >= 2) || (dr <= -2)) {
485: return(0);
486: }
487: dc = monster->col - col;
488: if ((dc >= 2) || (dc <= -2)) {
489: return(0);
490: }
491: if ((!dungeon[monster->row][col]) || (!dungeon[row][monster->col])) {
492: return(0);
493: }
494: if ((!is_passable(row, col)) || (dungeon[row][col] & MONSTER)) {
495: return(0);
496: }
497: if ((monster->row!=row)&&(monster->col!=col)&&((dungeon[row][col]&DOOR) ||
498: (dungeon[monster->row][monster->col]&DOOR))) {
499: return(0);
500: }
501: if (!(monster->m_flags & (FLITS | CONFUSED | CAN_FLIT)) &&
502: (monster->trow == NO_ROOM)) {
503: if ((monster->row < rogue.row) && (row < monster->row)) return(0);
504: if ((monster->row > rogue.row) && (row > monster->row)) return(0);
505: if ((monster->col < rogue.col) && (col < monster->col)) return(0);
506: if ((monster->col > rogue.col) && (col > monster->col)) return(0);
507: }
508: if (dungeon[row][col] & OBJECT) {
509: obj = object_at(&level_objects, row, col);
510: if ((obj->what_is == SCROL) && (obj->which_kind == SCARE_MONSTER)) {
511: return(0);
512: }
513: }
514: return(1);
515: }
516:
517: wake_up(monster)
518: object *monster;
519: {
520: if (!(monster->m_flags & NAPPING)) {
521: monster->m_flags &= (~(ASLEEP | IMITATES | WAKENS));
522: }
523: }
524:
525: wake_room(rn, entering, row, col)
526: short rn;
527: boolean entering;
528: short row, col;
529: {
530: object *monster;
531: short wake_percent;
532: boolean in_room;
533:
534: wake_percent = (rn == party_room) ? PARTY_WAKE_PERCENT : WAKE_PERCENT;
535: if (stealthy > 0) {
536: wake_percent /= (STEALTH_FACTOR + stealthy);
537: }
538:
539: monster = level_monsters.next_monster;
540:
541: while (monster) {
542: in_room = (rn == get_room_number(monster->row, monster->col));
543: if (in_room) {
544: if (entering) {
545: monster->trow = NO_ROOM;
546: } else {
547: monster->trow = row;
548: monster->tcol = col;
549: }
550: }
551: if ((monster->m_flags & WAKENS) &&
552: (rn == get_room_number(monster->row, monster->col))) {
553: if (rand_percent(wake_percent)) {
554: wake_up(monster);
555: }
556: }
557: monster = monster->next_monster;
558: }
559: }
560:
561: char *
562: mon_name(monster)
563: object *monster;
564: {
565: short ch;
566:
567: if (blind || ((monster->m_flags & INVISIBLE) &&
568: !(detect_monster || see_invisible || r_see_invisible))) {
569: return("something");
570: }
571: if (halluc) {
572: ch = get_rand('A', 'Z') - 'A';
573: return(m_names[ch]);
574: }
575: ch = monster->m_char - 'A';
576: return(m_names[ch]);
577: }
578:
579: rogue_is_around(row, col)
580: register row, col;
581: {
582: short rdif, cdif, retval;
583:
584: rdif = row - rogue.row;
585: cdif = col - rogue.col;
586:
587: retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
588: return(retval);
589: }
590:
591: wanderer()
592: {
593: object *monster;
594: short row, col, i;
595: boolean found = 0;
596:
597: for (i = 0; ((i < 15) && (!found)); i++) {
598: monster = gr_monster((object *) 0, 0);
599: if (!(monster->m_flags & (WAKENS | WANDERS))) {
600: free_object(monster);
601: } else {
602: found = 1;
603: }
604: }
605: if (found) {
606: found = 0;
607: wake_up(monster);
608: for (i = 0; ((i < 25) && (!found)); i++) {
609: gr_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT));
610: if (!rogue_can_see(row, col)) {
611: put_m_at(row, col, monster);
612: found = 1;
613: }
614: }
615: if (!found) {
616: free_object(monster);
617: }
618: }
619: }
620:
621: show_monsters()
622: {
623: object *monster;
624:
625: detect_monster = 1;
626:
627: if (blind) {
628: return;
629: }
630: monster = level_monsters.next_monster;
631:
632: while (monster) {
633: mvaddch(monster->row, monster->col, monster->m_char);
634: if (monster->m_flags & IMITATES) {
635: monster->m_flags &= (~IMITATES);
636: monster->m_flags |= WAKENS;
637: }
638: monster = monster->next_monster;
639: }
640: }
641:
642: create_monster()
643: {
644: short row, col;
645: short i;
646: boolean found = 0;
647: object *monster;
648:
649: row = rogue.row;
650: col = rogue.col;
651:
652: for (i = 0; i < 9; i++) {
653: rand_around(i, &row, &col);
654: if (((row == rogue.row) && (col = rogue.col)) ||
655: (row < MIN_ROW) || (row > (DROWS-2)) ||
656: (col < 0) || (col > (DCOLS-1))) {
657: continue;
658: }
659: if ((!(dungeon[row][col] & MONSTER)) &&
660: (dungeon[row][col] & (FLOOR|TUNNEL|STAIRS|DOOR))) {
661: found = 1;
662: break;
663: }
664: }
665: if (found) {
666: monster = gr_monster((object *) 0, 0);
667: put_m_at(row, col, monster);
668: mvaddch(row, col, gmc(monster));
669: if (monster->m_flags & (WANDERS | WAKENS)) {
670: wake_up(monster);
671: }
672: } else {
673: message("you hear a faint cry of anguish in the distance", 0);
674: }
675: }
676:
677: put_m_at(row, col, monster)
678: short row, col;
679: object *monster;
680: {
681: monster->row = row;
682: monster->col = col;
683: dungeon[row][col] |= MONSTER;
684: monster->trail_char = mvinch(row, col);
685: (void) add_to_pack(monster, &level_monsters, 0);
686: aim_monster(monster);
687: }
688:
689: aim_monster(monster)
690: object *monster;
691: {
692: short i, rn, d, r;
693:
694: rn = get_room_number(monster->row, monster->col);
695: r = get_rand(0, 12);
696:
697: for (i = 0; i < 4; i++) {
698: d = (r + i) % 4;
699: if (rooms[rn].doors[d].oth_room != NO_ROOM) {
700: monster->trow = rooms[rn].doors[d].door_row;
701: monster->tcol = rooms[rn].doors[d].door_col;
702: break;
703: }
704: }
705: }
706:
707: rogue_can_see(row, col)
708: register row, col;
709: {
710: register retval;
711:
712: retval = !blind &&
713: (((get_room_number(row, col) == cur_room) &&
714: !(rooms[cur_room].is_room & R_MAZE)) ||
715: rogue_is_around(row, col));
716:
717: return(retval);
718: }
719:
720: move_confused(monster)
721: object *monster;
722: {
723: short i, row, col;
724:
725: if (!(monster->m_flags & ASLEEP)) {
726: if (--monster->moves_confused <= 0) {
727: monster->m_flags &= (~CONFUSED);
728: }
729: if (monster->m_flags & STATIONARY) {
730: return(coin_toss() ? 1 : 0);
731: } else if (rand_percent(15)) {
732: return(1);
733: }
734: row = monster->row;
735: col = monster->col;
736:
737: for (i = 0; i < 9; i++) {
738: rand_around(i, &row, &col);
739: if ((row == rogue.row) && (col == rogue.col)) {
740: return(0);
741: }
742: if (mtry(monster, row, col)) {
743: return(1);
744: }
745: }
746: }
747: return(0);
748: }
749:
750: flit(monster)
751: object *monster;
752: {
753: short i, row, col;
754:
755: if (!rand_percent(FLIT_PERCENT + ((monster->m_flags & FLIES) ? 20 : 0))) {
756: return(0);
757: }
758: if (rand_percent(10)) {
759: return(1);
760: }
761: row = monster->row;
762: col = monster->col;
763:
764: for (i = 0; i < 9; i++) {
765: rand_around(i, &row, &col);
766: if ((row == rogue.row) && (col == rogue.col)) {
767: continue;
768: }
769: if (mtry(monster, row, col)) {
770: return(1);
771: }
772: }
773: return(1);
774: }
775:
776: gr_obj_char()
777: {
778: short r;
779: char *rs = "%!?]=/):*";
780:
781: r = get_rand(0, 8);
782:
783: return(rs[r]);
784: }
785:
786: no_room_for_monster(rn)
787: int rn;
788: {
789: short i, j;
790:
791: for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
792: for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
793: if (!(dungeon[i][j] & MONSTER)) {
794: return(0);
795: }
796: }
797: }
798: return(1);
799: }
800:
801: aggravate()
802: {
803: object *monster;
804:
805: message("you hear a high pitched humming noise", 0);
806:
807: monster = level_monsters.next_monster;
808:
809: while (monster) {
810: wake_up(monster);
811: monster->m_flags &= (~IMITATES);
812: if (rogue_can_see(monster->row, monster->col)) {
813: mvaddch(monster->row, monster->col, monster->m_char);
814: }
815: monster = monster->next_monster;
816: }
817: }
818:
819: boolean
820: mon_sees(monster, row, col)
821: object *monster;
822: {
823: short rn, rdif, cdif, retval;
824:
825: rn = get_room_number(row, col);
826:
827: if ( (rn != NO_ROOM) &&
828: (rn == get_room_number(monster->row, monster->col)) &&
829: !(rooms[rn].is_room & R_MAZE)) {
830: return(1);
831: }
832: rdif = row - monster->row;
833: cdif = col - monster->col;
834:
835: retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1);
836: return(retval);
837: }
838:
839: mv_aquatars()
840: {
841: object *monster;
842:
843: monster = level_monsters.next_monster;
844:
845: while (monster) {
846: if ((monster->m_char == 'A') &&
847: mon_can_go(monster, rogue.row, rogue.col)) {
848: mv_1_monster(monster, rogue.row, rogue.col);
849: monster->m_flags |= ALREADY_MOVED;
850: }
851: monster = monster->next_monster;
852: }
853: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.