|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.