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