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

Annotation of early-roguelike/arogue5/wizard.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * Special wizard commands (some of which are also non-wizard commands
                      3:  * under strange circumstances)
                      4:  *
                      5:  * Advanced Rogue
                      6:  * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
                      7:  * All rights reserved.
                      8:  *
                      9:  * Based on "Rogue: Exploring the Dungeons of Doom"
                     10:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     11:  * All rights reserved.
                     12:  *
                     13:  * See the file LICENSE.TXT for full copyright and licensing information.
                     14:  */
                     15:
                     16: #include "curses.h"
                     17: #include <ctype.h>
                     18: #include <string.h>
                     19: #include <stdlib.h>
                     20: #include "rogue.h"
                     21:
                     22:
                     23: /*
                     24:  * create_obj:
                     25:  *     Create any object for wizard, scroll, magician, or cleric
                     26:  */
                     27: void
                     28: create_obj(bool prompt, int which_item, int which_type)
                     29: {
                     30:     reg struct linked_list *item;
                     31:     reg struct object *obj;
                     32:     reg int wh;
                     33:     reg char ch, newitem, newtype = 0, whc, msz, *pt;
                     34:     WINDOW *thiswin;
                     35:
                     36:     thiswin = cw;
                     37:     if (prompt) {
                     38:        bool nogood = TRUE;
                     39:
                     40:        thiswin = hw;
                     41:        wclear(hw);
                     42:        wprintw(hw,"Item\t\t\tKey\n\n");
                     43:        wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_RING].mi_name,RING,
                     44:                things[TYP_STICK].mi_name,STICK);
                     45:        wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_POTION].mi_name,POTION,
                     46:                things[TYP_SCROLL].mi_name,SCROLL);
                     47:        wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_ARMOR].mi_name,ARMOR,
                     48:                things[TYP_WEAPON].mi_name,WEAPON);
                     49:        wprintw(hw,"%s\t%c\n",things[TYP_MM].mi_name,MM);
                     50:        wprintw(hw,"%s\t\t\t%c\n",things[TYP_FOOD].mi_name,FOOD);
                     51:        if (wizard) {
                     52:            wprintw(hw,"%s\t\t%c\n",things[TYP_RELIC].mi_name,RELIC);
                     53:            waddstr(hw,"monster\t\t\tm");
                     54:        }
                     55:        wprintw(hw,"\n\nWhat do you want to create? ");
                     56:        draw(hw);
                     57:        do {
                     58:            ch = wgetch(hw);
                     59:            if (ch == ESCAPE) {
                     60:                restscr(cw);
                     61:                return;
                     62:            }
                     63:            switch (ch) {
                     64:                case RING:
                     65:                case STICK:
                     66:                case POTION:
                     67:                case SCROLL:
                     68:                case ARMOR:
                     69:                case WEAPON:
                     70:                case FOOD:
                     71:                case MM:
                     72:                    nogood = FALSE;
                     73:                    break;
                     74:                case RELIC:
                     75:                case 'm':
                     76:                    if (wizard)
                     77:                        nogood = FALSE;
                     78:                    break;
                     79:                default:
                     80:                    nogood = TRUE;
                     81:            }
                     82:        } while (nogood);
                     83:        newitem = ch;
                     84:     }
                     85:     else
                     86:        newitem = which_item;
                     87:
                     88:     pt = "those";
                     89:     msz = 0;
                     90:     if(newitem == 'm') {
                     91:        makemonster(TRUE);              /* make monster and be done with it */
                     92:        return;
                     93:     }
                     94:     if(newitem == GOLD)
                     95:        pt = "gold";
                     96:     /* else if(isatrap(newitem))
                     97:        pt = "traps";
                     98:     */
                     99:     switch(newitem) {
                    100:        case POTION:    whc = TYP_POTION;       msz = MAXPOTIONS;
                    101:        when SCROLL:    whc = TYP_SCROLL;       msz = MAXSCROLLS;
                    102:        when WEAPON:    whc = TYP_WEAPON;       msz = MAXWEAPONS;
                    103:        when ARMOR:     whc = TYP_ARMOR;        msz = MAXARMORS;
                    104:        when RING:      whc = TYP_RING;         msz = MAXRINGS;
                    105:        when STICK:     whc = TYP_STICK;        msz = MAXSTICKS;
                    106:        when MM:        whc = TYP_MM;           msz = MAXMM;
                    107:        when RELIC:     whc = TYP_RELIC;        msz = MAXRELIC;
                    108:        when FOOD:
                    109:            whc = TYP_FOOD;
                    110:            msz = MAXFOODS;
                    111:            if (thiswin == hw)
                    112:                restscr(cw);
                    113:            mpos = 0;
                    114:        otherwise:
                    115:            if (thiswin == hw)
                    116:                restscr(cw);
                    117:            mpos = 0;
                    118:            msg("Even wizards can't create %s !!",pt);
                    119:            return;
                    120:     }
                    121:     if(msz == 1) {             /* if only one type of item */
                    122:        ch = 'a';
                    123:     }
                    124:     else if (prompt) {
                    125:        register struct magic_item *wmi;
                    126:        char wmn;
                    127:        register int ii;
                    128:        int old_prob;
                    129:
                    130:        mpos = 0;
                    131:        wmi = NULL;
                    132:        wmn = 0;
                    133:        switch(newitem) {
                    134:                case POTION:    wmi = &p_magic[0];
                    135:                when SCROLL:    wmi = &s_magic[0];
                    136:                when RING:      wmi = &r_magic[0];
                    137:                when STICK:     wmi = &ws_magic[0];
                    138:                when MM:        wmi = &m_magic[0];
                    139:                when RELIC:     wmi = &rel_magic[0];
                    140:                when WEAPON:    wmn = 1;
                    141:                when ARMOR:     wmn = 2;
                    142:        }
                    143:        wclear(hw);
                    144:        thiswin = hw;
                    145:        if (wmi != NULL) {
                    146:            ii = old_prob = 0;
                    147:            while (ii < msz) {
                    148:                if(wmi->mi_prob == old_prob && wizard == FALSE) {
                    149:                    msz--; /* can't make a unique item */
                    150:                }
                    151:                else {
                    152:                    mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
                    153:                    waddstr(hw,") ");
                    154:                    waddstr(hw,wmi->mi_name);
                    155:                    ii++;
                    156:                }
                    157:                old_prob = wmi->mi_prob;
                    158:                wmi++;
                    159:            }
                    160:        }
                    161:        else if (wmn != 0) {
                    162:            for(ii = 0 ; ii < msz ; ii++) {
                    163:                mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
                    164:                waddstr(hw,") ");
                    165:                if(wmn == 1)
                    166:                    waddstr(hw,weaps[ii].w_name);
                    167:                else
                    168:                    waddstr(hw,armors[ii].a_name);
                    169:            }
                    170:        }
                    171:        sprintf(prbuf,"Which %s? ",things[whc].mi_name);
                    172:        mvwaddstr(hw,LINES - 1, 0, prbuf);
                    173:        draw(hw);
                    174:        do {
                    175:            ch = wgetch(hw);
                    176:            if (ch == ESCAPE) {
                    177:                restscr(cw);
                    178:                msg("");
                    179:                return;
                    180:            }
                    181:        } until (isalpha(ch));
                    182:         if (thiswin == hw)                     /* restore screen if need be */
                    183:            restscr(cw);
                    184:         newtype = tolower(ch) - 'a';
                    185:         if(newtype < 0 || newtype >= msz) {    /* if an illegal value */
                    186:            mpos = 0;
                    187:            msg("There is no such %s",things[whc].mi_name);
                    188:            return;
                    189:         }
                    190:     }
                    191:     else
                    192:        newtype = which_type;
                    193:     item = new_item(sizeof *obj);      /* get some memory */
                    194:     obj = OBJPTR(item);
                    195:     obj->o_type = newitem;             /* store the new items */
                    196:     obj->o_mark[0] = '\0';
                    197:     obj->o_which = newtype;
                    198:     obj->o_group = 0;
                    199:     obj->contents = NULL;
                    200:     obj->o_count = 1;
                    201:     obj->o_flags = 0;
                    202:     obj->o_dplus = obj->o_hplus = 0;
                    203:     obj->o_weight = 0;
                    204:     wh = obj->o_which;
                    205:     mpos = 0;
                    206:     if (!wizard)                       /* users get 0 to +3 */
                    207:        whc = rnd(4);
                    208:     else                       /* wizard gets to choose */
                    209:        whc = getbless();
                    210:     if (whc < 0)
                    211:        obj->o_flags |= ISCURSED;
                    212:     switch (obj->o_type) {
                    213:        case WEAPON:
                    214:        case ARMOR:
                    215:            if (obj->o_type == WEAPON) {
                    216:                init_weapon(obj, wh);
                    217:                obj->o_hplus += whc;
                    218:                obj->o_dplus += whc;
                    219:            }
                    220:            else {                              /* armor here */
                    221:                obj->o_weight = armors[wh].a_wght;
                    222:                obj->o_ac = armors[wh].a_class - whc;
                    223:            }
                    224:        when RING:
                    225:            if (whc > 1 && r_magic[wh].mi_bless != 0)
                    226:                obj->o_flags |= ISBLESSED;
                    227:            r_know[wh] = TRUE;
                    228:            switch(wh) {
                    229:                case R_ADDSTR:
                    230:                case R_ADDWISDOM:
                    231:                case R_ADDINTEL:
                    232:                case R_PROTECT:
                    233:                case R_ADDHIT:
                    234:                case R_ADDDAM:
                    235:                case R_DIGEST:
                    236:                    obj->o_ac = whc + 1;
                    237:                    break;
                    238:                default:
                    239:                    obj->o_ac = 0;
                    240:            }
                    241:            obj->o_weight = things[TYP_RING].mi_wght;
                    242:        when MM:
                    243:            if (whc > 1 && m_magic[wh].mi_bless != 0)
                    244:                obj->o_flags |= ISBLESSED;
                    245:            m_know[wh] = TRUE;
                    246:            switch(wh) {
                    247:                case MM_JUG:
                    248:                    switch(rnd(9)) {
                    249:                        case 0: obj->o_ac = P_PHASE;
                    250:                        when 1: obj->o_ac = P_CLEAR;
                    251:                        when 2: obj->o_ac = P_SEEINVIS;
                    252:                        when 3: obj->o_ac = P_HEALING;
                    253:                        when 4: obj->o_ac = P_MFIND;
                    254:                        when 5: obj->o_ac = P_TFIND;
                    255:                        when 6: obj->o_ac = P_HASTE;
                    256:                        when 7: obj->o_ac = P_RESTORE;
                    257:                        when 8: obj->o_ac = P_FLY;
                    258:                    }
                    259:                when MM_OPEN:
                    260:                case MM_HUNGER:
                    261:                case MM_DRUMS:
                    262:                case MM_DISAPPEAR:
                    263:                case MM_CHOKE:
                    264:                case MM_KEOGHTOM:
                    265:                    if (whc < 0)
                    266:                        whc = -whc;     /* these cannot be negative */
                    267:                    obj->o_ac = (whc + 1) * 5;
                    268:                    break;
                    269:                when MM_BRACERS:
                    270:                    obj->o_ac = whc * 2 + 1;
                    271:                when MM_DISP:
                    272:                    obj->o_ac = 2;
                    273:                when MM_PROTECT:
                    274:                    obj->o_ac = whc;
                    275:                when MM_SKILLS:
                    276:                    if (wizard && whc != 0)
                    277:                        obj->o_ac = rnd(4);
                    278:                    else
                    279:                        obj->o_ac = player.t_ctype;
                    280:                otherwise:
                    281:                    obj->o_ac = 0;
                    282:            }
                    283:            obj->o_weight = things[TYP_MM].mi_wght;
                    284:        when STICK:
                    285:            if (whc > 1 && ws_magic[wh].mi_bless != 0)
                    286:                obj->o_flags |= ISBLESSED;
                    287:            ws_know[wh] = TRUE;
                    288:            fix_stick(obj);
                    289:        when SCROLL:
                    290:            if (whc > 1 && s_magic[wh].mi_bless != 0)
                    291:                obj->o_flags |= ISBLESSED;
                    292:            obj->o_weight = things[TYP_SCROLL].mi_wght;
                    293:            s_know[wh] = TRUE;
                    294:        when POTION:
                    295:            if (whc > 1 && p_magic[wh].mi_bless != 0)
                    296:                obj->o_flags |= ISBLESSED;
                    297:            obj->o_weight = things[TYP_POTION].mi_wght;
                    298:            p_know[wh] = TRUE;
                    299:        when RELIC:
                    300:            obj->o_weight = things[TYP_RELIC].mi_wght;
                    301:     }
                    302:     mpos = 0;
                    303:     obj->o_flags |= ISKNOW;
                    304:     if (add_pack(item, FALSE, NULL) == FALSE) {
                    305:        obj->o_pos = hero;
                    306:        fall(item, TRUE);
                    307:     }
                    308: }
                    309: 
                    310: /*
                    311:  * getbless:
                    312:  *     Get a blessing for a wizards object
                    313:  */
                    314: int
                    315: getbless(void)
                    316: {
                    317:        reg char bless;
                    318:
                    319:        msg("Blessing? (+,-,n)");
                    320:        bless = readchar();
                    321:        if (bless == '+')
                    322:                return (rnd(3) + 2);
                    323:        else if (bless == '-')
                    324:                return (-rnd(3) - 1);
                    325:        else
                    326:                return (0);
                    327: }
                    328: 
                    329: /*
                    330:  * get a non-monster death type
                    331:  */
                    332: int
                    333: getdeath(void)
                    334: {
                    335:     register int i;
                    336:     int which_death;
                    337:     char label[80];
                    338:
                    339:     clear();
                    340:     for (i=0; i<DEATHNUM; i++) {
                    341:        sprintf(label, "[%d] %s", i+1, deaths[i].name);
                    342:        mvaddstr(i+2, 0, label);
                    343:     }
                    344:     mvaddstr(0, 0, "Which death? ");
                    345:     refresh();
                    346:
                    347:     /* Get the death */
                    348:     for (;;) {
                    349:        get_str(label, stdscr);
                    350:        which_death = atoi(label);
                    351:        if ((which_death < 1 || which_death > DEATHNUM)) {
                    352:            mvaddstr(0, 0, "Please enter a number in the displayed range -- ");
                    353:            refresh();
                    354:        }
                    355:        else break;
                    356:     }
                    357:     return(deaths[which_death-1].reason);
                    358: }
                    359: 
                    360: /*
                    361:  * make a monster for the wizard
                    362:  */
                    363: short
                    364: makemonster(bool create)
                    365: {
                    366:     register int i;
                    367:     register short which_monst;
                    368:     register int num_monst = NUMMONST, pres_monst=1, num_lines=2*(LINES-3);
                    369:     char monst_name[40];
                    370:
                    371:     /* Print out the monsters */
                    372:     while (num_monst > 0) {
                    373:        register int left_limit;
                    374:
                    375:        if (num_monst < num_lines) left_limit = (num_monst+1)/2;
                    376:        else left_limit = num_lines/2;
                    377:
                    378:        wclear(hw);
                    379:        touchwin(hw);
                    380:
                    381:        /* Print left column */
                    382:        wmove(hw, 2, 0);
                    383:        for (i=0; i<left_limit; i++) {
                    384:            sprintf(monst_name, "[%d] %s\n",
                    385:                                pres_monst, monsters[pres_monst].m_name);
                    386:            waddstr(hw, monst_name);
                    387:            pres_monst++;
                    388:        }
                    389:
                    390:        /* Print right column */
                    391:        for (i=0; i<left_limit && pres_monst<=NUMMONST; i++) {
                    392:            sprintf(monst_name, "[%d] %s",
                    393:                                pres_monst, monsters[pres_monst].m_name);
                    394:            wmove(hw, i+2, COLS/2);
                    395:            waddstr(hw, monst_name);
                    396:            pres_monst++;
                    397:        }
                    398:
                    399:        if ((num_monst -= num_lines) > 0) {
                    400:            mvwaddstr(hw, LINES-1, 0, morestr);
                    401:            draw(hw);
                    402:            wait_for(hw,' ');
                    403:        }
                    404:
                    405:        else {
                    406:            mvwaddstr(hw, 0, 0, "Which monster");
                    407:            if (!terse && create) waddstr(hw, " do you wish to create");
                    408:            waddstr(hw, "? ");
                    409:            draw(hw);
                    410:        }
                    411:     }
                    412:
                    413: get_monst:
                    414:     get_str(monst_name, hw);
                    415:     which_monst = atoi(monst_name);
                    416:     if ((which_monst < 1 || which_monst > NUMMONST)) {
                    417:        mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
                    418:        draw(hw);
                    419:        goto get_monst;
                    420:     }
                    421:     restscr(cw);
                    422:     if (create) {
                    423:        creat_mons (&player, which_monst, TRUE);
                    424:        light(&hero);
                    425:     }
                    426:     touchwin(cw);
                    427:     return(which_monst);
                    428: }
                    429: 
                    430: /*
                    431:  * passwd:
                    432:  *     see if user knows password
                    433:  */
                    434:
                    435: bool
                    436: passwd(void)
                    437: {
                    438:     register char *sp, c;
                    439:     char buf[LINELEN];
                    440:
                    441:     msg("Wizard's Password:");
                    442:     mpos = 0;
                    443:     sp = buf;
                    444:     while ((c = readchar()) != '\n' && c != '\r' && c != '\033')
                    445:        if (c == md_killchar())
                    446:            sp = buf;
                    447:        else if (c == md_erasechar() && sp > buf)
                    448:            sp--;
                    449:        else
                    450:            *sp++ = c;
                    451:     if (sp == buf)
                    452:        return FALSE;
                    453:     *sp = '\0';
                    454:     return (strcmp(PASSWD, md_crypt(buf, "Si")) == 0);
                    455: }
                    456:
                    457: 
                    458: /*
                    459:  * teleport:
                    460:  *     Bamf the hero someplace else
                    461:  */
                    462:
                    463: int
                    464: teleport(void)
                    465: {
                    466:     register struct room *new_rp, *old_rp = roomin(&hero);
                    467:     register int rm;
                    468:     coord c;
                    469:
                    470:     c = hero;
                    471:     mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x));
                    472:     do
                    473:     {
                    474:        rm = rnd_room();
                    475:        rnd_pos(&rooms[rm], &hero);
                    476:     } until(winat(hero.y, hero.x) == FLOOR);
                    477:     player.t_oldpos = c;       /* Save last position */
                    478:
                    479:     /* If hero gets moved, darken old room */
                    480:     new_rp = &rooms[rm];
                    481:     if (old_rp && old_rp != new_rp) {
                    482:        old_rp->r_flags |= FORCEDARK;   /* Fake darkness */
                    483:        light(&c);
                    484:        old_rp->r_flags &= ~FORCEDARK; /* Restore light state */
                    485:     }
                    486:
                    487:     /* Darken where we just came from */
                    488:     else if (levtype == MAZELEV) light(&c);
                    489:
                    490:     light(&hero);
                    491:     mvwaddch(cw, hero.y, hero.x, PLAYER);
                    492:
                    493:     /* Reset current room and position */
                    494:     oldrp = new_rp;    /* Used in look() */
                    495:     player.t_oldpos = hero;
                    496:
                    497:     /*
                    498:      * turn off ISHELD in case teleportation was done while fighting
                    499:      * something that holds you
                    500:      */
                    501:     if (on(player, ISHELD)) {
                    502:        register struct linked_list *ip, *nip;
                    503:        register struct thing *mp;
                    504:
                    505:        turn_off(player, ISHELD);
                    506:        hold_count = 0;
                    507:        for (ip = mlist; ip; ip = nip) {
                    508:            mp = THINGPTR(ip);
                    509:            nip = next(ip);
                    510:            if (on(*mp, DIDHOLD)) {
                    511:                turn_off(*mp, DIDHOLD);
                    512:                turn_on(*mp, CANHOLD);
                    513:            }
                    514:            turn_off(*mp, DIDSUFFOCATE); /* Suffocation -- see below */
                    515:        }
                    516:     }
                    517:
                    518:     /* Make sure player does not suffocate */
                    519:     extinguish(suffocate);
                    520:
                    521:     count = 0;
                    522:     running = FALSE;
                    523:     md_flushinp();
                    524:     return rm;
                    525: }
                    526: 
                    527: /*
                    528:  * whatis:
                    529:  *     What a certin object is
                    530:  */
                    531:
                    532: void
                    533: whatis(struct linked_list *what)
                    534: {
                    535:     register struct object *obj;
                    536:     register struct linked_list *item;
                    537:
                    538:     if (what == NULL) {                /* do we need to ask which one? */
                    539:        if ((item = get_item(pack, "identify", IDENTABLE)) == NULL)
                    540:            return;
                    541:     }
                    542:     else
                    543:        item = what;
                    544:     obj = OBJPTR(item);
                    545:     switch (obj->o_type) {
                    546:         case SCROLL:
                    547:            s_know[obj->o_which] = TRUE;
                    548:            if (s_guess[obj->o_which]) {
                    549:                free(s_guess[obj->o_which]);
                    550:                s_guess[obj->o_which] = NULL;
                    551:            }
                    552:         when POTION:
                    553:            p_know[obj->o_which] = TRUE;
                    554:            if (p_guess[obj->o_which]) {
                    555:                free(p_guess[obj->o_which]);
                    556:                p_guess[obj->o_which] = NULL;
                    557:            }
                    558:        when STICK:
                    559:            ws_know[obj->o_which] = TRUE;
                    560:            if (ws_guess[obj->o_which]) {
                    561:                free(ws_guess[obj->o_which]);
                    562:                ws_guess[obj->o_which] = NULL;
                    563:            }
                    564:         when RING:
                    565:            r_know[obj->o_which] = TRUE;
                    566:            if (r_guess[obj->o_which]) {
                    567:                free(r_guess[obj->o_which]);
                    568:                r_guess[obj->o_which] = NULL;
                    569:            }
                    570:         when MM:
                    571:            /* If it's an identified jug, identify its potion */
                    572:            if (obj->o_which == MM_JUG && (obj->o_flags & ISKNOW)) {
                    573:                if (obj->o_ac != JUG_EMPTY)
                    574:                    p_know[obj->o_ac] = TRUE;
                    575:                break;
                    576:            }
                    577:
                    578:            m_know[obj->o_which] = TRUE;
                    579:            if (m_guess[obj->o_which]) {
                    580:                free(m_guess[obj->o_which]);
                    581:                m_guess[obj->o_which] = NULL;
                    582:            }
                    583:        otherwise:
                    584:            break;
                    585:     }
                    586:     obj->o_flags |= ISKNOW;
                    587:     if (what == NULL)
                    588:        msg(inv_name(obj, FALSE));
                    589: }
                    590:

CVSweb