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