Annotation of 43BSDTahoe/games/rogue/monster.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.