|
|
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.