[BACK]Return to command.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / arogue7

Annotation of early-roguelike/arogue7/command.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * command.c  -  Read and execute the user commands
                      3:  *
                      4:  * Advanced Rogue
                      5:  * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
                      6:  * All rights reserved.
                      7:  *
                      8:  * Based on "Rogue: Exploring the Dungeons of Doom"
                      9:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     10:  * All rights reserved.
                     11:  *
                     12:  * See the file LICENSE.TXT for full copyright and licensing information.
                     13:  */
                     14:
                     15: /*
                     16:  * Read and execute the user commands
                     17:  *
                     18:  */
                     19:
                     20: #include "curses.h"
                     21: #include <ctype.h>
                     22: #include <string.h>
                     23: #include <stdlib.h>
                     24: #include <signal.h>
                     25: #include "mach_dep.h"
                     26: #include "rogue.h"
                     27: #ifdef PC7300
                     28: #include "sys/window.h"
                     29: extern struct uwdata wdata;
                     30: #endif
                     31:
                     32: void display(void);
                     33: void help(void);
                     34: void identify(char ch);
                     35: void d_level(void);
                     36: void u_level(void);
                     37: void shell(void);
                     38: void nameit(void);
                     39: void namemonst(void);
                     40: void count_gold(void);
                     41:
                     42: /*
                     43:  * command:
                     44:  *     Process the user commands
                     45:  */
                     46:
                     47: void
                     48: command(void)
                     49: {
                     50:     unsigned char ch;
                     51:     struct linked_list *item;
                     52:     unsigned char countch, direction, newcount = FALSE;
                     53:     int segment = 1;
                     54:     int monst_limit, monst_current;
                     55:
                     56:     monst_limit = monst_current = 1;
                     57:     while (playing) {
                     58:        /*
                     59:         * Let the daemons start up, but only do them once a round
                     60:         * (round = 10 segments).
                     61:         */
                     62:        if (segment >= 10) {
                     63:            do_daemons(BEFORE);
                     64:            do_fuses(BEFORE);
                     65:        }
                     66:
                     67:        after = TRUE;
                     68:        do {
                     69:            /* One more tick of the clock. */
                     70:            if (segment >= 10 && after && (++turns % DAYLENGTH) == 0) {
                     71:                daytime ^= TRUE;
                     72:                if (levtype == OUTSIDE) {
                     73:                    if (daytime) msg("The sun rises above the horizon");
                     74:                    else msg("The sun sinks below the horizon");
                     75:                }
                     76:                light(&hero);
                     77:            }
                     78:
                     79:            /*
                     80:             * Don't bother with these updates unless the player's going
                     81:             * to do something.
                     82:             */
                     83:            if (player.t_action == A_NIL && player.t_no_move <= 1) {
                     84:                look(after, FALSE);
                     85:                lastscore = purse;
                     86:                wmove(cw, hero.y, hero.x);
                     87:                if (!((running || count) && jump)) {
                     88:                    status(FALSE);
                     89:                }
                     90:            }
                     91:
                     92:            /* Draw the screen */
                     93:            if (!((running || count) && jump)) {
                     94:                wmove(cw, hero.y, hero.x);
                     95:                draw(cw);
                     96:            }
                     97:
                     98:            after = TRUE;
                     99:
                    100:            /*
                    101:             * Read command or continue run
                    102:             */
                    103:            if (--player.t_no_move <= 0) {
                    104:                take = 0;               /* Nothing here to start with */
                    105:                player.t_no_move = 0;   /* Be sure we don't go too negative */
                    106:                if (!running) door_stop = FALSE;
                    107:
                    108:                /* Was the player being held? */
                    109:                if (player.t_action == A_FREEZE) {
                    110:                    player.t_action = A_NIL;
                    111:                    msg("You can move again.");
                    112:                }
                    113:
                    114:                if (player.t_action != A_NIL) ch = (char) player.t_action;
                    115:                else if (running) {
                    116:                    char scratch;
                    117:
                    118:                    /* If in a corridor or maze, if we are at a turn with
                    119:                     * only one way to go, turn that way.
                    120:                     */
                    121:                    scratch = CCHAR( winat(hero.y, hero.x) );
                    122:                    if ((scratch==PASSAGE||scratch==DOOR||levtype==MAZELEV)  &&
                    123:                        off(player, ISHUH)                                   &&
                    124:                        off(player, ISBLIND)) {
                    125:                        int y, x;
                    126:                        if (getdelta(runch, &y, &x) == TRUE) {
                    127:                            corr_move(y, x);
                    128:                        }
                    129:                    }
                    130:                    ch = runch;
                    131:                }
                    132:                else if (count) ch = countch;
                    133:                else {
                    134:                    ch = readchar();
                    135:                    if (mpos != 0 && !running)  /* Erase message if its there */
                    136:                        msg("");
                    137:                }
                    138:
                    139:                /*
                    140:                 * check for prefixes
                    141:                 */
                    142:                if (isdigit(ch))
                    143:                {
                    144:                    count = 0;
                    145:                    newcount = TRUE;
                    146:                    while (isdigit(ch))
                    147:                    {
                    148:                        count = count * 10 + (ch - '0');
                    149:                        if (count > 255)
                    150:                                count = 255;
                    151:                        ch = readchar();
                    152:                    }
                    153:                    countch = ch;
                    154:                    /*
                    155:                     * turn off count for commands which don't make sense
                    156:                     * to repeat
                    157:                     */
                    158:                    switch (ch) {
                    159:                        case 'h': case 'j': case 'k': case 'l':
                    160:                        case 'y': case 'u': case 'b': case 'n':
                    161:                        case 'H': case 'J': case 'K': case 'L':
                    162:                        case 'Y': case 'U': case 'B': case 'N':
                    163:                        case C_SEARCH: case '.':
                    164:                            break;
                    165:                        default:
                    166:                            count = 0;
                    167:                    }
                    168:                }
                    169:
                    170:                /* Save current direction */
                    171:                if (!running) { /* If running, it is already saved */
                    172:                    switch (ch) {
                    173:                        case 'h': case 'j': case 'k': case 'l':
                    174:                        case 'y': case 'u': case 'b': case 'n':
                    175:                        case 'H': case 'J': case 'K': case 'L':
                    176:                        case 'Y': case 'U': case 'B': case 'N':
                    177:                            runch = tolower(ch);
                    178:                    }
                    179:                }
                    180:
                    181:                /* Perform the action */
                    182:                switch (ch) {
                    183:                    case 'f':
                    184:                        if (!on(player, ISBLIND))
                    185:                        {
                    186:                            door_stop = TRUE;
                    187:                            firstmove = TRUE;
                    188:                        }
                    189:                        if (count && !newcount)
                    190:                            ch = direction;
                    191:                        else
                    192:                            ch = readchar();
                    193:                        switch (ch)
                    194:                        {
                    195:                            case 'h': case 'j': case 'k': case 'l':
                    196:                            case 'y': case 'u': case 'b': case 'n':
                    197:                                ch = toupper(ch);
                    198:                        }
                    199:                        direction = ch;
                    200:                }
                    201:                newcount = FALSE;
                    202:
                    203:                /*
                    204:                 * execute a command
                    205:                 */
                    206:                if (count && !running && player.t_action == A_NIL)
                    207:                    count--;
                    208:                switch (ch) {
                    209:                    case '!' : shell();
                    210:                    when 'h' : do_move(0, -1);
                    211:                    when 'j' : do_move(1, 0);
                    212:                    when 'k' : do_move(-1, 0);
                    213:                    when 'l' : do_move(0, 1);
                    214:                    when 'y' : do_move(-1, -1);
                    215:                    when 'u' : do_move(-1, 1);
                    216:                    when 'b' : do_move(1, -1);
                    217:                    when 'n' : do_move(1, 1);
                    218:                    when 'H' : do_run('h');
                    219:                    when 'J' : do_run('j');
                    220:                    when 'K' : do_run('k');
                    221:                    when 'L' : do_run('l');
                    222:                    when 'Y' : do_run('y');
                    223:                    when 'U' : do_run('u');
                    224:                    when 'B' : do_run('b');
                    225:                    when 'N' : do_run('n');
                    226:                    when A_PICKUP:
                    227:                        player.t_action = A_NIL;
                    228:                        if (add_pack(NULL, FALSE, NULL)) {
                    229:                            char tch;
                    230:
                    231:                            tch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
                    232:                            if (tch != FLOOR && tch != PASSAGE) {
                    233:                                player.t_action = A_PICKUP; /*get more */
                    234:                                player.t_no_move += 2 * movement(&player);
                    235:                            }
                    236:                        }
                    237:                    when A_ATTACK:
                    238:                        /* Is our attackee still there? */
                    239:                        if (isalpha(winat(player.t_newpos.y,
                    240:                                          player.t_newpos.x))) {
                    241:                            /* Our friend is still here */
                    242:                            player.t_action = A_NIL;
                    243:                            fight(&player.t_newpos, cur_weapon, FALSE);
                    244:                        }
                    245:                        else {  /* Our monster has moved */
                    246:                            player.t_action = A_NIL;
                    247:                        }
                    248:                    when A_THROW:
                    249:                        if (player.t_action == A_NIL) {
                    250:                            item = get_item(pack, "throw", ALL, FALSE, FALSE);
                    251:                            if (item != NULL && get_dir(&player.t_newpos)) {
                    252:                                player.t_action = A_THROW;
                    253:                                player.t_using = item;
                    254:                                player.t_no_move = 2 * movement(&player);
                    255:                            }
                    256:                            else
                    257:                                after = FALSE;
                    258:                        }
                    259:                        else {
                    260:                            missile(player.t_newpos.y, player.t_newpos.x,
                    261:                                    player.t_using, &player);
                    262:                            player.t_action = A_NIL;
                    263:                            player.t_using = 0;
                    264:                        }
                    265:                    when 'Q' : after = FALSE; quit(0);
                    266:                    when 'i' : after = FALSE; inventory(pack, ALL);
                    267:                    when 'I' : after = FALSE; picky_inven();
                    268:                    when C_DROP : player.t_action = C_DROP; drop(NULL);
                    269:                    when 'P' :
                    270:                        if (levtype != POSTLEV) {
                    271:                            /* We charge 2 movement units per item */
                    272:                            player.t_no_move =
                    273:                                2 * grab(hero.y, hero.x) * movement(&player);
                    274:                        }
                    275:                        else {
                    276:                            /* Let's quote the wise guy a price */
                    277:                            buy_it();
                    278:                            after = FALSE;
                    279:                        }
                    280:                    when C_COUNT : count_gold();
                    281:                    when C_QUAFF : quaff(-1, 0, 0, TRUE);
                    282:                    when C_READ : read_scroll(-1, 0, TRUE);
                    283:                    when C_EAT : eat();
                    284:                    when C_WIELD : wield();
                    285:                    when C_WEAR : wear();
                    286:                    when C_TAKEOFF : take_off();
                    287:                    when 'o' : option();
                    288:                    when CTRL('N') : nameit();
                    289:                    when '=' : after = FALSE; display();
                    290:                    when 'm' : nameitem(NULL, TRUE);
                    291:                    when '>' : after = FALSE; d_level();
                    292:                    when '<' : after = FALSE; u_level();
                    293:                    when '?' : after = FALSE; help();
                    294:                    when '/' : after = FALSE; identify(0);
                    295:                    when C_USE : use_mm(-1);
                    296:                    when CTRL('T') :
                    297:                        if (player.t_action == A_NIL) {
                    298:                            if (get_dir(&player.t_newpos)) {
                    299:                                player.t_action = CTRL('T');
                    300:                                player.t_no_move = 2 * movement(&player);
                    301:                            }
                    302:                            else
                    303:                                after = FALSE;
                    304:                        }
                    305:                        else {
                    306:                            steal();
                    307:                            player.t_action = A_NIL;
                    308:                        }
                    309:                    when C_DIP : dip_it();
                    310:                    when 'G' :
                    311:                        if (player.t_action == A_NIL) {
                    312:                            player.t_action = 'G';
                    313:                            player.t_no_move = movement(&player);
                    314:                        }
                    315:                        else {
                    316:                            gsense();
                    317:                            player.t_action = A_NIL;
                    318:                        }
                    319:                    when C_SETTRAP : set_trap(&player, hero.y, hero.x);
                    320:                    when C_SEARCH :
                    321:                        if (player.t_action == A_NIL) {
                    322:                            player.t_action = C_SEARCH;
                    323:                            player.t_no_move = 5 * movement(&player);
                    324:                        }
                    325:                        else {
                    326:                            search(FALSE, FALSE);
                    327:                            player.t_action = A_NIL;
                    328:                        }
                    329:                    when C_ZAP : if (!player_zap(0, FALSE))
                    330:                                    after=FALSE;
                    331:                    when C_PRAY : pray();
                    332:                    when C_CHANT : chant();
                    333:                    when C_CAST : cast();
                    334:                    when 'a' :
                    335:                        if (player.t_action == A_NIL) {
                    336:                            if (get_dir(&player.t_newpos)) {
                    337:                                player.t_action = 'a';
                    338:                                player.t_no_move = 2 * movement(&player);
                    339:                            }
                    340:                            else
                    341:                                after = FALSE;
                    342:                        }
                    343:                        else {
                    344:                            affect();
                    345:                            player.t_action = A_NIL;
                    346:                        }
                    347:                    when 'v' : after = FALSE;
                    348:                               msg("Advanced Rogue Version %s.",
                    349:                                    release);
                    350:                    when CTRL('L') : after = FALSE; clearok(curscr, TRUE);
                    351:                                    touchwin(cw); /* MMMMMMMMMM */
                    352:                    when CTRL('R') : after = FALSE; msg(huh);
                    353:                    when 'S' :
                    354:                        after = FALSE;
                    355:                        if (save_game())
                    356:                        {
                    357:                            wclear(cw);
                    358:                            draw(cw);
                    359:                            endwin();
                    360: #ifdef PC7300
                    361:                            endhardwin();
                    362: #endif
                    363:                            exit(0);
                    364:                        }
                    365:                    when '.' :
                    366:                        player.t_no_move = movement(&player);  /* Rest */
                    367:                        player.t_action = A_NIL;
                    368:                    when ' ' : after = FALSE;   /* Do Nothing */
                    369: #ifdef WIZARD
                    370:                    when CTRL('P') :
                    371:                        after = FALSE;
                    372:                        if (wizard)
                    373:                        {
                    374:                            wizard = FALSE;
                    375:                            trader = 0;
                    376:                            msg("Not wizard any more");
                    377:                        }
                    378:                        else
                    379:                        {
                    380:                            if (waswizard || passwd())
                    381:                            {
                    382:                                msg("Welcome, oh mighty wizard.");
                    383:                                wizard = waswizard = TRUE;
                    384:                            }
                    385:                            else
                    386:                                msg("Sorry");
                    387:                        }
                    388: #endif
                    389:                    when ESCAPE :       /* Escape */
                    390:                        door_stop = FALSE;
                    391:                        count = 0;
                    392:                        after = FALSE;
                    393:                    when '#':
                    394:                        if (levtype == POSTLEV)         /* buy something */
                    395:                            buy_it();
                    396:                        after = FALSE;
                    397:                    when '$':
                    398:                        if (levtype == POSTLEV)         /* price something */
                    399:                            price_it();
                    400:                        after = FALSE;
                    401:                    when '%':
                    402:                        if (levtype == POSTLEV)         /* sell something */
                    403:                            sell_it();
                    404:                        after = FALSE;
                    405:                    otherwise :
                    406:                        after = FALSE;
                    407: #ifdef WIZARD
                    408:                        if (wizard) switch (ch)
                    409:                        {
                    410:                            case 'M' : create_obj(TRUE, 0, 0);
                    411:                            when CTRL('W') : wanderer();
                    412:                            when CTRL('I') : inventory(lvl_obj, ALL);
                    413:                            when CTRL('Z') : whatis(NULL);
                    414:                            when CTRL('D') : level++; new_level(NORMLEV);
                    415:                            when CTRL('F') : overlay(stdscr,cw);
                    416:                            when CTRL('X') : overlay(mw,cw);
                    417:                            when CTRL('J') : teleport();
                    418:                            when CTRL('E') : msg("food left: %d\tfood level: %d",
                    419:                                                    food_left, foodlev);
                    420:                            when CTRL('A') : activity();
                    421:                            when CTRL('C') :
                    422:                            {
                    423:                                int tlev;
                    424:                                prbuf[0] = 0;
                    425:                                msg("Which level? ");
                    426:                                if(get_str(prbuf,msgw) == NORM) {
                    427:                                    tlev = atoi(prbuf);
                    428:                                    if(tlev < 1) {
                    429:                                        mpos = 0;
                    430:                                        msg("Illegal level.");
                    431:                                    }
                    432:                                    else if (tlev > 199) {
                    433:                                            levtype = MAZELEV;
                    434:                                            level = tlev - 200 + 1;
                    435:                                    }
                    436:                                    else if (tlev > 99) {
                    437:                                            levtype = POSTLEV;
                    438:                                            level = tlev - 100 + 1;
                    439:                                    }
                    440:                                    else {
                    441:                                            levtype = NORMLEV;
                    442:                                            level = tlev;
                    443:                                    }
                    444:                                    new_level(levtype);
                    445:                                }
                    446:                            }
                    447:                            when CTRL('G') :
                    448:                            {
                    449:                                item=get_item(pack,"charge",STICK,FALSE,FALSE);
                    450:                                if (item != NULL) {
                    451:                                    (OBJPTR(item))->o_charges=10000;
                    452:                                }
                    453:                            }
                    454:                            when CTRL('H') :
                    455:                            {
                    456:                                register int i;
                    457:                                register struct object *obj;
                    458:
                    459:                                for (i = 0; i < 9; i++)
                    460:                                    raise_level();
                    461:                                /*
                    462:                                 * Give the rogue a sword
                    463:                                 */
                    464:                                if (cur_weapon==NULL || cur_weapon->o_type !=
                    465:                                    RELIC) {
                    466:                                    item = spec_item(WEAPON, TWOSWORD, 5, 5);
                    467:                                    add_pack(item, TRUE, NULL);
                    468:                                    cur_weapon = OBJPTR(item);
                    469:                                    (OBJPTR(item))->o_flags |= (ISKNOW|ISPROT);
                    470:                                }
                    471:                                /*
                    472:                                 * And his suit of armor
                    473:                                 */
                    474:                                if (player.t_ctype != C_MONK) {
                    475:                                    item = spec_item(ARMOR, PLATE_ARMOR, 10, 0);
                    476:                                    obj = OBJPTR(item);
                    477:                                    if (player.t_ctype == C_THIEF)
                    478:                                        obj->o_which = STUDDED_LEATHER;
                    479:                                    obj->o_flags |= (ISKNOW | ISPROT);
                    480:                                    obj->o_weight = armors[PLATE_ARMOR].a_wght;
                    481:                                    cur_armor = obj;
                    482:                                    add_pack(item, TRUE, NULL);
                    483:                                }
                    484:                                purse += 20000;
                    485:                            }
                    486:                            otherwise :
                    487:                                msg("Illegal command '%s'.", unctrl(ch));
                    488:                                count = 0;
                    489:                        }
                    490:                        else
                    491: #endif
                    492:                        {
                    493:                            msg("Illegal command '%s'.", unctrl(ch));
                    494:                            count = 0;
                    495:                            after = FALSE;
                    496:                        }
                    497:                }
                    498:
                    499:                /*
                    500:                 * If he ran into something to take, let him pick it up.
                    501:                 * unless it's a trading post
                    502:                 */
                    503:                if (auto_pickup && take != 0 && levtype != POSTLEV) {
                    504:                    /* get ready to pick it up */
                    505:                    player.t_action = A_PICKUP;
                    506:                    player.t_no_move += 2 * movement(&player);
                    507:                }
                    508:            }
                    509:
                    510:            /* If he was fighting, let's stop (for now) */
                    511:            if (player.t_quiet < 0) player.t_quiet = 0;
                    512:
                    513:            if (!running)
                    514:                door_stop = FALSE;
                    515:
                    516:            if (after && segment >= 10) {
                    517:                /*
                    518:                 * Kick off the rest if the daemons and fuses
                    519:                 */
                    520:
                    521:                /*
                    522:                 * If player is infested, take off a hit point
                    523:                 */
                    524:                if (on(player, HASINFEST)) {
                    525:                    if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION);
                    526:                }
                    527:
                    528:                /*
                    529:                 * The eye of Vecna is a constant drain on the player
                    530:                 */
                    531:                if (cur_relic[EYE_VECNA]) {
                    532:                    if ((--pstats.s_hpt) <= 0) death(D_RELIC);
                    533:                }
                    534:
                    535:                /*
                    536:                 * if player has body rot then take off five hits
                    537:                 */
                    538:                if (on(player, DOROT)) {
                    539:                     if ((pstats.s_hpt -= 5) <= 0) death(D_ROT);
                    540:                }
                    541:                do_daemons(AFTER);
                    542:                do_fuses(AFTER);
                    543:            }
                    544:        } while (after == FALSE);
                    545:
                    546:        /* Make the monsters go */
                    547:        if (--monst_current <= 0)
                    548:            monst_current = monst_limit = runners(monst_limit);
                    549:
                    550: #ifdef NEEDLOOK
                    551:        /* Shall we take a look? */
                    552:        if (player.t_no_move <= 1 &&
                    553:            !((running || count) && jump))
                    554:            look(FALSE, FALSE);
                    555: #endif
                    556:
                    557:        if (++segment > 10) segment = 1;
                    558:        t_free_list(monst_dead);
                    559:     }
                    560: }
                    561:
                    562: /*
                    563:  * display
                    564:  *     tell the player what is at a certain coordinates assuming
                    565:  *     it can be seen.
                    566:  */
                    567: void
                    568: display(void)
                    569: {
                    570:     coord c;
                    571:     struct linked_list *item;
                    572:     struct thing *tp;
                    573:     int what;
                    574:
                    575:     msg("What do you want to display (* for help)?");
                    576:     c = get_coordinates();
                    577:     mpos = 0;
                    578:     if (!cansee(c.y, c.x)) {
                    579:        msg("You can't see what is there.");
                    580:        return;
                    581:     }
                    582:     what = mvwinch(cw, c.y, c.x);
                    583:     if (isalpha(what)) {
                    584:        item = find_mons(c.y, c.x);
                    585:        tp = THINGPTR(item);
                    586:        msg("%s", monster_name(tp));
                    587:        return;
                    588:     }
                    589:     if ((item = find_obj(c.y, c.x)) != NULL) {
                    590:        msg("%s", inv_name(OBJPTR(item), FALSE));
                    591:        return;
                    592:     }
                    593:     identify(what);
                    594: }
                    595:
                    596: /*
                    597:  * quit:
                    598:  *     Have player make certain, then exit.
                    599:  */
                    600:
                    601: void
                    602: quit(int sig)
                    603: {
                    604:     /*
                    605:      * Reset the signal in case we got here via an interrupt
                    606:      */
                    607:     if (signal(SIGINT, quit) != quit)
                    608:        mpos = 0;
                    609:     msg("Really quit? <yes or no> ");
                    610:     draw(cw);
                    611:     prbuf[0] = '\0';
                    612:     if ((get_str(prbuf, msgw) == NORM) && strcmp(prbuf, "yes") == 0) {
                    613:        clear();
                    614:        move(lines-1, 0);
                    615:        draw(stdscr);
                    616:        writelog(pstats.s_exp + (long) purse, CHICKEN, 0);
                    617:        score(pstats.s_exp + (long) purse, CHICKEN, 0);
                    618: #ifdef PC7300
                    619:        endhardwin();
                    620: #endif
                    621:        exit(0);
                    622:     }
                    623:     else
                    624:     {
                    625:        signal(SIGINT, quit);
                    626:        wmove(cw, 0, 0);
                    627:        wclrtoeol(cw);
                    628:        status(FALSE);
                    629:        draw(cw);
                    630:        mpos = 0;
                    631:        count = 0;
                    632:        running = FALSE;
                    633:     }
                    634: }
                    635:
                    636: /*
                    637:  * bugkill:
                    638:  *     killed by a program bug instead of voluntarily.
                    639:  */
                    640:
                    641: void
                    642: bugkill(int sig)
                    643: {
                    644:     signal(sig, quit); /* If we get it again, give up */
                    645:     death(D_SIGNAL);   /* Killed by a bug */
                    646: }
                    647:
                    648:
                    649: /*
                    650:  * search:
                    651:  *     Player gropes about him to find hidden things.
                    652:  */
                    653:
                    654: void
                    655: search(bool is_thief, bool door_chime)
                    656: {
                    657:     register int x, y;
                    658:     register char ch,  /* The trap or door character */
                    659:                 sch,   /* Trap or door character (as seen on screen) */
                    660:                 mch;   /* Monster, if a monster is on the trap or door */
                    661:     register struct linked_list *item;
                    662:     register struct thing *mp; /* Status on surrounding monster */
                    663:
                    664:     /*
                    665:      * Look all around the hero, if there is something hidden there,
                    666:      * give him a chance to find it.  If its found, display it.
                    667:      */
                    668:     if (on(player, ISBLIND))
                    669:        return;
                    670:     for (x = hero.x - 1; x <= hero.x + 1; x++)
                    671:        for (y = hero.y - 1; y <= hero.y + 1; y++)
                    672:        {
                    673:            if (y==hero.y && x==hero.x)
                    674:                continue;
                    675:
                    676:            /* Mch and ch will be the same unless there is a monster here */
                    677:            mch = CCHAR( winat(y, x) );
                    678:            ch = CCHAR( mvwinch(stdscr, y, x) );
                    679:            sch = CCHAR( mvwinch(cw, y, x) );   /* What's on the screen */
                    680:
                    681:            if (door_chime == FALSE && isatrap(ch)) {
                    682:                    register struct trap *tp;
                    683:
                    684:                    /* Is there a monster on the trap? */
                    685:                    if (mch != ch && (item = find_mons(y, x)) != NULL) {
                    686:                        mp = THINGPTR(item);
                    687:                        if (sch == mch) sch = mp->t_oldch;
                    688:                    }
                    689:                    else mp = NULL;
                    690:
                    691:                    /*
                    692:                     * is this one found already?
                    693:                     */
                    694:                    if (isatrap(sch))
                    695:                        continue;       /* give him chance for other traps */
                    696:                    tp = trap_at(y, x);
                    697:                    /*
                    698:                     * if the thief set it then don't display it.
                    699:                     * if its not a thief he has 50/50 shot
                    700:                     */
                    701:                    if((tp->tr_flags&ISTHIEFSET) || (!is_thief && rnd(100)>50))
                    702:                        continue;       /* give him chance for other traps */
                    703:                    tp->tr_flags |= ISFOUND;
                    704:
                    705:                    /* Let's update the screen */
                    706:                    if (mp != NULL && mvwinch(cw, y, x) == mch)
                    707:                        mp->t_oldch = ch; /* Will change when monst moves */
                    708:                    else mvwaddch(cw, y, x, ch);
                    709:
                    710:                    count = 0;
                    711:                    running = FALSE;
                    712:
                    713:                    /* Stop what we were doing */
                    714:                    player.t_no_move = movement(&player);
                    715:                    player.t_action = A_NIL;
                    716:                    player.t_using = NULL;
                    717:
                    718:                    if (fight_flush) md_flushinp();
                    719:                    msg(tr_name(tp->tr_type));
                    720:            }
                    721:            else if (ch == SECRETDOOR) {
                    722:                if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) {
                    723:                    struct room *rp;
                    724:                    coord cp;
                    725:
                    726:                    /* Is there a monster on the door? */
                    727:                    if (mch != ch && (item = find_mons(y, x)) != NULL) {
                    728:                        mp = THINGPTR(item);
                    729:
                    730:                        /* Screen will change when monster moves */
                    731:                        if (sch == mch) mp->t_oldch = ch;
                    732:                    }
                    733:                    mvaddch(y, x, DOOR);
                    734:                    count = 0;
                    735:                    /*
                    736:                     * if its the entrance to a treasure room, wake it up
                    737:                     */
                    738:                    cp.y = y;
                    739:                    cp.x = x;
                    740:                    rp = roomin(&cp);
                    741:                    if (rp->r_flags & ISTREAS)
                    742:                        wake_room(rp);
                    743:
                    744:                    /* Make sure we don't shoot into the room */
                    745:                    if (door_chime == FALSE) {
                    746:                        count = 0;
                    747:                        running = FALSE;
                    748:
                    749:                        /* Stop what we were doing */
                    750:                        player.t_no_move = movement(&player);
                    751:                        player.t_action = A_NIL;
                    752:                        player.t_using = NULL;
                    753:                    }
                    754:                }
                    755:            }
                    756:        }
                    757: }
                    758:
                    759:
                    760: /*
                    761:  * help:
                    762:  *     Give single character help, or the whole mess if he wants it
                    763:  */
                    764:
                    765: void
                    766: help(void)
                    767: {
                    768:     register struct h_list *strp = helpstr;
                    769: #ifdef WIZARD
                    770:     struct h_list *wizp = wiz_help;
                    771: #endif
                    772:     register char helpch;
                    773:     register int cnt;
                    774:
                    775:     msg("Character you want help for (* for all): ");
                    776:     helpch = readchar();
                    777:     mpos = 0;
                    778:     /*
                    779:      * If its not a *, print the right help string
                    780:      * or an error if he typed a funny character.
                    781:      */
                    782:     if (helpch != '*') {
                    783:        wmove(msgw, 0, 0);
                    784:        while (strp->h_ch) {
                    785:            if (strp->h_ch == helpch) {
                    786:                msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
                    787:                return;
                    788:            }
                    789:            strp++;
                    790:        }
                    791: #ifdef WIZARD
                    792:        if (wizard) {
                    793:            while (wizp->h_ch) {
                    794:                if (wizp->h_ch == helpch) {
                    795:                    msg("%s%s", unctrl(wizp->h_ch), wizp->h_desc);
                    796:                    return;
                    797:                }
                    798:                wizp++;
                    799:            }
                    800:        }
                    801: #endif
                    802:
                    803:        msg("Unknown character '%s'", unctrl(helpch));
                    804:        return;
                    805:     }
                    806:     /*
                    807:      * Here we print help for everything.
                    808:      * Then wait before we return to command mode
                    809:      */
                    810:     wclear(hw);
                    811:     cnt = 0;
                    812:     while (strp->h_ch) {
                    813:        mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
                    814:        waddstr(hw, strp->h_desc);
                    815:        strp++;
                    816:        if (++cnt >= 46 && strp->h_ch) {
                    817:            wmove(hw, lines-1, 0);
                    818:            wprintw(hw, morestr);
                    819:            draw(hw);
                    820:            wait_for(' ');
                    821:            wclear(hw);
                    822:            cnt = 0;
                    823:        }
                    824:     }
                    825: #ifdef WIZARD
                    826:     if (wizard) {
                    827:        while (wizp->h_ch) {
                    828:            mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(wizp->h_ch));
                    829:            waddstr(hw, wizp->h_desc);
                    830:            wizp++;
                    831:            if (++cnt >= 46 && wizp->h_ch) {
                    832:                wmove(hw, lines-1, 0);
                    833:                wprintw(hw, morestr);
                    834:                draw(hw);
                    835:                wait_for(' ');
                    836:                wclear(hw);
                    837:                cnt = 0;
                    838:            }
                    839:        }
                    840:     }
                    841: #endif
                    842:     wmove(hw, lines-1, 0);
                    843:     wprintw(hw, spacemsg);
                    844:     draw(hw);
                    845:     wait_for(' ');
                    846:     wclear(hw);
                    847:     draw(hw);
                    848:     wmove(cw, 0, 0);
                    849:     wclrtoeol(cw);
                    850:     status(FALSE);
                    851:     touchwin(cw);
                    852: }
                    853: /*
                    854:  * identify:
                    855:  *     Tell the player what a certain thing is.
                    856:  */
                    857:
                    858: void
                    859: identify(char ch)
                    860: {
                    861:     register char *str;
                    862:
                    863:     if (ch == 0) {
                    864:        msg("What do you want identified? ");
                    865:        ch = readchar();
                    866:        mpos = 0;
                    867:        if (ch == ESCAPE)
                    868:        {
                    869:            msg("");
                    870:            return;
                    871:        }
                    872:     }
                    873:     if (isalpha(ch))
                    874:        str = monsters[id_monst(ch)].m_name;
                    875:     else switch(ch)
                    876:     {
                    877:        case '|':
                    878:        case '-':
                    879:            str = (levtype == OUTSIDE) ? "boundary of sector"
                    880:                                       : "wall of a room";
                    881:        when GOLD:      str = "gold";
                    882:        when STAIRS :   str = (levtype == OUTSIDE) ? "entrance to a dungeon"
                    883:                                                   : "passage leading down";
                    884:        when DOOR:      str = "door";
                    885:        when FLOOR:     str = (levtype == OUTSIDE) ? "meadow" : "room floor";
                    886:        when VPLAYER:   str = "the hero of the game ---> you";
                    887:        when IPLAYER:   str = "you (but invisible)";
                    888:        when PASSAGE:   str = "passage";
                    889:        when POST:      str = "trading post";
                    890:        when POOL:      str = (levtype == OUTSIDE) ? "lake"
                    891:                                                   : "a shimmering pool";
                    892:        when TRAPDOOR:  str = "trapdoor";
                    893:        when ARROWTRAP: str = "arrow trap";
                    894:        when SLEEPTRAP: str = "sleeping gas trap";
                    895:        when BEARTRAP:  str = "bear trap";
                    896:        when TELTRAP:   str = "teleport trap";
                    897:        when DARTTRAP:  str = "dart trap";
                    898:        when MAZETRAP:  str = "entrance to a maze";
                    899:        when FOREST:    str = "forest";
                    900:        when POTION:    str = "potion";
                    901:        when SCROLL:    str = "scroll";
                    902:        when FOOD:      str = "food";
                    903:        when WEAPON:    str = "weapon";
                    904:        when ' ' :      str = "solid rock";
                    905:        when ARMOR:     str = "armor";
                    906:        when MM:        str = "miscellaneous magic";
                    907:        when RING:      str = "ring";
                    908:        when STICK:     str = "wand or staff";
                    909:        when SECRETDOOR:str = "secret door";
                    910:        when RELIC:     str = "artifact";
                    911:        otherwise:      str = "unknown character";
                    912:     }
                    913:     msg("'%s' : %s", unctrl(ch), str);
                    914: }
                    915:
                    916: /*
                    917:  * d_level:
                    918:  *     He wants to go down a level
                    919:  */
                    920:
                    921: void
                    922: d_level()
                    923: {
                    924:     bool no_phase=FALSE;
                    925:     char position = CCHAR( winat(hero.y, hero.x) );
                    926:
                    927:
                    928:     /* If we are on a trading post, go to a trading post level. */
                    929:     if (position == POST) {
                    930:        new_level(POSTLEV);
                    931:        return;
                    932:     }
                    933:
                    934:     /* If we are at a top-level trading post, we probably can't go down */
                    935:     if (levtype == POSTLEV && level == 0 && position != STAIRS) {
                    936:        msg("I see no way down.");
                    937:        return;
                    938:     }
                    939:
                    940:     if (winat(hero.y, hero.x) != STAIRS) {
                    941:        if (off(player, CANINWALL) ||   /* Must use stairs if can't phase */
                    942:            (levtype == OUTSIDE && rnd(100) < 90)) {
                    943:            msg("I see no way down.");
                    944:            return;
                    945:        }
                    946:
                    947:        /* Is there any dungeon left below? */
                    948:        if (level >= nfloors) {
                    949:            msg("There is only solid rock below.");
                    950:            return;
                    951:        }
                    952:
                    953:        extinguish(unphase);    /* Using phase to go down gets rid of it */
                    954:        no_phase = TRUE;
                    955:     }
                    956:
                    957:     /* Is this the bottom? */
                    958:     if (level >= nfloors) {
                    959:        msg("The stairway only goes up.");
                    960:        return;
                    961:     }
                    962:
                    963:     level++;
                    964:     new_level(NORMLEV);
                    965:     if (no_phase) unphase();
                    966: }
                    967:
                    968: /*
                    969:  * u_level:
                    970:  *     He wants to go up a level
                    971:  */
                    972:
                    973: void
                    974: u_level(void)
                    975: {
                    976:     bool no_phase = FALSE;
                    977:     register struct linked_list *item;
                    978:     struct thing *tp;
                    979:     struct object *obj;
                    980:
                    981:     if (winat(hero.y, hero.x) != STAIRS) {
                    982:        if (off(player, CANINWALL)) {   /* Must use stairs if can't phase */
                    983:            msg("I see no way up.");
                    984:            return;
                    985:        }
                    986:
                    987:        extinguish(unphase);
                    988:        no_phase = TRUE;
                    989:     }
                    990:
                    991:     if (level == 0) {
                    992:        msg("The stairway only goes down.");
                    993:        return;
                    994:     }
                    995:
                    996:     /*
                    997:      * does he have the item he was quested to get?
                    998:      */
                    999:     if (level == 1) {
                   1000:        for (item = pack; item != NULL; item = next(item)) {
                   1001:            obj = OBJPTR(item);
                   1002:            if (obj->o_type == RELIC && obj->o_which == quest_item)
                   1003:                total_winner();
                   1004:        }
                   1005:     }
                   1006:     /*
                   1007:      * check to see if he trapped a UNIQUE, If he did then put it back
                   1008:      * in the monster table for next time
                   1009:      */
                   1010:     for (item = tlist; item != NULL; item = next(item)) {
                   1011:        tp = THINGPTR(item);
                   1012:        if (on(*tp, ISUNIQUE))
                   1013:            monsters[tp->t_index].m_normal = TRUE;
                   1014:     }
                   1015:     t_free_list(tlist);        /* Monsters that fell below are long gone! */
                   1016:
                   1017:     if (levtype != POSTLEV) level--;
                   1018:     if (level > 0) new_level(NORMLEV);
                   1019:     else {
                   1020:        level = -1;     /* Indicate that we are new to the outside */
                   1021:        new_level(OUTSIDE);     /* Leaving the dungeon */
                   1022:        msg("You emerge into the %s", daytime ? "light" : "night");
                   1023:     }
                   1024:
                   1025:     if (no_phase) unphase();
                   1026: }
                   1027:
                   1028: /*
                   1029:  * Let him escape for a while
                   1030:  */
                   1031:
                   1032: void
                   1033: shell(void)
                   1034: {
                   1035:     register char *sh;
                   1036:
                   1037:     /*
                   1038:      * Set the terminal back to original mode
                   1039:      */
                   1040:     sh = getenv("SHELL");
                   1041:     wclear(hw);
                   1042:     wmove(hw, lines-1, 0);
                   1043:     draw(hw);
                   1044:     endwin();
                   1045:     in_shell = TRUE;
                   1046:     fflush(stdout);
                   1047:     /*
                   1048:      * Fork and do a shell
                   1049:      */
                   1050:
                   1051:     md_shellescape();
                   1052:
                   1053:        printf(retstr);
                   1054:        noecho();
                   1055:        raw();
                   1056:        keypad(cw,1);
                   1057:        keypad(msgw,1);
                   1058:        in_shell = FALSE;
                   1059:        wait_for('\n');
                   1060:        clearok(cw, TRUE);
                   1061:        touchwin(cw);
                   1062: }
                   1063:
                   1064: /*
                   1065:  * see what we want to name -- an item or a monster.
                   1066:  */
                   1067: void
                   1068: nameit(void)
                   1069: {
                   1070:     char answer;
                   1071:
                   1072:     msg("Name monster or item (m or i)? ");
                   1073:     answer = readchar();
                   1074:     mpos = 0;
                   1075:
                   1076:     while (answer != 'm' && answer != 'i' && answer != ESCAPE) {
                   1077:        mpos = 0;
                   1078:        msg("Please specify m or i, for monster or item - ");
                   1079:        answer = readchar();
                   1080:     }
                   1081:
                   1082:     switch (answer) {
                   1083:        case 'm': namemonst();
                   1084:        when 'i': nameitem(NULL, FALSE);
                   1085:     }
                   1086: }
                   1087:
                   1088: /*
                   1089:  * allow a user to call a potion, scroll, or ring something
                   1090:  */
                   1091: void
                   1092: nameitem(struct linked_list *item, bool mark)
                   1093: {
                   1094:     register struct object *obj;
                   1095:     register char **guess = NULL, *elsewise = NULL;
                   1096:     register bool *know;
                   1097:
                   1098:     if (item == NULL) {
                   1099:        if (mark) item = get_item(pack, "mark", ALL, FALSE, FALSE);
                   1100:        else      item = get_item(pack, "name", CALLABLE, FALSE, FALSE);
                   1101:        if (item == NULL) return;
                   1102:     }
                   1103:     /*
                   1104:      * Make certain that it is somethings that we want to wear
                   1105:      */
                   1106:     obj = OBJPTR(item);
                   1107:     switch (obj->o_type)
                   1108:     {
                   1109:        case RING:
                   1110:            guess = r_guess;
                   1111:            know = r_know;
                   1112:            elsewise = (r_guess[obj->o_which] != NULL ?
                   1113:                        r_guess[obj->o_which] : r_stones[obj->o_which]);
                   1114:        when POTION:
                   1115:            guess = p_guess;
                   1116:            know = p_know;
                   1117:            elsewise = (p_guess[obj->o_which] != NULL ?
                   1118:                        p_guess[obj->o_which] : p_colors[obj->o_which]);
                   1119:        when SCROLL:
                   1120:            guess = s_guess;
                   1121:            know = s_know;
                   1122:            elsewise = (s_guess[obj->o_which] != NULL ?
                   1123:                        s_guess[obj->o_which] : s_names[obj->o_which]);
                   1124:        when STICK:
                   1125:            guess = ws_guess;
                   1126:            know = ws_know;
                   1127:            elsewise = (ws_guess[obj->o_which] != NULL ?
                   1128:                        ws_guess[obj->o_which] : ws_made[obj->o_which]);
                   1129:        when MM:
                   1130:            guess = m_guess;
                   1131:            know = m_know;
                   1132:            elsewise = (m_guess[obj->o_which] != NULL ?
                   1133:                        m_guess[obj->o_which] : "nothing");
                   1134:        otherwise:
                   1135:            if (!mark) {
                   1136:                msg("You can't call that anything.");
                   1137:                return;
                   1138:            }
                   1139:            else know = (bool *) 0;
                   1140:     }
                   1141:     if ((obj->o_flags & ISPOST)        || (know && know[obj->o_which]) && !mark) {
                   1142:        msg("That has already been identified.");
                   1143:        return;
                   1144:     }
                   1145:     if (mark) {
                   1146:        if (obj->o_mark[0]) {
                   1147:            addmsg(terse ? "M" : "Was m");
                   1148:            msg("arked \"%s\"", obj->o_mark);
                   1149:        }
                   1150:        msg(terse ? "Mark it: " : "What do you want to mark it? ");
                   1151:        prbuf[0] = '\0';
                   1152:     }
                   1153:     else {
                   1154:        if (elsewise) {
                   1155:            addmsg(terse ? "N" : "Was n");
                   1156:            msg("amed \"%s\"", elsewise);
                   1157:            strcpy(prbuf, elsewise);
                   1158:        }
                   1159:        else prbuf[0] = '\0';
                   1160:        msg(terse ? "Name it: " : "What do you want to name it? ");
                   1161:     }
                   1162:     if (get_str(prbuf, msgw) == NORM) {
                   1163:        if (mark) {
                   1164:            strncpy(obj->o_mark, prbuf, MARKLEN-1);
                   1165:            obj->o_mark[MARKLEN-1] = '\0';
                   1166:        }
                   1167:        else if (prbuf[0] != '\0') {
                   1168:            if (guess[obj->o_which] != NULL)
                   1169:                free(guess[obj->o_which]);
                   1170:            guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1);
                   1171:            strcpy(guess[obj->o_which], prbuf);
                   1172:        }
                   1173:     }
                   1174: }
                   1175:
                   1176: /* Name a monster */
                   1177:
                   1178: void
                   1179: namemonst(void)
                   1180: {
                   1181:     register struct thing *tp;
                   1182:     struct linked_list *item;
                   1183:     coord c;
                   1184:
                   1185:     /* Find the monster */
                   1186:     msg("Choose the monster (* for help)");
                   1187:     c = get_coordinates();
                   1188:
                   1189:     /* Make sure we can see it and that it is a monster. */
                   1190:     mpos = 0;
                   1191:     if (!cansee(c.y, c.x)) {
                   1192:        msg("You can't see what is there.");
                   1193:        return;
                   1194:     }
                   1195:
                   1196:     if (isalpha(mvwinch(cw, c.y, c.x))) {
                   1197:        item = find_mons(c.y, c.x);
                   1198:        if (item != NULL) {
                   1199:            tp = THINGPTR(item);
                   1200:            if (tp->t_name == NULL)
                   1201:                strcpy(prbuf, monsters[tp->t_index].m_name);
                   1202:            else
                   1203:                strcpy(prbuf, tp->t_name);
                   1204:
                   1205:            addmsg(terse ? "N" : "Was n");
                   1206:            msg("amed \"%s\"", prbuf);
                   1207:            msg(terse ? "Name it: " : "What do you want to name it? ");
                   1208:
                   1209:            if (get_str(prbuf, msgw) == NORM) {
                   1210:                if (prbuf[0] != '\0') {
                   1211:                    if (tp->t_name != NULL)
                   1212:                        free(tp->t_name);
                   1213:                    tp->t_name = new((unsigned int) strlen(prbuf) + 1);
                   1214:                    strcpy(tp->t_name, prbuf);
                   1215:                }
                   1216:            }
                   1217:            return;
                   1218:        }
                   1219:     }
                   1220:
                   1221:     msg("There is no monster there to name.");
                   1222: }
                   1223:
                   1224: void
                   1225: count_gold(void)
                   1226: {
                   1227:        if (player.t_action != C_COUNT) {
                   1228:            msg("You take a break to count your money...");
                   1229:            player.t_using = NULL;
                   1230:            player.t_action = C_COUNT;  /* We are counting */
                   1231:            player.t_no_move = (purse/300 + 1) * movement(&player);
                   1232:            return;
                   1233:        }
                   1234:        if (purse > 100)
                   1235:                msg("You think you have about %d gold pieces.", purse);
                   1236:        else
                   1237:                msg("You have %d gold pieces.", purse);
                   1238:        player.t_action = A_NIL;
                   1239: }

CVSweb