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

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

1.1       rubenllo    1: /*
                      2:     command.c  -  Read and execute the user commands
                      3:
                      4:     UltraRogue: The Ultimate Adventure in the Dungeons of Doom
                      5:     Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
                     10:     All rights reserved.
                     11:
                     12:     Based on "Rogue: Exploring the Dungeons of Doom"
                     13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     14:     All rights reserved.
                     15:
                     16:     See the file LICENSE.TXT for full copyright and licensing information.
                     17: */
                     18:
                     19: #include <string.h>
                     20: #include <stdlib.h>
                     21: #include <ctype.h>
                     22: #include "rogue.h"
                     23:
                     24: /*
                     25:     command()
                     26:         Process the user commands
                     27: */
                     28:
                     29: void
                     30: command(void)
                     31: {
                     32:     static char repcommand;     /* Command to repeat if we are repeating */
                     33:     static int fight_to_death; /* Flags if we are fighting to death     */
                     34:     static coord dir;          /* Last direction specified              */
                     35:
                     36:     object  *obj;
                     37:     char     ch;
                     38:     int      ntimes = 1; /* Number of player moves */
                     39:     coord    nullcoord;
                     40:
                     41:     nullcoord.x = nullcoord.y = 0;
                     42:
                     43:     if (on(player, CANFLY) && rnd(2))
                     44:         ntimes++;
                     45:
                     46:     if (on(player, ISHASTE))
                     47:         ntimes++;
                     48:
                     49:     if (fighting && att_bonus())
                     50:         ntimes *= 2;
                     51:
                     52:     if (on(player, ISSLOW))
                     53:     {
                     54:         if (player.t_turn != TRUE)
                     55:             ntimes--;
                     56:
                     57:         player.t_turn ^= TRUE;
                     58:     }
                     59:
                     60:     if (ntimes == 0)
                     61:         return;
                     62:
                     63:     while (ntimes--)
                     64:     {
                     65:         moving = FALSE;
                     66:
                     67:         /* If player is infested, take off a hit point */
                     68:
                     69:         if (on(player, HASINFEST) && !is_wearing(R_HEALTH))
                     70:         {
                     71:             if ((pstats.s_hpt -= infest_dam) <= 0)
                     72:             {
                     73:                 death(D_INFESTATION);
                     74:                 return;
                     75:             }
                     76:         }
                     77:
                     78:         look(after);
                     79:
                     80:         if (!running)
                     81:             door_stop = FALSE;
                     82:
                     83:         status(FALSE);
                     84:         wmove(cw, hero.y, hero.x);
                     85:
                     86:         if (!((running || count) && jump))
                     87:             wrefresh(cw);   /* Draw screen */
                     88:
                     89:         take = 0;
                     90:         after = TRUE;
                     91:
                     92:         /*
                     93:          * Read command or continue run
                     94:          */
                     95:
                     96:         if (!no_command)
                     97:         {
                     98:             if (fighting)
                     99:             {
                    100:                 ch = (fight_to_death) ? 'F' : 'f';
                    101:             }
                    102:             else if (running)
                    103:             {
                    104:                 /*
                    105:                  * If in a corridor, if we are at a turn with
                    106:                  * only one way to go, turn that way.
                    107:                  */
                    108:
                    109:                 if ((winat(hero.y, hero.x) == PASSAGE) && off(player, ISHUH) &&
                    110:                     (off(player, ISBLIND)))
                    111:                     switch (runch)
                    112:                     {
                    113:                         case 'h': corr_move(0, -1); break;
                    114:                         case 'j': corr_move(1, 0); break;
                    115:                         case 'k': corr_move(-1, 0); break;
                    116:                         case 'l': corr_move(0, 1); break;
                    117:                     }
                    118:
                    119:                 ch = runch;
                    120:             }
                    121:             else if (count)
                    122:                 ch = repcommand;
                    123:             else
                    124:             {
                    125:                 ch = readchar();
                    126:
                    127:                 if (mpos != 0 && !running)
                    128:                     msg("");    /* Erase message if its there */
                    129:             }
                    130:         }
                    131:         else
                    132:         {
                    133:             ch = '.';
                    134:             fighting = moving = FALSE;
                    135:         }
                    136:
                    137:         if (no_command)
                    138:         {
                    139:             if (--no_command == 0)
                    140:                 msg("You can move again.");
                    141:         }
                    142:         else
                    143:         {
                    144:
                    145:             /*
                    146:              * check for prefixes
                    147:              */
                    148:
                    149:             if (isdigit(ch))
                    150:             {
                    151:                 count = 0;
                    152:                 while (isdigit(ch))
                    153:                 {
                    154:                     count = count * 10 + (ch - '0');
                    155:                     ch = readcharw(cw);
                    156:                 }
                    157:                 repcommand = ch;
                    158:
                    159:                 /*
                    160:                  * Preserve count for commands which can be
                    161:                  * repeated.
                    162:                  */
                    163:
                    164:                 switch(ch)
                    165:                 {
                    166:                     case 'h':
                    167:                     case 'j':
                    168:                     case 'k':
                    169:                     case 'l':
                    170:                     case 'y':
                    171:                     case 'u':
                    172:                     case 'b':
                    173:                     case 'n':
                    174:                     case 'H':
                    175:                     case 'J':
                    176:                     case 'K':
                    177:                     case 'L':
                    178:                     case 'Y':
                    179:                     case 'U':
                    180:                     case 'B':
                    181:                     case 'N':
                    182:                     case 'q':
                    183:                     case 'r':
                    184:                     case 's':
                    185:                     case 'm':
                    186:                     case 't':
                    187:                     case 'C':
                    188:                     case 'I':
                    189:                     case '.':
                    190:                     case 'z':
                    191:                     case 'p':
                    192:                         break;
                    193:                     default:
                    194:                         count = 0;
                    195:                 }
                    196:             }
                    197:
                    198:             /* Save current direction */
                    199:
                    200:             if (!running)   /* If running, it is already saved */
                    201:                 switch (ch)
                    202:                 {
                    203:                     case 'h':
                    204:                     case 'j':
                    205:                     case 'k':
                    206:                     case 'l':
                    207:                     case 'y':
                    208:                     case 'u':
                    209:                     case 'b':
                    210:                     case 'n':
                    211:                         runch = ch;
                    212:                         break;
                    213:                     case 'H':
                    214:                     case 'J':
                    215:                     case 'K':
                    216:                     case 'L':
                    217:                     case 'Y':
                    218:                     case 'U':
                    219:                     case 'B':
                    220:                     case 'N':
                    221:                         runch = (char) tolower(ch);
                    222:                         break;
                    223:                 }
                    224:
                    225:             /*
                    226:              * execute a command
                    227:              */
                    228:
                    229:             if (count && !running)
                    230:                 count--;
                    231:
                    232:             switch(ch)
                    233:             {
                    234:                 /*
                    235:                  * Movement and combat commands
                    236:                  */
                    237:
                    238:                 case 'h': do_move(0,-1); break;
                    239:                 case 'j': do_move(1, 0);  break;
                    240:                 case 'k': do_move(-1, 0); break;
                    241:                 case 'l': do_move(0, 1); break;
                    242:                 case 'y': do_move(-1, -1); break;
                    243:                 case 'u': do_move(-1, 1); break;
                    244:                 case 'b': do_move(1, -1); break;
                    245:                 case 'n': do_move(1, 1); break;
                    246:                 case 'H': do_run('h'); break;
                    247:                 case 'J': do_run('j'); break;
                    248:                 case 'K': do_run('k'); break;
                    249:                 case 'L': do_run('l'); break;
                    250:                 case 'Y': do_run('y'); break;
                    251:                 case 'U': do_run('u'); break;
                    252:                 case 'B': do_run('b'); break;
                    253:                 case 'N': do_run('n'); break;
                    254:                 case 'm':
                    255:                     moving = TRUE;
                    256:                     if (!get_dir())
                    257:                     {
                    258:                         after = FALSE;
                    259:                         break;
                    260:                     }
                    261:                     do_move(delta.y, delta.x);
                    262:                     break;
                    263:                 case 'F':
                    264:                 case 'f':
                    265:                     fight_to_death = (ch == 'F');
                    266:                     if (!fighting)
                    267:                     {
                    268:                         if (get_dir())
                    269:                         {
                    270:                             dir = delta;
                    271:                             beast = NULL;
                    272:                         }
                    273:                         else
                    274:                         {
                    275:                             after = FALSE;
                    276:                             break;
                    277:                         }
                    278:                     }
                    279:                     do_fight(dir, (ch == 'F') ? TRUE : FALSE);
                    280:                     break;
                    281:                 case 't':
                    282:                     if (get_dir())
                    283:                         missile(delta.y, delta.x, get_item("throw", 0),
                    284:                             &player);
                    285:                     else
                    286:                         after = FALSE;
                    287:
                    288:                     /*
                    289:                      * Informational commands - Do not do
                    290:                      * after daemons
                    291:                      */
                    292:                      break;
                    293:
                    294:                 case 0x7f:            /* sometime generated by */
                    295:                                       /* suspend/foreground    */
                    296:                 case ESCAPE:
                    297:                 case ' ':
                    298:                     after = FALSE;    /* do nothing */
                    299:                     break;
                    300:                 case 'Q':
                    301:                     after = FALSE;
                    302:                     quit();
                    303:                     break;
                    304:                 case 'i':
                    305:                     after = FALSE;
                    306:                     inventory(pack, '*');
                    307:                     break;
                    308:                 case 'I':
                    309:                     after = FALSE;
                    310:                     inventory(pack, 0);
                    311:                     break;
                    312:                 case '~':
                    313:                     after = FALSE;
                    314:                     next_exp_level(MESSAGE);
                    315:                     break;
                    316:                 case '>':
                    317:                     after = FALSE;
                    318:                     d_level();
                    319:                     break;
                    320:                 case '<':
                    321:                     after = FALSE;
                    322:                     u_level();
                    323:                     break;
                    324:                 case '?':
                    325:                     after = FALSE;
                    326:                     help();
                    327:                     break;
                    328:                 case '/':
                    329:                     after = FALSE;
                    330:                     identify();
                    331:                     break;
                    332:                 case 'v':
                    333:                     after = FALSE;
                    334:                     msg("UltraRogue Version %s.", release);
                    335:                     break;
                    336:                 case 'o':
                    337:                     after = FALSE;
                    338:                     option();
                    339:                     strcpy(fd_data[1].mi_name, fruit);
                    340:                     break;
                    341:                 case 12:    /* ctrl-l */
                    342:                 case 18:    /* ctrl-r */
                    343:                     after = FALSE;
                    344:                     clearok(cw, TRUE);
                    345:                                        wrefresh(cw);
                    346:                     break;
                    347:                 case 16: /* ctrl-p */
                    348:                 {
                    349:                     int decrement = FALSE;
                    350:                     after = FALSE;
                    351:
                    352:                     if (mpos == 0)
                    353:                         decrement = TRUE;
                    354:
                    355:                     msg_index = (msg_index + 9) % 10;
                    356:                     msg(msgbuf[msg_index]);
                    357:                     if (decrement)
                    358:                         msg_index = (msg_index + 9) % 10;
                    359:                 }
                    360:                 break;
                    361:
                    362:                 case 'S':
                    363:                     after = FALSE;
                    364:                     if (save_game())
                    365:                     {
                    366:                         wclear(cw);
                    367:                         wrefresh(cw);
                    368:                         endwin();
                    369:                        printf("\n");
                    370:                         exit(0);
                    371:                     }
                    372:                     break;
                    373:
                    374:                 /*
                    375:                  * Other misc commands
                    376:                  */
                    377:
                    378:                 case '.':   break;   /* rest */
                    379:                 case ',':   add_pack(NULL, NOMESSAGE); break;
                    380:                 case 'q': quaff(&player, -1, ISNORMAL); break;
                    381:                 case 'r': read_scroll(&player, -1, ISNORMAL); break;
                    382:                 case 'd': drop(NULL); break;
                    383:                 case '^': set_trap(&player, hero.y, hero.x); break;
                    384:                 case 'c': incant(&player, nullcoord); break;
                    385:                 case 'D': dip_it(); break;
                    386:                 case 'e': eat(); break;
                    387:                 case '=': listen(); break;
                    388:                 case 'A': apply(); break;
                    389:                 case 'w': wield(); break;
                    390:                 case 'W': wear(); break;
                    391:                 case 'T': take_off(); break;
                    392:                 case 'P': ring_on(); break;
                    393:                 case 'R': ring_off(); break;
                    394:                 case 'p': prayer(); break;
                    395:                 case 'C': call(FALSE); break;
                    396:                 case 'M': call(TRUE); break;
                    397:                 case 's': search(FALSE); break;
                    398:
                    399:                 /*
                    400:                  * Directional commands - get_dir sets delta
                    401:                  */
                    402:                 case 20:    /* ctrl-t */
                    403:                     if (get_dir())
                    404:                         steal();
                    405:                     else
                    406:                         after = FALSE;
                    407:                     break;
                    408:
                    409:                 case 'z':
                    410:                     if (get_dir())
                    411:                         do_zap(&player, -1, ISNORMAL);
                    412:                     else
                    413:                         after = FALSE;
                    414:                     break;
                    415:
                    416:                 case 'a':
                    417:                     if (get_dir())
                    418:                         affect();
                    419:                     else
                    420:                         after = FALSE;
                    421:                     touchwin(cw);
                    422:                     break;
                    423:
                    424:                 /*
                    425:                  * wizard commands
                    426:                  */
                    427:
                    428: #ifdef WIZARD
                    429:                 case 0x17:    /* ctrl-w */
                    430:                     after = FALSE;
                    431:
                    432:                     if (!wizard)
                    433:                     {
                    434:                         if (!canwizard)
                    435:                         {
                    436:                             msg("Illegal command '^W'.");
                    437:                             break;
                    438:                         }
                    439:
                    440:                         if (passwd())
                    441:                         {
                    442:                             msg("Welcome, oh mighty wizard.");
                    443:                             wizard = waswizard = TRUE;
                    444:                         }
                    445:                         else
                    446:                         {
                    447:                             msg("Incorrect password.");
                    448:                             break;
                    449:                         }
                    450:                     }
                    451:
                    452:                     msg("Wizard command: ");
                    453:                     mpos = 0;
                    454:                     ch = readchar();
                    455:
                    456:                     switch (ch)
                    457:                     {
                    458:                         case 'v':
                    459:                             wiz_verbose = !wiz_verbose;
                    460:                             break;
                    461:
                    462:                         case 'e':
                    463:                             wizard = FALSE;
                    464:                             msg("Not wizard any more.");
                    465:                             break;
                    466:
                    467:                         case 's': activity(); break;
                    468:                         case 't': teleport(); break;
                    469:                         case 'm': overlay(mw, cw); break;
                    470:                         case 'f': overlay(stdscr, cw); break;
                    471:                         case 'i': inventory(lvl_obj, 0); break;
                    472:                         case 'c': buy_it('\0', ISNORMAL); break;
                    473:                         case 'I': whatis(NULL); break;
                    474:                         case 'F':
                    475:                              msg("food left: %d\tfood level: %d",
                    476:                                   food_left,foodlev);
                    477:                              break;
                    478:                         case 'M':
                    479:                             creat_mons(&player, get_monster_number("create"),
                    480:                                        MESSAGE);
                    481:                             break;
                    482:
                    483:                         case 'r':
                    484:                             msg("rnd(4)%d, rnd(40)%d, rnd(100)%d",
                    485:                                  rnd(4), rnd(40), rnd(100));
                    486:                             break;
                    487:
                    488:                         case 'C':
                    489:                             obj = get_object(pack, "charge", STICK, NULL);
                    490:
                    491:                             if (obj != NULL)
                    492:                                 obj->o_charges = 10000;
                    493:
                    494:                             break;
                    495:
                    496:                         case 'w':
                    497:                             obj = get_object(pack, "price", 0, NULL);
                    498:
                    499:                             if (obj != NULL)
                    500:                                 msg("Worth %d.", get_worth(obj));
                    501:
                    502:                             break;
                    503:
                    504:                         case 'g':
                    505:                             {
                    506:                                 int tlev;
                    507:
                    508:                                 prbuf[0] = '\0';
                    509:                                 msg("Which level? ");
                    510:
                    511:                                 if (get_string(prbuf, cw) == NORM)
                    512:                                 {
                    513:                                     msg("");
                    514:
                    515:                                     if ((tlev = atoi(prbuf)) < 1)
                    516:                                         msg("Illegal level.");
                    517:                                     else if (tlev > 3000)
                    518:                                     {
                    519:                                         levtype = THRONE;
                    520:                                         level = tlev - 3000;
                    521:                                     }
                    522:                                     else if (tlev > 2000)
                    523:                                     {
                    524:                                         levtype = MAZELEV;
                    525:                                         level = tlev - 2000;
                    526:                                     }
                    527:                                     else if (tlev > 1000)
                    528:                                     {
                    529:                                         levtype = POSTLEV;
                    530:                                         level = tlev - 1000;
                    531:                                     }
                    532:                                     else
                    533:                                     {
                    534:                                         levtype = NORMLEV;
                    535:                                         level = tlev;
                    536:                                     }
                    537:
                    538:                                     new_level(levtype,0);
                    539:                                 }
                    540:                             }
                    541:                             break;
                    542:
                    543:                         case 'o':   make_omnipotent(); break;
                    544:
                    545:                         case ESCAPE: /* Escape */
                    546:                             door_stop = FALSE;
                    547:
                    548:                             count = 0;
                    549:                             after = FALSE;
                    550:                             break;
                    551:
                    552:                         default:
                    553:                             msg("Illegal wizard command '%s', %d.",
                    554:                                 unctrl(ch), ch);
                    555:                             count = 0;
                    556:                             break;
                    557:
                    558:                     }
                    559:
                    560:                 break;
                    561: #endif
                    562:
                    563:                 default:
                    564:                     msg("Illegal command '%s', %d.",
                    565:                         unctrl(ch), ch);
                    566:                     count = 0;
                    567:                     after = FALSE;
                    568:                     break;
                    569:             }
                    570:
                    571:             /*
                    572:              * turn off flags if no longer needed
                    573:              */
                    574:             if (!running)
                    575:                 door_stop = FALSE;
                    576:         }
                    577:
                    578:         /*
                    579:          * If he ran into something to take, let him pick it up.
                    580:          */
                    581:         if (take != 0)
                    582:             if (!moving)
                    583:                 pick_up(take);
                    584:             else
                    585:                 show_floor();
                    586:         if (!running)
                    587:             door_stop = FALSE;
                    588:     } /* end while */
                    589: }
                    590:
                    591:
                    592: void
                    593: do_after_effects(void)
                    594: {
                    595:     int i;
                    596:
                    597:     /* Kick off the rest of the daemons and fuses */
                    598:
                    599:     look(FALSE);
                    600:     do_daemons(AFTER);
                    601:     do_fuses(AFTER);
                    602:
                    603:     /* Special abilities */
                    604:
                    605:     if ((player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN ||
                    606:      player.t_ctype == C_NINJA || player.t_ctype == C_RANGER) &&
                    607:      (rnd(100) < (2 * pstats.s_dext + 5 * pstats.s_lvl)))
                    608:         search(TRUE);
                    609:
                    610:     for (i = 0; i < ring_value(R_SEARCH); i++)
                    611:         search(FALSE);
                    612:
                    613:     if (is_wearing(R_TELEPORT) && rnd(50) < 2)
                    614:     {
                    615:         teleport();
                    616:
                    617:         if (off(player, ISCLEAR))
                    618:         {
                    619:             if (on(player, ISHUH))
                    620:                 lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
                    621:             else
                    622:                 light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
                    623:
                    624:             turn_on(player, ISHUH);
                    625:         }
                    626:         else
                    627:             msg("You feel dizzy for a moment, but it quickly passes.");
                    628:     }
                    629:
                    630:     /* accidents and general clumsiness */
                    631:
                    632:     if (fighting && rnd(50) == 0)
                    633:     {
                    634:         msg("You become tired of this nonsense.");
                    635:         fighting = after = FALSE;
                    636:     }
                    637:
                    638:     if (on(player, ISELECTRIC))
                    639:         electrificate();
                    640:
                    641:     if (!fighting && (no_command == 0) && cur_weapon != NULL
                    642:         && rnd(on(player, STUMBLER) ? 399 : 9999) == 0
                    643:         && rnd(pstats.s_dext) <
                    644:         2 - hitweight() + (on(player, STUMBLER) ? 4 : 0))
                    645:     {
                    646:         msg("You trip and stumble over your weapon.");
                    647:         running = after = FALSE;
                    648:
                    649:         if (rnd(8) == 0 && (pstats.s_hpt -= roll(1, 10)) <= 0)
                    650:         {
                    651:             msg("You break your neck and die.");
                    652:             death(D_FALL);
                    653:             return;
                    654:         }
                    655:         else if (cur_weapon->o_flags & ISPOISON && rnd(4) == 0)
                    656:         {
                    657:             msg("You are cut by your %s!",
                    658:                 inv_name(cur_weapon, LOWERCASE));
                    659:
                    660:             if (player.t_ctype != C_PALADIN
                    661:                 && !(player.t_ctype == C_NINJA &&
                    662:                 pstats.s_lvl > 12)
                    663:                 && !save(VS_POISON))
                    664:             {
                    665:                 if (pstats.s_hpt == 1)
                    666:                 {
                    667:                     msg("You die from the poison in the cut.");
                    668:                     death(D_POISON);
                    669:                     return;
                    670:                 }
                    671:                 else
                    672:                 {
                    673:                     msg("You feel very sick now.");
                    674:                     pstats.s_hpt /= 2;
                    675:                     chg_str(-2, FALSE, FALSE);
                    676:                 }
                    677:             }
                    678:        }
                    679:    }
                    680:
                    681:    /* Time to enforce weapon and armor restrictions */
                    682:    if (rnd(9999) == 0)
                    683:         if (((cur_weapon == NULL) ||
                    684:             (wield_ok(&player, cur_weapon, NOMESSAGE)))
                    685:             && ((cur_armor == NULL) ||
                    686:             (wear_ok(&player, cur_armor, NOMESSAGE))))
                    687:         {
                    688:             switch (player.t_ctype)
                    689:             {
                    690:                 case C_CLERIC:
                    691:                 case C_DRUID:
                    692:                 case C_RANGER:
                    693:                 case C_PALADIN:
                    694:                     if (rnd(luck) != 0)
                    695:                         /* You better have done
                    696:                          * little wrong */
                    697:                         goto bad_cleric;
                    698:
                    699:                     msg("You are enraptured by the renewed "
                    700:                         "power of your god.");
                    701:                     break;
                    702:
                    703:                 case C_MAGICIAN:
                    704:                 case C_ILLUSION:
                    705:                     msg("You become in tune with the universe.");
                    706:                     break;
                    707:
                    708:                 case C_THIEF:
                    709:                 case C_NINJA:
                    710:                 case C_ASSASIN:
                    711:                     msg("You become supernaly sensitive to your "
                    712:                         "surroundings.");
                    713:                     break;
                    714:
                    715:                 case C_FIGHTER:
                    716:                     msg("You catch your second wind.");
                    717:                     break;
                    718:
                    719:                 default:
                    720:                     msg("What a strange type you are!");
                    721:                     break;
                    722:            }
                    723:            pstats.s_hpt = max_stats.s_hpt += rnd(pstats.s_lvl) + 1;
                    724:             pstats.s_power = max_stats.s_power += rnd(pstats.s_lvl) + 1;
                    725:         }
                    726:         else
                    727:         {   /* he blew it - make him pay */
                    728:
                    729:             int death_cause = 0;
                    730:
                    731:             switch (player.t_ctype)
                    732:             {
                    733:                 case C_CLERIC:
                    734:                 case C_DRUID:
                    735:                 case C_RANGER:
                    736:                 case C_PALADIN:
                    737:             bad_cleric:
                    738:                     msg("Your god scourges you for your misdeeds.");
                    739:                     death_cause = D_GODWRATH;
                    740:                     break;
                    741:
                    742:                 case C_MAGICIAN:
                    743:                 case C_ILLUSION:
                    744:                     msg("You short out your manna on the unfamiliar %s.",
                    745:                         (cur_armor != NULL ? "armor" : "weapon"));
                    746:
                    747:                    death_cause = D_SPELLFUMBLE;
                    748:                    break;
                    749:
                    750:                 case C_THIEF:
                    751:                 case C_NINJA:
                    752:                 case C_ASSASIN:
                    753:                     msg("You trip and fall because of the unfamiliar %s.",
                    754:                         (cur_armor != NULL ? "armor" : "weapon"));
                    755:                     death_cause = D_CLUMSY;
                    756:                     break;
                    757:
                    758:                 case C_FIGHTER:
                    759:                     debug("Fighter getting raw deal?");
                    760:                    break;
                    761:
                    762:                 default:
                    763:                     msg("What a strange type you are!");
                    764:                     break;
                    765:             }
                    766:
                    767:             aggravate();
                    768:             pstats.s_power /= 2;
                    769:             pstats.s_hpt /= 2;
                    770:             player.t_no_move++;
                    771:
                    772:             if ((pstats.s_hpt -= rnd(pstats.s_lvl)) <= 0)
                    773:             {
                    774:                 death(death_cause);
                    775:             }
                    776:         }
                    777:
                    778:     if (rnd(500000) == 0)
                    779:     {
                    780:         new_level(THRONE,0);
                    781:         fighting = running = after = FALSE;
                    782:         command();
                    783:     }
                    784: }
                    785:
                    786: void
                    787: make_omnipotent(void)
                    788: {
                    789:     int i;
                    790:     struct linked_list  *item;
                    791:     struct object *obj;
                    792:
                    793:     for (i = 0; i < 20; i++)
                    794:         raise_level();
                    795:
                    796:     max_stats.s_hpt += 1000;
                    797:     max_stats.s_power += 1000;
                    798:     pstats.s_hpt = max_stats.s_hpt;
                    799:     pstats.s_power = max_stats.s_power;
                    800:     max_stats.s_str = pstats.s_str = 25;
                    801:     max_stats.s_intel = pstats.s_intel = 25;
                    802:     max_stats.s_wisdom = pstats.s_wisdom = 25;
                    803:     max_stats.s_dext = pstats.s_dext = 25;
                    804:     max_stats.s_const = pstats.s_const = 25;
                    805:
                    806:     if (cur_weapon == NULL || cur_weapon->o_which != CLAYMORE)
                    807:     {
                    808:         item = spec_item(WEAPON, CLAYMORE, 10, 10);
                    809:         cur_weapon = OBJPTR(item);
                    810:         cur_weapon->o_flags |= ISKNOW;
                    811:         add_pack(item, NOMESSAGE);
                    812:     }
                    813:
                    814:     /* and a kill-o-zap stick */
                    815:
                    816:     item = spec_item(STICK, WS_DISINTEGRATE, 10000, 0);
                    817:     obj = OBJPTR(item);
                    818:     obj->o_flags |= ISKNOW;
                    819:     know_items[TYP_STICK][WS_DISINTEGRATE] = TRUE;
                    820:
                    821:     if (guess_items[TYP_STICK][WS_DISINTEGRATE])
                    822:     {
                    823:         ur_free(guess_items[TYP_STICK][WS_DISINTEGRATE]);
                    824:         guess_items[TYP_STICK][WS_DISINTEGRATE] = NULL;
                    825:     }
                    826:
                    827:     add_pack(item, NOMESSAGE);
                    828:
                    829:     /* and his suit of armor */
                    830:
                    831:     if (cur_armor == NULL ||
                    832:         !(cur_armor->o_which == CRYSTAL_ARMOR ||
                    833:           cur_armor->o_which == MITHRIL))
                    834:     {
                    835:         item = spec_item(ARMOR, CRYSTAL_ARMOR, 15, 0);
                    836:         obj = OBJPTR(item);
                    837:         obj->o_flags |= ISKNOW;
                    838:         obj->o_weight =
                    839:             (int) (armors[CRYSTAL_ARMOR].a_wght * 0.2);
                    840:         cur_armor = obj;
                    841:         add_pack(item, NOMESSAGE);
                    842:     }
                    843:
                    844:     /* and some rings (have to put them on, for now) */
                    845:
                    846:
                    847:     if (!is_wearing(R_SEARCH))
                    848:     {
                    849:         item = spec_item(RING, R_SEARCH, 0, 0);
                    850:         obj = OBJPTR(item);
                    851:         obj->o_flags |= ISKNOW;
                    852:         know_items[TYP_RING][R_SEARCH] = TRUE;
                    853:
                    854:         if (guess_items[TYP_RING][R_SEARCH])
                    855:         {
                    856:             ur_free(guess_items[TYP_RING][R_SEARCH]);
                    857:             guess_items[TYP_RING][R_SEARCH] = NULL;
                    858:         }
                    859:
                    860:         add_pack(item, NOMESSAGE);
                    861:     }
                    862:
                    863:     if (!is_wearing(R_PIETY))
                    864:     {
                    865:         item = spec_item(RING, R_PIETY, 0, 0);
                    866:         obj = OBJPTR(item);
                    867:         obj->o_flags |= ISKNOW;
                    868:         know_items[TYP_RING][R_PIETY] = TRUE;
                    869:
                    870:         if (guess_items[TYP_RING][R_PIETY])
                    871:         {
                    872:             ur_free(guess_items[TYP_RING][R_PIETY]);
                    873:             guess_items[TYP_RING][R_PIETY] = NULL;
                    874:         }
                    875:
                    876:         add_pack(item, NOMESSAGE);
                    877:     }
                    878:
                    879:     item = spec_item(SCROLL, S_ELECTRIFY, 0, 0);
                    880:     obj = OBJPTR(item);
                    881:     obj->o_flags |= ISKNOW;
                    882:     know_items[TYP_SCROLL][S_ELECTRIFY] = TRUE;
                    883:
                    884:     if (guess_items[TYP_SCROLL][S_ELECTRIFY])
                    885:     {
                    886:         ur_free(guess_items[TYP_SCROLL][S_ELECTRIFY]);
                    887:         guess_items[TYP_SCROLL][S_ELECTRIFY] = NULL;
                    888:     }
                    889:
                    890:     add_pack(item, NOMESSAGE);
                    891:
                    892:     /* Spiff him up a bit */
                    893:     quaff(&player, P_SHERO, ISBLESSED);
                    894:     quaff(&player, P_CLEAR, ISBLESSED);
                    895:     quaff(&player, P_FIRERESIST, ISBLESSED);
                    896:     quaff(&player, P_TRUESEE, ISBLESSED);
                    897:     quaff(&player, P_PHASE, ISBLESSED);
                    898:     purse += 50000L;
                    899:     updpack();
                    900: }
                    901:
                    902:
                    903: /*
                    904:     quit()
                    905:         Have player make certain, then exit.
                    906: */
                    907:
                    908: void
                    909: quit_handler(int sig)
                    910: {
                    911:     if (signal(SIGINT, quit_handler) != quit_handler)
                    912:         mpos = 0;
                    913:
                    914:     sig = 0;
                    915:
                    916:     quit();
                    917: }
                    918:
                    919: void
                    920: quit(void)
                    921: {
                    922:     msg("Really quit?");
                    923:
                    924:     wrefresh(cw);
                    925:
                    926:     if (readchar() == 'y')
                    927:     {
                    928:         clear();
                    929:         wclear(cw);
                    930:         wrefresh(cw);
                    931:         move(LINES - 1, 0);
                    932:         wrefresh(stdscr);
                    933:         score(pstats.s_exp, pstats.s_lvl, CHICKEN, 0);
                    934:         byebye();
                    935:     }
                    936:     else
                    937:     {
                    938:         signal(SIGINT, quit_handler);
                    939:         wmove(cw, 0, 0);
                    940:         wclrtoeol(cw);
                    941:         status(FALSE);
                    942:         wrefresh(cw);
                    943:         mpos = 0;
                    944:         count = 0;
                    945:         fighting = running = 0;
                    946:     }
                    947: }
                    948:
                    949: /*
                    950:     search()
                    951:         Player gropes about him to find hidden things.
                    952: */
                    953:
                    954: void
                    955: search(int is_thief)
                    956: {
                    957:     int x, y;
                    958:     char ch;
                    959:
                    960:     /*
                    961:      * Look all around the hero, if there is something hidden there, give
                    962:      * him a chance to find it.  If its found, display it.
                    963:      */
                    964:
                    965:     if (on(player, ISBLIND))
                    966:         return;
                    967:
                    968:     for (x = hero.x - 1; x <= hero.x + 1; x++)
                    969:         for (y = hero.y - 1; y <= hero.y + 1; y++)
                    970:         {
                    971:             ch = winat(y, x);
                    972:
                    973:             if (isatrap(ch))
                    974:             {
                    975:                 static char trname[1024]; /* temp scratch space */
                    976:                 struct trap *tp;
                    977:                 struct room *rp;
                    978:
                    979:                 if (isatrap( mvwinch(cw, y, x)))
                    980:                     continue;
                    981:
                    982:                 tp = trap_at(y, x);
                    983:
                    984:                 if ((tp->tr_flags & ISTHIEFSET) ||
                    985:                     (rnd(100) > 50 && !is_thief))
                    986:                     break;
                    987:
                    988:                 rp = roomin(hero);
                    989:
                    990:                 if (tp->tr_type == FIRETRAP && rp != NULL)
                    991:                 {
                    992:                     rp->r_flags &= ~ISDARK;
                    993:                     light(&hero);
                    994:                 }
                    995:
                    996:                 tp->tr_flags |= ISFOUND;
                    997:                 mvwaddch(cw, y, x, ch);
                    998:                 count = 0;
                    999:                 running = FALSE;
                   1000:                 msg(tr_name(tp->tr_type,trname));
                   1001:             }
                   1002:             else if (ch == SECRETDOOR)
                   1003:             {
                   1004:                 if (rnd(100) < 20 && !is_thief)
                   1005:                 {
                   1006:                     mvaddch(y, x, DOOR);
                   1007:                     count = 0;
                   1008:                 }
                   1009:             }
                   1010:         }
                   1011: }
                   1012:
                   1013: /*
                   1014:     help()
                   1015:         Give single character help, or the whole mess if he wants it
                   1016: */
                   1017:
                   1018: void
                   1019: help(void)
                   1020: {
                   1021:     const struct h_list *strp = helpstr;
                   1022:     char helpch;
                   1023:     int cnt;
                   1024:
                   1025:     msg("Character you want help for (* for all): ");
                   1026:     helpch = readchar();
                   1027:     mpos = 0;
                   1028:
                   1029:     /*
                   1030:      * If its not a *, print the right help string or an error if he
                   1031:      * typed a funny character.
                   1032:      */
                   1033:
                   1034:     if (helpch != '*')
                   1035:     {
                   1036:         wmove(cw, 0, 0);
                   1037:
                   1038:         while (strp->h_ch)
                   1039:         {
                   1040:             if (strp->h_desc == 0)
                   1041:                 if (!wizard)
                   1042:                     break;
                   1043:                 else
                   1044:                 {
                   1045:                     strp++;
                   1046:                     continue;
                   1047:                 }
                   1048:
                   1049:             if (strp->h_ch == helpch)
                   1050:             {
                   1051:                 msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
                   1052:                 break;
                   1053:             }
                   1054:             strp++;
                   1055:         }
                   1056:
                   1057:         if (strp->h_ch != helpch)
                   1058:             msg("Unknown character '%s'.", unctrl(helpch));
                   1059:
                   1060:         return;
                   1061:     }
                   1062:
                   1063:     /*
                   1064:      * Here we print help for everything. Then wait before we return to
                   1065:      * command mode
                   1066:      */
                   1067:
                   1068:     wclear(hw);
                   1069:     cnt = 0;
                   1070:
                   1071:     while (strp->h_ch)
                   1072:     {
                   1073:         if (strp->h_desc == 0)
                   1074:             if (!wizard)
                   1075:                 break;
                   1076:             else
                   1077:             {
                   1078:                 strp++;
                   1079:                 continue;
                   1080:             }
                   1081:
                   1082:         mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
                   1083:         waddstr(hw, strp->h_desc);
                   1084:         strp++;
                   1085:
                   1086:         if (++cnt >= 46 && strp->h_ch && (strp->h_desc != NULL || wizard))
                   1087:         {
                   1088:             wmove(hw, LINES - 1, 0);
                   1089:             wprintw(hw, (char *) morestr);
                   1090:             wrefresh(hw);
                   1091:             wait_for(' ');
                   1092:             wclear(hw);
                   1093:             cnt = 0;
                   1094:         }
                   1095:     }
                   1096:
                   1097:     wmove(hw, LINES - 1, 0);
                   1098:     wprintw(hw, (char *) morestr);
                   1099:     wrefresh(hw);
                   1100:     wait_for(' ');
                   1101:     wclear(hw);
                   1102:     wrefresh(hw);
                   1103:
                   1104:     wmove(cw, 0, 0);
                   1105:     wclrtoeol(cw);
                   1106:     status(FALSE);
                   1107:     touchwin(cw);
                   1108:
                   1109:     return;
                   1110: }
                   1111:
                   1112: /*
                   1113:     identify()
                   1114:         Tell the player what a certain thing is.
                   1115: */
                   1116:
                   1117: void
                   1118: identify(void)
                   1119: {
                   1120:     int   ch;
                   1121:     char *str;
                   1122:
                   1123:     msg("What do you want identified? ");
                   1124:     mpos = 0;
                   1125:
                   1126:     if ((ch = readchar()) == ESCAPE)
                   1127:     {
                   1128:         msg("");
                   1129:         return;
                   1130:     }
                   1131:
                   1132:     if (isalpha(ch))
                   1133:     {
                   1134:         id_monst(ch);
                   1135:         return;
                   1136:     }
                   1137:
                   1138:     switch (ch)
                   1139:     {
                   1140:         case '|':
                   1141:         case '-':        str = "wall of a room";                 break;
                   1142:         case GOLD:       str = "gold";                           break;
                   1143:         case STAIRS:     str = "passage leading down";           break;
                   1144:         case DOOR:       str = "door";                           break;
                   1145:         case FLOOR:      str = "room floor";                     break;
                   1146:         case VPLAYER:    str = "The hero of the game ---> you";  break;
                   1147:         case IPLAYER:    str = "you (but invisible)";            break;
                   1148:         case PASSAGE:    str = "passage";                        break;
                   1149:         case POST:       str = "trading post";                   break;
                   1150:         case POOL:       str = "a shimmering pool";              break;
                   1151:         case TRAPDOOR:   str = "trapdoor";                       break;
                   1152:         case ARROWTRAP:  str = "arrow trap";                     break;
                   1153:         case SLEEPTRAP:  str = "sleeping gas trap";              break;
                   1154:         case BEARTRAP:   str = "bear trap";                      break;
                   1155:         case TELTRAP:    str = "teleport trap";                  break;
                   1156:         case DARTTRAP:   str = "dart trap";                      break;
                   1157:         case MAZETRAP:   str = "entrance to a maze";             break;
                   1158:         case FIRETRAP:   str = "fire trap";                      break;
                   1159:         case POISONTRAP: str = "poison pool trap";               break;
                   1160:         case LAIR:       str = "monster lair entrance";          break;
                   1161:         case RUSTTRAP:   str = "rust trap";                      break;
                   1162:         case POTION:     str = "potion";                         break;
                   1163:         case SCROLL:     str = "scroll";                         break;
                   1164:         case FOOD:       str = "food";                           break;
                   1165:         case WEAPON:     str = "weapon";                         break;
                   1166:         case ' ':        str = "solid rock";                     break;
                   1167:         case ARMOR:      str = "armor";                          break;
                   1168:         case ARTIFACT:   str = "an artifact from bygone ages";   break;
                   1169:         case RING:       str = "ring";                           break;
                   1170:         case STICK:      str = "wand or staff";                  break;
                   1171:         default:         str = "unknown character";              break;
                   1172:     }
                   1173:     msg("'%s'; %s", unctrl(ch), str);
                   1174: }
                   1175:
                   1176: /*
                   1177:     d_level()
                   1178:         He wants to go down a level
                   1179: */
                   1180:
                   1181: void
                   1182: d_level(void)
                   1183: {
                   1184:     int no_phase = FALSE;
                   1185:
                   1186:     if (mvinch(hero.y, hero.x) != STAIRS)
                   1187:     {
                   1188:         if (off(player, CANINWALL))  /* Must use stairs if can't phase */
                   1189:         {
                   1190:             msg("I see no way down.");
                   1191:             return;
                   1192:         }
                   1193:
                   1194:         extinguish_fuse(FUSE_UNPHASE);/*Using phase to go down gets rid of it*/
                   1195:         no_phase = TRUE;
                   1196:     }
                   1197:
                   1198:     if (is_wearing(R_LEVITATION) || on(player, CANFLY))
                   1199:     {
                   1200:         msg("You can't!  You're floating in the air.");
                   1201:         return;
                   1202:     }
                   1203:
                   1204:     if (rnd(pstats.s_dext) < 3 * (2 - hitweight() +
                   1205:         (on(player, STUMBLER) ? 4 : 0)))
                   1206:     {
                   1207:         msg("You trip and fall down the stairs.");
                   1208:
                   1209:         if ((pstats.s_hpt -= roll(1, 10)) <= 0)
                   1210:         {
                   1211:             msg("You break your neck and die.");
                   1212:             death(D_FALL);
                   1213:             return;
                   1214:         }
                   1215:     }
                   1216:
                   1217:     level++;
                   1218:     new_level(NORMLEV,0);
                   1219:
                   1220:     if (no_phase)
                   1221:         unphase(NULL);
                   1222:
                   1223:     return;
                   1224: }
                   1225:
                   1226: /*
                   1227:     u_level()
                   1228:         He wants to go up a level
                   1229: */
                   1230:
                   1231: void
                   1232: u_level(void)
                   1233: {
                   1234:     char ch = 0;
                   1235:
                   1236:     if (has_artifact && ((ch = CCHAR(mvinch(hero.y, hero.x))) == STAIRS ||
                   1237:                  (on(player, CANINWALL)
                   1238:             && (is_wearing(R_LEVITATION) || on(player, CANFLY)))))
                   1239:     {
                   1240:         if (--level == 0)
                   1241:             total_winner();
                   1242:         else if (rnd(wizard ? 3 : 15) == 0)
                   1243:             new_level(THRONE,0);
                   1244:         else
                   1245:         {
                   1246:             new_level(NORMLEV,0);
                   1247:             msg("You feel a wrenching sensation in your gut.");
                   1248:         }
                   1249:
                   1250:         if (on(player, CANINWALL) && ch != STAIRS)
                   1251:         {
                   1252:             extinguish_fuse(FUSE_UNPHASE);
                   1253:             unphase(NULL);
                   1254:         }
                   1255:
                   1256:         return;
                   1257:     }
                   1258:     else if (ch != STAIRS &&
                   1259:          !(on(player, CANINWALL) && (is_wearing(R_LEVITATION)
                   1260:                          || on(player, CANFLY))))
                   1261:         msg("I see no way up.");
                   1262:     else
                   1263:         msg("Your way is magically blocked.");
                   1264:
                   1265:     return;
                   1266: }
                   1267:
                   1268: /*
                   1269:     call()
                   1270:         allow a user to call a potion, scroll, or ring something
                   1271: */
                   1272:
                   1273: void
                   1274: call(int mark)
                   1275: {
                   1276:     struct object    *obj;
                   1277:     char             *elsewise;
                   1278:     int item_type =   numthings;
                   1279:     char            **item_color = NULL;
                   1280:
                   1281:     if (mark)
                   1282:         obj = get_object(pack, "mark", 0, bff_markable);
                   1283:     else
                   1284:         obj = get_object(pack, "call", 0, bff_callable);
                   1285:
                   1286:     if (obj == NULL)
                   1287:         return;
                   1288:
                   1289:     switch (obj->o_type)
                   1290:     {
                   1291:         case RING:
                   1292:             item_type = TYP_RING;
                   1293:             item_color = r_stones;
                   1294:             break;
                   1295:         case POTION:
                   1296:             item_type = TYP_POTION;
                   1297:             item_color = p_colors;
                   1298:             break;
                   1299:         case SCROLL:
                   1300:             item_type = TYP_SCROLL;
                   1301:             item_color = s_names;
                   1302:             break;
                   1303:         case STICK:
                   1304:             item_type = TYP_STICK;
                   1305:             item_color = ws_made;
                   1306:             break;
                   1307:         default:
                   1308:             if (!mark)
                   1309:             {
                   1310:                 msg("You can't call that anything.");
                   1311:                 return;
                   1312:             }
                   1313:             break;
                   1314:     }
                   1315:
                   1316:     if (!mark && know_items[item_type][obj->o_which])
                   1317:     {
                   1318:         msg("That has already been identified.");
                   1319:         return;
                   1320:     }
                   1321:
                   1322:     if (mark)
                   1323:     {
                   1324:         if (obj->o_mark[0])
                   1325:             msg("Was marked \"%s\".", obj->o_mark);
                   1326:
                   1327:         msg("What do you want to mark it? ");
                   1328:         prbuf[0] = '\0';
                   1329:     }
                   1330:     else
                   1331:     {
                   1332:         elsewise = (guess_items[item_type][obj->o_which] != NULL ?
                   1333:            guess_items[item_type][obj->o_which] : item_color[obj->o_which]);
                   1334:
                   1335:         msg("Was called \"%s\".", elsewise);
                   1336:         msg("What do you want to call it? ");
                   1337:
                   1338:         if (guess_items[item_type][obj->o_which] != NULL)
                   1339:             ur_free(guess_items[item_type][obj->o_which]);
                   1340:
                   1341:         strcpy(prbuf, elsewise);
                   1342:     }
                   1343:
                   1344:     if (get_string(prbuf, cw) == NORM)
                   1345:     {
                   1346:         if (mark)
                   1347:         {
                   1348:             strncpy(obj->o_mark, prbuf, MARKLEN - 1);
                   1349:             obj->o_mark[MARKLEN - 1] = '\0';
                   1350:         }
                   1351:         else
                   1352:         {
                   1353:             guess_items[item_type][obj->o_which] = new_alloc(strlen(prbuf) + 1);
                   1354:             strcpy(guess_items[item_type][obj->o_which], prbuf);
                   1355:         }
                   1356:     }
                   1357:
                   1358:     return;
                   1359: }
                   1360:
                   1361: /*
                   1362:     att_bonus()
                   1363:         bonus attacks for certain player classes
                   1364: */
                   1365:
                   1366: int
                   1367: att_bonus(void)
                   1368: {
                   1369:     int bonus = FALSE;
                   1370:
                   1371:     if ((player.t_ctype == C_FIGHTER || player.t_ctype == C_PALADIN)
                   1372:             && (pstats.s_lvl > 12 ||
                   1373:             (pstats.s_lvl > 6 && pstats.s_lvl < 13 && rnd(2))))
                   1374:         bonus = TRUE;
                   1375:
                   1376:     else if ((player.t_ctype == C_RANGER)
                   1377:              && (pstats.s_lvl > 14 ||
                   1378:              (pstats.s_lvl > 7 && pstats.s_lvl < 15 && rnd(2))))
                   1379:         bonus = TRUE;
                   1380:
                   1381:     else if ((player.t_ctype == C_NINJA)
                   1382:              && (pstats.s_lvl > 8 ||
                   1383:              (pstats.s_lvl > 4 && pstats.s_lvl < 9 && rnd(2))))
                   1384:         bonus = TRUE;
                   1385:
                   1386:     return(bonus);
                   1387: }

CVSweb