# 2.11BSD#431 - /usr/src/games/rogue/monster.c

##### Functions

    aggravate         X
    aim_monster       X
    create_monster    X
    flit              X
    gmc               X
    gmc_row_col       X
    gr_monster        X
    gr_obj_char       X
    mon_can_go        X
    mon_name          X
    mon_sees          X
    move_confused     X
    move_mon_to       X
    mtry              X
    mv_1_monster      X
    mv_aquatars       X
    mv_mons           X
    no_room_for_monsterX
    party_monsters    X
    put_m_at          X
    put_mons          X
    rogue_can_see     X
    rogue_is_around   X
    show_monsters     X
    wake_room         X
    wake_up           X
    wanderer          X

##### Variables

    level_monsters    X
    m_names           X
    mon_tab           X

       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: }

#### Defined functions

aggravate defined in line 779; used 1 times

- in /usr/src/games/rogue/use.c line 241

aim_monster defined in line 667; used 1 times

- in line 664

create_monster defined in line 620; used 1 times

- in /usr/src/games/rogue/use.c line 238

flit defined in line 728; used 1 times

- in line 280

gmc defined in line 240; used 3 times

- in line 437, 646
- in /usr/src/games/rogue/zap.c line 183

gmc_row_col defined in line 221; used 1 times

- in /usr/src/games/rogue/room.c line 140

gr_monster defined in line 109; used 6 times

- in line 100, 209, 576, 644
- in /usr/src/games/rogue/rogue.h line 418
- in /usr/src/games/rogue/zap.c line 140

gr_obj_char defined in line 754; used 2 times

- in line 127
- in /usr/src/games/rogue/use.c line 457

mon_can_go defined in line 454; used 7 times

- in line 167, 174, 284, 293, 397, 825
- in /usr/src/games/rogue/spec_hit.c line 277

mon_name defined in line 539; used 9 times

- in /usr/src/games/rogue/hit.c line 49, 269
- in /usr/src/games/rogue/rogue.h line 400
- in /usr/src/games/rogue/spec_hit.c line 328, 367, 435
- in /usr/src/games/rogue/zap.c line 296, 312, 329

mon_sees defined in line 797; used 4 times

- in line 378
- in /usr/src/games/rogue/rogue.h line 407
- in /usr/src/games/rogue/room.c line 381
- in /usr/src/games/rogue/spec_hit.c line 448

move_confused defined in line 698; used 1 times

- in line 161

move_mon_to defined in line 404; used 2 times

- in line 398
- in /usr/src/games/rogue/spec_hit.c line 280

mtry defined in line 393; used 11 times

- in line 316, 325-328(2), 338-363(6), 720, 747

mv_1_monster defined in line 254; used 5 times

- in line 151, 169, 175, 826
- in /usr/src/games/rogue/spec_hit.c line 287

mv_aquatars defined in line 817; used 3 times

- in /usr/src/games/rogue/pack.c line 143, 279
- in /usr/src/games/rogue/throw.c line 60

mv_mons defined in line 136; used 5 times

- in /usr/src/games/rogue/move.c line 368, 416
- in /usr/src/games/rogue/spec_hit.c line 98-102(2)
- in /usr/src/games/rogue/use.c line 510

no_room_for_monster defined in line 764; used 1 times

- in line 195

party_monsters defined in line 181; used 1 times

- in /usr/src/games/rogue/object.c line 613

put_m_at defined in line 655; used 4 times

- in line 105, 213, 589, 645

put_mons defined in line 90; used 1 times

- in /usr/src/games/rogue/main.c line 35

rogue_can_see defined in line 685; used 11 times

- in line 423, 434, 588, 790
- in /usr/src/games/rogue/spec_hit.c line 194, 426
- in /usr/src/games/rogue/throw.c line 70, 144-147(2), 195
- in /usr/src/games/rogue/zap.c line 182

rogue_is_around defined in line 557; used 2 times

- in line 269, 693

show_monsters defined in line 599; used 3 times

- in /usr/src/games/rogue/play.c line 249
- in /usr/src/games/rogue/use.c line 103, 488

wake_room defined in line 503; used 3 times

- in /usr/src/games/rogue/level.c line 716
- in /usr/src/games/rogue/move.c line 76, 83

wake_up defined in line 495; used 14 times

- in line 102, 273, 532, 585, 648, 788
- in /usr/src/games/rogue/hit.c line 121
- in /usr/src/games/rogue/spec_hit.c line 323
- in /usr/src/games/rogue/throw.c line 74
- in /usr/src/games/rogue/zap.c line 68, 146, 223, 230, 294

wanderer defined in line 569; used 1 times

- in /usr/src/games/rogue/move.c line 420

#### Defined variables

level_monsters defined in line 19; used 7 times

- in line 145, 226, 517, 608, 663, 785, 821

m_names defined in line 22; used 7 times

- in line 551-554(2)
- in /usr/src/games/rogue/inventory.c line 672
- in /usr/src/games/rogue/score.c line 58-63(2), 326-331(2)

mon_tab defined in line 51; used 5 times

- in line 119-125(3), 192, 217

sccsid defined in line 14; never used

Last modified: 1987-11-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3128 |