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

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

unix.superglobalmegacorp.com

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