Annotation of 43BSDReno/games/phantasia/fight.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * fight.c   Phantasia monster fighting routines
                      3:  */
                      4: 
                      5: #include "include.h"
                      6: 
                      7: /************************************************************************
                      8: /
                      9: / FUNCTION NAME: encounter()
                     10: /
                     11: / FUNCTION: monster battle routine
                     12: /
                     13: / AUTHOR: E. A. Estes, 2/20/86
                     14: /
                     15: / ARGUMENTS:
                     16: /      int particular - particular monster to fight if >= 0
                     17: /
                     18: / RETURN VALUE: none
                     19: /
                     20: / MODULES CALLED: monsthits(), playerhits(), readmessage(), callmonster(), 
                     21: /      writerecord(), pickmonster(), displaystats(), pow(), cancelmonster(), 
                     22: /      awardtreasure(), more(), death(), wmove(), setjmp(), drandom(), printw(), 
                     23: /      longjmp(), wrefresh(), mvprintw(), wclrtobot()
                     24: /
                     25: / GLOBAL INPUTS: Curmonster, Whichmonster, LINES, Lines, Circle, Shield, 
                     26: /      Player, *stdscr, Fileloc, Fightenv[], *Enemyname
                     27: /
                     28: / GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, Luckout
                     29: /
                     30: / DESCRIPTION:
                     31: /      Choose a monster and check against some special types.
                     32: /      Arbitrate between monster and player.  Watch for either
                     33: /      dying.
                     34: /
                     35: /************************************************************************/
                     36: 
                     37: encounter(particular)
                     38: int    particular;
                     39: {
                     40: bool   firsthit = Player.p_blessing;   /* set if player gets the first hit */
                     41: int    flockcnt = 1;                   /* how many time flocked */
                     42: 
                     43:     /* let others know what we are doing */
                     44:     Player.p_status = S_MONSTER;
                     45:     writerecord(&Player, Fileloc);
                     46: 
                     47: #ifdef SYS5
                     48:     flushinp();
                     49: #endif
                     50: 
                     51:     Shield = 0.0;              /* no shield up yet */
                     52: 
                     53:     if (particular >= 0)
                     54:        /* monster is specified */
                     55:        Whichmonster = particular;
                     56:     else
                     57:        /* pick random monster */
                     58:        Whichmonster = pickmonster();
                     59: 
                     60:     setjmp(Fightenv);          /* this is to enable changing fight state */
                     61: 
                     62:     move(6, 0);
                     63:     clrtobot();                        /* clear bottom area of screen */
                     64: 
                     65:     Lines = 9;
                     66:     callmonster(Whichmonster); /* set up monster to fight */
                     67: 
                     68:     Luckout = FALSE;           /* haven't tried to luckout yet */
                     69: 
                     70:     if (Curmonster.m_type == SM_MORGOTH)
                     71:        mvprintw(4, 0, "You've encountered %s, Bane of the Council and Valar.\n",
                     72:            Enemyname);
                     73: 
                     74:     if (Curmonster.m_type == SM_UNICORN)
                     75:        {
                     76:        if (Player.p_virgin)
                     77:            {
                     78:            printw("You just subdued %s, thanks to the virgin.\n", Enemyname);
                     79:            Player.p_virgin = FALSE;
                     80:            }
                     81:        else
                     82:            {
                     83:            printw("You just saw %s running away!\n", Enemyname);
                     84:            Curmonster.m_experience = 0.0;
                     85:            Curmonster.m_treasuretype = 0;
                     86:            }
                     87:        }
                     88:     else
                     89:        /* not a special monster */
                     90:        for (;;)
                     91:            /* print header, and arbitrate between player and monster */
                     92:            {
                     93:            mvprintw(6, 0, "You are being attacked by %s,   EXP: %.0f   (Size: %.0f)\n",
                     94:                Enemyname, Curmonster.m_experience, Circle);
                     95: 
                     96:            displaystats();
                     97:            mvprintw(1, 26, "%20.0f", Player.p_energy + Shield);        /* overprint energy */
                     98:            readmessage();
                     99: 
                    100:            if (Curmonster.m_type == SM_DARKLORD
                    101:                && Player.p_blessing
                    102:                && Player.p_charms > 0)
                    103:                /* overpower Dark Lord with blessing and charm */
                    104:                {
                    105:                mvprintw(7, 0, "You just overpowered %s!", Enemyname);
                    106:                Lines = 8;
                    107:                Player.p_blessing = FALSE;
                    108:                --Player.p_charms;
                    109:                break;
                    110:                }
                    111: 
                    112:            /* allow paralyzed monster to wake up */
                    113:            Curmonster.m_speed = MIN(Curmonster.m_speed + 1.0, Curmonster.m_maxspeed);
                    114: 
                    115:            if (drandom() * Curmonster.m_speed > drandom() * Player.p_speed
                    116:                /* monster is faster */
                    117:                && Curmonster.m_type != SM_DARKLORD
                    118:                /* not D. L. */
                    119:                && Curmonster.m_type != SM_SHRIEKER
                    120:                /* not mimic */
                    121:                && !firsthit)
                    122:                /* monster gets a hit */
                    123:                monsthits();
                    124:            else
                    125:                /* player gets a hit */
                    126:                {
                    127:                firsthit = FALSE;
                    128:                playerhits();
                    129:                }
                    130: 
                    131:            refresh();
                    132: 
                    133:            if (Lines > LINES - 2)
                    134:                /* near bottom of screen - pause */
                    135:                {
                    136:                more(Lines);
                    137:                move(Lines = 8, 0);
                    138:                clrtobot();
                    139:                }
                    140: 
                    141:            if (Player.p_energy <= 0.0)
                    142:                /* player died */
                    143:                {
                    144:                more(Lines);
                    145:                death(Enemyname);
                    146:                cancelmonster();
                    147:                break;          /* fight ends if the player is saved from death */
                    148:                }
                    149: 
                    150:            if (Curmonster.m_energy <= 0.0)
                    151:                /* monster died */
                    152:                break;
                    153:            }
                    154: 
                    155:     /* give player credit for killing monster */
                    156:     Player.p_experience += Curmonster.m_experience;
                    157: 
                    158:     if (drandom() < Curmonster.m_flock / 100.0)
                    159:        /* monster flocks */
                    160:        {
                    161:        more(Lines);
                    162:        ++flockcnt;
                    163:        longjmp(Fightenv, 0);
                    164:        /*NOTREACHED*/
                    165:        }
                    166:     else if (Circle > 1.0
                    167:        && Curmonster.m_treasuretype > 0
                    168:        && drandom() > 0.2 + pow(0.4, (double) (flockcnt / 3 + Circle / 3.0)))
                    169:        /* monster has treasure; this takes # of flocks and size into account */
                    170:        {
                    171:        more(Lines);
                    172:        awardtreasure();
                    173:        }
                    174: 
                    175:     /* pause before returning */
                    176:     getyx(stdscr, Lines, flockcnt);
                    177:     more(Lines + 1);
                    178: 
                    179:     Player.p_ring.ring_inuse = FALSE;  /* not using ring */
                    180: 
                    181:     /* clean up the screen */
                    182:     move(4, 0);
                    183:     clrtobot();
                    184: }
                    185: /**/
                    186: /************************************************************************
                    187: /
                    188: / FUNCTION NAME: pickmonster()
                    189: /
                    190: / FUNCTION: choose a monster based upon where we are
                    191: /
                    192: / AUTHOR: E. A. Estes, 2/20/86
                    193: /
                    194: / ARGUMENTS: none
                    195: /
                    196: / RETURN VALUE: monster number to call
                    197: /
                    198: / MODULES CALLED: floor(), drandom()
                    199: /
                    200: / GLOBAL INPUTS: Marsh, Circle, Player
                    201: /
                    202: / GLOBAL OUTPUTS: none
                    203: /
                    204: / DESCRIPTION:
                    205: /      Certain monsters can be found in certain areas of the grid.
                    206: /      We take care of rolling them here.
                    207: /      Unfortunately, this routine assumes that the monster data
                    208: /      base is arranged in a particular order.  If the data base
                    209: /      is altered (to add monsters, or make them tougher), this
                    210: /      routine may also need to be changed.
                    211: /
                    212: /************************************************************************/
                    213: 
                    214: pickmonster()
                    215: {
                    216:     if (Player.p_specialtype == SC_VALAR)
                    217:        /* even chance of any monster */
                    218:        return((int) ROLL(0.0, 100.0));
                    219: 
                    220:     if (Marsh)
                    221:        /* water monsters */
                    222:        return((int) ROLL(0.0, 15.0));
                    223: 
                    224:     else if (Circle > 24)
                    225:        /* even chance of all non-water monsters */
                    226:        return((int) ROLL(14.0, 86.0));
                    227: 
                    228:     else if (Circle > 15)
                    229:        /* chance of all non-water monsters, weighted toward middle */
                    230:        return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 37.0)));
                    231: 
                    232:     else if (Circle > 8)
                    233:        /* not all non-water monsters, weighted toward middle */
                    234:        return((int) (ROLL(0.0, 50.0) + ROLL(14.0, 26.0)));
                    235: 
                    236:     else if (Circle > 3)
                    237:        /* even chance of some tamer non-water monsters */
                    238:        return((int) ROLL(14.0, 50.0));
                    239: 
                    240:     else 
                    241:        /* even chance of some of the tamest non-water monsters */
                    242:        return((int) ROLL(14.0, 25.0));
                    243: }
                    244: /**/
                    245: /************************************************************************
                    246: /
                    247: / FUNCTION NAME: playerhits()
                    248: /
                    249: / FUNCTION: prompt player for action in monster battle, and process
                    250: /
                    251: / AUTHOR: E. A. Estes, 12/4/85
                    252: /
                    253: / ARGUMENTS: none
                    254: /
                    255: / RETURN VALUE: none
                    256: /
                    257: / MODULES CALLED: hitmonster(), throwspell(), inputoption(), cancelmonster(), 
                    258: /      floor(), wmove(), drandom(), altercoordinates(), waddstr(), mvprintw(), 
                    259: /      wclrtoeol(), wclrtobot()
                    260: /
                    261: / GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, Luckout, *Enemyname
                    262: /
                    263: / GLOBAL OUTPUTS: Curmonster, Lines, Player, Luckout
                    264: /
                    265: / DESCRIPTION:
                    266: /      Process all monster battle options.
                    267: /
                    268: /************************************************************************/
                    269: 
                    270: playerhits()
                    271: {
                    272: double inflict;        /* damage inflicted */
                    273: int    ch;             /* input */
                    274: 
                    275:     mvaddstr(7, 0, "1:Melee  2:Skirmish  3:Evade  4:Spell  5:Nick  ");
                    276: 
                    277:     if (!Luckout)
                    278:        /* haven't tried to luckout yet */
                    279:        if (Curmonster.m_type == SM_MORGOTH)
                    280:            /* cannot luckout against Morgoth */
                    281:            addstr("6:Ally  ");
                    282:        else
                    283:            addstr("6:Luckout  ");
                    284: 
                    285:     if (Player.p_ring.ring_type != R_NONE)
                    286:        /* player has a ring */
                    287:        addstr("7:Use Ring  ");
                    288:     else
                    289:        clrtoeol();
                    290: 
                    291:     ch = inputoption();
                    292: 
                    293:     move(8, 0);
                    294:     clrtobot();                        /* clear any messages from before */
                    295:     Lines = 9;
                    296:     mvaddstr(4, 0, "\n\n");    /* clear status area */
                    297: 
                    298:     switch (ch)
                    299:        {
                    300:        case 'T':               /* timeout; lose turn */
                    301:            break;
                    302: 
                    303:        case ' ':
                    304:        case '1':               /* melee */
                    305:            /* melee affects monster's energy and strength */
                    306:            inflict = ROLL(Player.p_might / 2.0 + 5.0, 1.3 * Player.p_might)
                    307:                + (Player.p_ring.ring_inuse ? Player.p_might : 0.0);
                    308: 
                    309:            Curmonster.m_melee += inflict;
                    310:            Curmonster.m_strength = Curmonster.m_o_strength
                    311:                - Curmonster.m_melee / Curmonster.m_o_energy
                    312:                * Curmonster.m_o_strength / 4.0;
                    313:            hitmonster(inflict);
                    314:            break;
                    315: 
                    316:        case '2':               /* skirmish */
                    317:            /* skirmish affects monter's energy and speed */
                    318:            inflict = ROLL(Player.p_might / 3.0 + 3.0, 1.1 * Player.p_might)
                    319:                + (Player.p_ring.ring_inuse ? Player.p_might : 0.0);
                    320: 
                    321:            Curmonster.m_skirmish += inflict;
                    322:            Curmonster.m_maxspeed = Curmonster.m_o_speed
                    323:                - Curmonster.m_skirmish / Curmonster.m_o_energy
                    324:                * Curmonster.m_o_speed / 4.0;
                    325:            hitmonster(inflict);
                    326:            break;
                    327: 
                    328:        case '3':               /* evade */
                    329:            /* use brains and speed to try to evade */
                    330:            if ((Curmonster.m_type == SM_DARKLORD
                    331:                || Curmonster.m_type == SM_SHRIEKER
                    332:                /* can always run from D. L. and shrieker */
                    333:                || drandom() * Player.p_speed * Player.p_brains
                    334:                    > drandom() * Curmonster.m_speed * Curmonster.m_brains)
                    335:                && (Curmonster.m_type != SM_MIMIC))
                    336:                /* cannot run from mimic */
                    337:                {
                    338:                mvaddstr(Lines++, 0, "You got away!");
                    339:                cancelmonster();
                    340:                altercoordinates(0.0, 0.0, A_NEAR);
                    341:                }
                    342:            else
                    343:                mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
                    344: 
                    345:            break;
                    346: 
                    347:        case 'M':
                    348:        case '4':               /* magic spell */
                    349:            throwspell();
                    350:            break;
                    351: 
                    352:        case '5':               /* nick */
                    353:            /* hit 1 plus sword; give some experience */
                    354:            inflict = 1.0 + Player.p_sword;
                    355:            Player.p_experience += floor(Curmonster.m_experience / 10.0);
                    356:            Curmonster.m_experience *= 0.92;
                    357:            /* monster gets meaner */
                    358:            Curmonster.m_maxspeed += 2.0;
                    359:            Curmonster.m_speed = (Curmonster.m_speed < 0.0) ? 0.0 : Curmonster.m_speed + 2.0;
                    360:            if (Curmonster.m_type == SM_DARKLORD)
                    361:                /* Dark Lord; doesn't like to be nicked */
                    362:                {
                    363:                mvprintw(Lines++, 0,
                    364:                    "You hit %s %.0f times, and made him mad!", Enemyname, inflict);
                    365:                Player.p_quickness /= 2.0;
                    366:                altercoordinates(0.0, 0.0, A_FAR);
                    367:                cancelmonster();
                    368:                }
                    369:            else
                    370:                hitmonster(inflict);
                    371:            break;
                    372: 
                    373:        case 'B':
                    374:        case '6':       /* luckout */
                    375:            if (Luckout)
                    376:                mvaddstr(Lines++, 0, "You already tried that.");
                    377:            else
                    378:                {
                    379:                Luckout = TRUE;
                    380:                if (Curmonster.m_type == SM_MORGOTH)
                    381:                    /* Morgoth; ally */
                    382:                    {
                    383:                    if (drandom() < Player.p_sin / 100.0)
                    384:                        {
                    385:                        mvprintw(Lines++, 0, "%s accepted!", Enemyname);
                    386:                        cancelmonster();
                    387:                        }
                    388:                    else
                    389:                        mvaddstr(Lines++, 0, "Nope, he's not interested.");
                    390:                    }
                    391:                else
                    392:                    /* normal monster; use brains for success */
                    393:                    {
                    394:                    if ((drandom() + 0.333) * Player.p_brains
                    395:                        < (drandom() + 0.333) * Curmonster.m_brains)
                    396:                        mvprintw(Lines++, 0, "You blew it, %s.", Player.p_name);
                    397:                    else
                    398:                        {
                    399:                        mvaddstr(Lines++, 0, "You made it!");
                    400:                        Curmonster.m_energy = 0.0;
                    401:                        }
                    402:                    }
                    403:                }
                    404:            break;
                    405: 
                    406:        case '7':               /* use ring */
                    407:            if (Player.p_ring.ring_type != R_NONE)
                    408:                {
                    409:                mvaddstr(Lines++, 0, "Now using ring.");
                    410:                Player.p_ring.ring_inuse = TRUE;
                    411:                if (Player.p_ring.ring_type != R_DLREG)
                    412:                    /* age ring */
                    413:                    --Player.p_ring.ring_duration;
                    414:                }
                    415:            break;
                    416:        }
                    417: 
                    418: }
                    419: /**/
                    420: /************************************************************************
                    421: /
                    422: / FUNCTION NAME: monsthits()
                    423: /
                    424: / FUNCTION: process a monster hitting the player
                    425: /
                    426: / AUTHOR: E. A. Estes, 12/4/85
                    427: /
                    428: / ARGUMENTS: none
                    429: /
                    430: / RETURN VALUE: none
                    431: /
                    432: / MODULES CALLED: cancelmonster(), scramblestats(), more(), floor(), wmove(), 
                    433: /      drandom(), altercoordinates(), longjmp(), waddstr(), mvprintw(), 
                    434: /      getanswer()
                    435: /
                    436: / GLOBAL INPUTS: Curmonster, Lines, Circle, Shield, Player, *stdscr, 
                    437: /      Fightenv[], *Enemyname
                    438: /
                    439: / GLOBAL OUTPUTS: Curmonster, Whichmonster, Lines, Shield, Player, 
                    440: /      *Enemyname
                    441: /
                    442: / DESCRIPTION:
                    443: /      Handle all special monsters here.  If the monster is not a special
                    444: /      one, simply roll a hit against the player.
                    445: /
                    446: /************************************************************************/
                    447: 
                    448: monsthits()
                    449: {
                    450: double inflict;                /* damage inflicted */
                    451: int    ch;                     /* input */
                    452: 
                    453:     switch (Curmonster.m_type)
                    454:        /* may be a special monster */
                    455:        {
                    456:        case SM_DARKLORD:
                    457:            /* hits just enough to kill player */
                    458:            inflict = (Player.p_energy + Shield) * 1.02;
                    459:            goto SPECIALHIT;
                    460: 
                    461:        case SM_SHRIEKER:
                    462:            /* call a big monster */
                    463:            mvaddstr(Lines++, 0,
                    464:                "Shrieeeek!!  You scared it, and it called one of its friends.");
                    465:            more(Lines);
                    466:            Whichmonster = (int) ROLL(70.0, 30.0);
                    467:            longjmp(Fightenv, 0);
                    468:            /*NOTREACHED*/
                    469: 
                    470:        case SM_BALROG:
                    471:            /* take experience away */
                    472:            inflict = ROLL(10.0, Curmonster.m_strength);
                    473:            inflict = MIN(Player.p_experience, inflict);
                    474:            mvprintw(Lines++, 0, 
                    475:                "%s took away %.0f experience points.", Enemyname, inflict);
                    476:            Player.p_experience -= inflict;
                    477:            return;
                    478: 
                    479:        case SM_FAERIES:
                    480:            if (Player.p_holywater > 0)
                    481:                /* holy water kills when monster tries to hit */
                    482:                {
                    483:                mvprintw(Lines++, 0, "Your holy water killed it!");
                    484:                --Player.p_holywater;
                    485:                Curmonster.m_energy = 0.0;
                    486:                return;
                    487:                }
                    488:            break;
                    489: 
                    490:        case SM_NONE:
                    491:            /* normal hit */
                    492:            break;
                    493: 
                    494:        default:
                    495:            if (drandom() > 0.2)
                    496:                /* normal hit */
                    497:                break;
                    498: 
                    499:            /* else special things */
                    500:            switch (Curmonster.m_type)
                    501:                {
                    502:                case SM_LEANAN:
                    503:                    /* takes some of the player's strength */
                    504:                    inflict = ROLL(1.0, (Circle - 1.0) / 2.0);
                    505:                    inflict = MIN(Player.p_strength, inflict);
                    506:                    mvprintw(Lines++, 0, "%s sapped %0.f of your strength!",
                    507:                        Enemyname, inflict);
                    508:                    Player.p_strength -= inflict;
                    509:                    Player.p_might -= inflict;
                    510:                    break;
                    511: 
                    512:                case SM_SARUMAN:
                    513:                    if (Player.p_palantir)
                    514:                        /* take away palantir */
                    515:                        {
                    516:                        mvprintw(Lines++, 0, "Wormtongue stole your palantir!");
                    517:                        Player.p_palantir = FALSE;
                    518:                        }
                    519:                    else if (drandom() > 0.5)
                    520:                        /* gems turn to gold */
                    521:                        {
                    522:                        mvprintw(Lines++, 0,
                    523:                            "%s transformed your gems into gold!", Enemyname);
                    524:                        Player.p_gold += Player.p_gems;
                    525:                        Player.p_gems = 0.0;
                    526:                        }
                    527:                    else
                    528:                        /* scramble some stats */
                    529:                        {
                    530:                        mvprintw(Lines++, 0, "%s scrambled your stats!", Enemyname);
                    531:                        scramblestats();
                    532:                        }
                    533:                    break;
                    534: 
                    535:                case SM_THAUMATURG:
                    536:                    /* transport player */
                    537:                    mvprintw(Lines++, 0, "%s transported you!", Enemyname);
                    538:                    altercoordinates(0.0, 0.0, A_FAR);
                    539:                    cancelmonster();
                    540:                    break;
                    541: 
                    542:                case SM_VORTEX:
                    543:                    /* suck up some mana */
                    544:                    inflict = ROLL(0, 7.5 * Circle);
                    545:                    inflict = MIN(Player.p_mana, floor(inflict));
                    546:                    mvprintw(Lines++, 0,
                    547:                        "%s sucked up %.0f of your mana!", Enemyname, inflict);
                    548:                    Player.p_mana -= inflict;
                    549:                    break;
                    550: 
                    551:                case SM_NAZGUL:
                    552:                    /* try to take ring if player has one */
                    553:                    if (Player.p_ring.ring_type != R_NONE)
                    554:                        /* player has a ring */
                    555:                        {
                    556:                        mvaddstr(Lines++, 0, "Will you relinguish your ring ? ");
                    557:                        ch = getanswer("YN", FALSE);
                    558:                        if (ch == 'Y')
                    559:                            /* take ring away */
                    560:                            {
                    561:                            Player.p_ring.ring_type = R_NONE;
                    562:                            Player.p_ring.ring_inuse = FALSE;
                    563:                            cancelmonster();
                    564:                            break;
                    565:                            }
                    566:                        }
                    567: 
                    568:                    /* otherwise, take some brains */
                    569:                    mvprintw(Lines++, 0,
                    570:                        "%s neutralized 1/5 of your brain!", Enemyname);
                    571:                    Player.p_brains *= 0.8;
                    572:                    break;
                    573: 
                    574:                case SM_TIAMAT:
                    575:                    /* take some gold and gems */
                    576:                    mvprintw(Lines++, 0,
                    577:                        "%s took half your gold and gems and flew off.", Enemyname);
                    578:                    Player.p_gold /= 2.0;
                    579:                    Player.p_gems /= 2.0;
                    580:                    cancelmonster();
                    581:                    break;
                    582: 
                    583:                case SM_KOBOLD:
                    584:                    /* steal a gold piece and run */
                    585:                    mvprintw(Lines++, 0,
                    586:                        "%s stole one gold piece and ran away.", Enemyname);
                    587:                    Player.p_gold = MAX(0.0, Player.p_gold - 1.0);
                    588:                    cancelmonster();
                    589:                    break;
                    590: 
                    591:                case SM_SHELOB:
                    592:                    /* bite and (medium) poison */
                    593:                    mvprintw(Lines++, 0,
                    594:                        "%s has bitten and poisoned you!", Enemyname);
                    595:                    Player.p_poison -= 1.0;
                    596:                    break;
                    597: 
                    598:                case SM_LAMPREY:
                    599:                    /*  bite and (small) poison */
                    600:                    mvprintw(Lines++, 0, "%s bit and poisoned you!", Enemyname);
                    601:                    Player.p_poison += 0.25;
                    602:                    break;
                    603: 
                    604:                case SM_BONNACON:
                    605:                    /* fart and run */
                    606:                    mvprintw(Lines++, 0, "%s farted and scampered off.", Enemyname);
                    607:                    Player.p_energy /= 2.0;             /* damage from fumes */
                    608:                    cancelmonster();
                    609:                    break;
                    610: 
                    611:                case SM_SMEAGOL:
                    612:                    if (Player.p_ring.ring_type != R_NONE)
                    613:                        /* try to steal ring */
                    614:                        {
                    615:                        mvprintw(Lines++, 0,
                    616:                            "%s tried to steal your ring, ", Enemyname);
                    617:                        if (drandom() > 0.1)
                    618:                            addstr("but was unsuccessful.");
                    619:                        else
                    620:                            {
                    621:                            addstr("and ran away with it!");
                    622:                            Player.p_ring.ring_type = R_NONE;
                    623:                            cancelmonster();
                    624:                            }
                    625:                        }
                    626:                    break;
                    627: 
                    628:                case SM_SUCCUBUS:
                    629:                    /* inflict damage through shield */
                    630:                    inflict = ROLL(15.0, Circle * 10.0);
                    631:                    inflict = MIN(inflict, Player.p_energy);
                    632:                    mvprintw(Lines++, 0, "%s sapped %.0f of your energy.",
                    633:                        Enemyname, inflict);
                    634:                    Player.p_energy -= inflict;
                    635:                    break;
                    636: 
                    637:                case SM_CERBERUS:
                    638:                    /* take all metal treasures */
                    639:                    mvprintw(Lines++, 0,
                    640:                        "%s took all your metal treasures!", Enemyname);
                    641:                    Player.p_crowns = 0;
                    642:                    Player.p_sword =
                    643:                    Player.p_shield =
                    644:                    Player.p_gold = 0.0;
                    645:                    cancelmonster();
                    646:                    break;
                    647: 
                    648:                case SM_UNGOLIANT:
                    649:                    /* (large) poison and take a quickness */
                    650:                    mvprintw(Lines++, 0,
                    651:                        "%s poisoned you, and took one quik.", Enemyname);
                    652:                    Player.p_poison += 5.0;
                    653:                    Player.p_quickness -= 1.0;
                    654:                    break;
                    655: 
                    656:                case SM_JABBERWOCK:
                    657:                    /* fly away, and leave either a Jubjub bird or Bonnacon */
                    658:                    mvprintw(Lines++, 0,
                    659:                        "%s flew away, and left you to contend with one of its friends.",
                    660:                        Enemyname);
                    661:                    Whichmonster = 55 + (drandom() > 0.5) ? 22 : 0;
                    662:                    longjmp(Fightenv, 0);
                    663:                    /*NOTREACHED*/
                    664: 
                    665:                case SM_TROLL:
                    666:                    /* partially regenerate monster */
                    667:                    mvprintw(Lines++, 0,
                    668:                        "%s partially regenerated his energy.!", Enemyname);
                    669:                    Curmonster.m_energy +=
                    670:                        floor((Curmonster.m_o_energy - Curmonster.m_energy) / 2.0);
                    671:                    Curmonster.m_strength = Curmonster.m_o_strength;
                    672:                    Curmonster.m_melee = Curmonster.m_skirmish = 0.0;
                    673:                    Curmonster.m_maxspeed = Curmonster.m_o_speed;
                    674:                    break;
                    675: 
                    676:                case SM_WRAITH:
                    677:                    if (!Player.p_blindness)
                    678:                        /* make blind */
                    679:                        {
                    680:                        mvprintw(Lines++, 0, "%s blinded you!", Enemyname);
                    681:                        Player.p_blindness = TRUE;
                    682:                        Enemyname = "A monster";
                    683:                        }
                    684:                    break;
                    685:                }
                    686:            return;
                    687:        }
                    688: 
                    689:     /* fall through to here if monster inflicts a normal hit */
                    690:     inflict = drandom() * Curmonster.m_strength + 0.5;
                    691: SPECIALHIT:
                    692:     mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, inflict);
                    693: 
                    694:     if ((Shield -= inflict) < 0)
                    695:        {
                    696:        Player.p_energy += Shield;
                    697:        Shield = 0.0;
                    698:        }
                    699: }
                    700: /**/
                    701: /************************************************************************
                    702: /
                    703: / FUNCTION NAME: cancelmonster()
                    704: /
                    705: / FUNCTION: mark current monster as no longer active
                    706: /
                    707: / AUTHOR: E. A. Estes, 12/4/85
                    708: /
                    709: / ARGUMENTS: none
                    710: /
                    711: / RETURN VALUE: none
                    712: /
                    713: / MODULES CALLED: none
                    714: /
                    715: / GLOBAL INPUTS: none
                    716: /
                    717: / GLOBAL OUTPUTS: Curmonster
                    718: /
                    719: / DESCRIPTION:
                    720: /      Clear current monster's energy, experience, treasure type, and
                    721: /      flock.  This is the same as having the monster run away.
                    722: /
                    723: /************************************************************************/
                    724: 
                    725: cancelmonster()
                    726: {
                    727:     Curmonster.m_energy = 0.0;
                    728:     Curmonster.m_experience = 0.0;
                    729:     Curmonster.m_treasuretype = 0;
                    730:     Curmonster.m_flock = 0.0;
                    731: }
                    732: /**/
                    733: /************************************************************************
                    734: /
                    735: / FUNCTION NAME: hitmonster()
                    736: /
                    737: / FUNCTION: inflict damage upon current monster
                    738: /
                    739: / AUTHOR: E. A. Estes, 12/4/85
                    740: /
                    741: / ARGUMENTS:
                    742: /      double inflict - damage to inflict upon monster
                    743: /
                    744: / RETURN VALUE: none
                    745: /
                    746: / MODULES CALLED: monsthits(), wmove(), strcmp(), waddstr(), mvprintw()
                    747: /
                    748: / GLOBAL INPUTS: Curmonster, Lines, Player, *stdscr, *Enemyname
                    749: /
                    750: / GLOBAL OUTPUTS: Curmonster, Lines
                    751: /
                    752: / DESCRIPTION:
                    753: /      Hit monster specified number of times.  Handle when monster dies,
                    754: /      and a few special monsters.
                    755: /
                    756: /************************************************************************/
                    757: 
                    758: hitmonster(inflict)
                    759: double inflict;
                    760: {
                    761:     mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, inflict);
                    762:     Curmonster.m_energy -= inflict;
                    763:     if (Curmonster.m_energy > 0.0)
                    764:        {
                    765:        if (Curmonster.m_type == SM_DARKLORD || Curmonster.m_type == SM_SHRIEKER)
                    766:            /* special monster didn't die */
                    767:            monsthits();
                    768:        }
                    769:     else
                    770:        /* monster died.  print message. */
                    771:        {
                    772:        if (Curmonster.m_type == SM_MORGOTH)
                    773:            mvaddstr(Lines++, 0, "You have defeated Morgoth, but he may return. . .");
                    774:        else
                    775:            /* all other types of monsters */
                    776:            {
                    777:            mvprintw(Lines++, 0, "You killed it.  Good work, %s.", Player.p_name);
                    778: 
                    779:            if (Curmonster.m_type == SM_MIMIC
                    780:                && strcmp(Curmonster.m_name, "A Mimic") != 0
                    781:                && !Player.p_blindness)
                    782:                mvaddstr(Lines++, 0, "The body slowly changes into the form of a mimic.");
                    783:            }
                    784:        }
                    785: }
                    786: /**/
                    787: /************************************************************************
                    788: /
                    789: / FUNCTION NAME: throwspell()
                    790: /
                    791: / FUNCTION: throw a magic spell
                    792: /
                    793: / AUTHOR: E. A. Estes, 12/4/85
                    794: /
                    795: / ARGUMENTS: none
                    796: /
                    797: / RETURN VALUE: none
                    798: /
                    799: / MODULES CALLED: hitmonster(), cancelmonster(), sqrt(), floor(), wmove(), 
                    800: /      drandom(), altercoordinates(), longjmp(), infloat(), waddstr(), mvprintw(), 
                    801: /      getanswer()
                    802: /
                    803: / GLOBAL INPUTS: Curmonster, Whichmonster, Nomana[], Player, *stdscr, 
                    804: /      Fightenv[], Illspell[], *Enemyname
                    805: /
                    806: / GLOBAL OUTPUTS: Curmonster, Whichmonster, Shield, Player
                    807: /
                    808: / DESCRIPTION:
                    809: /      Prompt player and process magic spells.
                    810: /
                    811: /************************************************************************/
                    812: 
                    813: throwspell()
                    814: {
                    815: double inflict;        /* damage inflicted */
                    816: double dtemp;          /* for dtemporary calculations */
                    817: int    ch;             /* input */
                    818: 
                    819:     mvaddstr(7, 0, "\n\n");            /* clear menu area */
                    820: 
                    821:     if (Player.p_magiclvl >= ML_ALLORNOTHING)
                    822:        mvaddstr(7, 0, "1:All or Nothing  ");
                    823:     if (Player.p_magiclvl >= ML_MAGICBOLT)
                    824:        addstr("2:Magic Bolt  ");
                    825:     if (Player.p_magiclvl >= ML_FORCEFIELD)
                    826:        addstr("3:Force Field  ");
                    827:     if (Player.p_magiclvl >= ML_XFORM)
                    828:        addstr("4:Transform  ");
                    829:     if (Player.p_magiclvl >= ML_INCRMIGHT)
                    830:        addstr("5:Increase Might\n");
                    831:     if (Player.p_magiclvl >= ML_INVISIBLE)
                    832:        mvaddstr(8, 0, "6:Invisibility  ");
                    833:     if (Player.p_magiclvl >= ML_XPORT)
                    834:        addstr("7:Transport  ");
                    835:     if (Player.p_magiclvl >= ML_PARALYZE)
                    836:        addstr("8:Paralyze  ");
                    837:     if (Player.p_specialtype >= SC_COUNCIL)
                    838:        addstr("9:Specify");
                    839:     mvaddstr(4, 0, "Spell ? ");
                    840: 
                    841:     ch = getanswer(" ", TRUE);
                    842: 
                    843:     mvaddstr(7, 0, "\n\n");            /* clear menu area */
                    844: 
                    845:     if (Curmonster.m_type == SM_MORGOTH && ch != '3')
                    846:        /* can only throw force field against Morgoth */
                    847:        ILLSPELL();
                    848:     else
                    849:        switch (ch)
                    850:            {
                    851:            case '1':   /* all or nothing */
                    852:                if (drandom() < 0.25)
                    853:                    /* success */
                    854:                    {
                    855:                    inflict = Curmonster.m_energy * 1.01 + 1.0;
                    856: 
                    857:                    if (Curmonster.m_type == SM_DARKLORD)
                    858:                        /* all or nothing doesn't quite work against D. L. */
                    859:                        inflict *= 0.9;
                    860:                    }
                    861:                else
                    862:                    /* failure -- monster gets stronger and quicker */
                    863:                    {
                    864:                    Curmonster.m_o_strength = Curmonster.m_strength *= 2.0;
                    865:                    Curmonster.m_maxspeed *= 2.0;
                    866:                    Curmonster.m_o_speed *= 2.0;
                    867: 
                    868:                    /* paralyzed monsters wake up a bit */
                    869:                    Curmonster.m_speed = MAX(1.0, Curmonster.m_speed * 2.0);
                    870:                    }
                    871: 
                    872:                if (Player.p_mana >= MM_ALLORNOTHING)
                    873:                    /* take a mana if player has one */
                    874:                    Player.p_mana -= MM_ALLORNOTHING;
                    875: 
                    876:                hitmonster(inflict);
                    877:                break;
                    878: 
                    879:            case '2':   /* magic bolt */
                    880:                if (Player.p_magiclvl < ML_MAGICBOLT)
                    881:                    ILLSPELL();
                    882:                else
                    883:                    {
                    884:                    do
                    885:                        /* prompt for amount to expend */
                    886:                        {
                    887:                        mvaddstr(4, 0, "How much mana for bolt? ");
                    888:                        dtemp = floor(infloat());
                    889:                        }
                    890:                    while (dtemp < 0.0 || dtemp > Player.p_mana);
                    891: 
                    892:                    Player.p_mana -= dtemp;
                    893: 
                    894:                    if (Curmonster.m_type == SM_DARKLORD)
                    895:                        /* magic bolts don't work against D. L. */
                    896:                        inflict = 0.0;
                    897:                    else
                    898:                        inflict = dtemp * ROLL(15.0, sqrt(Player.p_magiclvl / 3.0 + 1.0));
                    899:                    mvaddstr(5, 0, "Magic Bolt fired!\n");
                    900:                    hitmonster(inflict);
                    901:                    }
                    902:                break;
                    903: 
                    904:            case '3':   /* force field */
                    905:                if (Player.p_magiclvl < ML_FORCEFIELD)
                    906:                    ILLSPELL();
                    907:                else if (Player.p_mana < MM_FORCEFIELD)
                    908:                    NOMANA();
                    909:                else
                    910:                    {
                    911:                    Player.p_mana -= MM_FORCEFIELD;
                    912:                    Shield = (Player.p_maxenergy + Player.p_shield) * 4.2 + 45.0;
                    913:                    mvaddstr(5, 0, "Force Field up.\n");
                    914:                    }
                    915:                break;
                    916: 
                    917:            case '4':   /* transform */
                    918:                if (Player.p_magiclvl < ML_XFORM)
                    919:                    ILLSPELL();
                    920:                else if (Player.p_mana < MM_XFORM)
                    921:                    NOMANA();
                    922:                else
                    923:                    {
                    924:                    Player.p_mana -= MM_XFORM;
                    925:                    Whichmonster = (int) ROLL(0.0, 100.0);
                    926:                    longjmp(Fightenv, 0);
                    927:                    /*NOTREACHED*/
                    928:                    }
                    929:                break;
                    930: 
                    931:            case '5':   /* increase might */
                    932:                if (Player.p_magiclvl < ML_INCRMIGHT)
                    933:                    ILLSPELL();
                    934:                else if (Player.p_mana < MM_INCRMIGHT)
                    935:                    NOMANA();
                    936:                else
                    937:                    {
                    938:                    Player.p_mana -= MM_INCRMIGHT;
                    939:                    Player.p_might +=
                    940:                        (1.2 * (Player.p_strength + Player.p_sword)
                    941:                        + 5.0 - Player.p_might) / 2.0;
                    942:                    mvprintw(5, 0, "New strength:  %.0f\n", Player.p_might);
                    943:                    }
                    944:                break;
                    945: 
                    946:            case '6':   /* invisible */
                    947:                if (Player.p_magiclvl < ML_INVISIBLE)
                    948:                    ILLSPELL();
                    949:                else if (Player.p_mana < MM_INVISIBLE)
                    950:                    NOMANA();
                    951:                else
                    952:                    {
                    953:                    Player.p_mana -= MM_INVISIBLE;
                    954:                    Player.p_speed +=
                    955:                        (1.2 * (Player.p_quickness + Player.p_quksilver)
                    956:                        + 5.0 - Player.p_speed) / 2.0;
                    957:                    mvprintw(5, 0, "New quickness:  %.0f\n", Player.p_speed);
                    958:                    }
                    959:                break;
                    960: 
                    961:            case '7':   /* transport */
                    962:                if (Player.p_magiclvl < ML_XPORT)
                    963:                    ILLSPELL();
                    964:                else if (Player.p_mana < MM_XPORT)
                    965:                    NOMANA();
                    966:                else
                    967:                    {
                    968:                    Player.p_mana -= MM_XPORT;
                    969:                    if (Player.p_brains + Player.p_magiclvl
                    970:                        < Curmonster.m_experience / 200.0 * drandom())
                    971:                        {
                    972:                        mvaddstr(5, 0, "Transport backfired!\n");
                    973:                        altercoordinates(0.0, 0.0, A_FAR);
                    974:                        cancelmonster();
                    975:                        }
                    976:                    else
                    977:                        {
                    978:                        mvprintw(5, 0, "%s is transported.\n", Enemyname);
                    979:                        if (drandom() < 0.3)
                    980:                            /* monster didn't drop its treasure */
                    981:                            Curmonster.m_treasuretype = 0;
                    982: 
                    983:                        Curmonster.m_energy = 0.0;
                    984:                        }
                    985:                    }
                    986:                break;
                    987: 
                    988:            case '8':   /* paralyze */
                    989:                if (Player.p_magiclvl < ML_PARALYZE)
                    990:                    ILLSPELL();
                    991:                else if (Player.p_mana < MM_PARALYZE)
                    992:                    NOMANA();
                    993:                else
                    994:                    {
                    995:                    Player.p_mana -= MM_PARALYZE;
                    996:                    if (Player.p_magiclvl >
                    997:                        Curmonster.m_experience / 1000.0 * drandom())
                    998:                        {
                    999:                        mvprintw(5, 0, "%s is held.\n", Enemyname);
                   1000:                        Curmonster.m_speed = -2.0;
                   1001:                        }
                   1002:                    else
                   1003:                        mvaddstr(5, 0, "Monster unaffected.\n");
                   1004:                    }
                   1005:                break;
                   1006: 
                   1007:            case '9':   /* specify */
                   1008:                if (Player.p_specialtype < SC_COUNCIL)
                   1009:                    ILLSPELL();
                   1010:                else if (Player.p_mana < MM_SPECIFY)
                   1011:                    NOMANA();
                   1012:                else
                   1013:                    {
                   1014:                    Player.p_mana -= MM_SPECIFY;
                   1015:                    mvaddstr(5, 0, "Which monster do you want [0-99] ? ");
                   1016:                    Whichmonster = (int) infloat();
                   1017:                    Whichmonster = MAX(0, MIN(99, Whichmonster));
                   1018:                    longjmp(Fightenv, 0);
                   1019:                    /*NOTREACHED*/
                   1020:                    }
                   1021:                break;
                   1022:            }
                   1023: }
                   1024: /**/
                   1025: /************************************************************************
                   1026: /
                   1027: / FUNCTION NAME: callmonster()
                   1028: /
                   1029: / FUNCTION: read monster from file, and fill structure
                   1030: /
                   1031: / AUTHOR: E. A. Estes, 2/25/86
                   1032: /
                   1033: / ARGUMENTS:
                   1034: /      int which - which monster to call
                   1035: /
                   1036: / RETURN VALUE: none
                   1037: /
                   1038: / MODULES CALLED: truncstring(), fread(), fseek(), floor(), drandom(), 
                   1039: /      strcpy()
                   1040: /
                   1041: / GLOBAL INPUTS: Curmonster, Circle, Player, *Monstfp
                   1042: /
                   1043: / GLOBAL OUTPUTS: Curmonster, Player, *Enemyname
                   1044: /
                   1045: / DESCRIPTION:
                   1046: /      Read specified monster from monster database and fill up
                   1047: /      current monster structure.
                   1048: /      Adjust statistics based upon current size.
                   1049: /      Handle some special monsters.
                   1050: /
                   1051: /************************************************************************/
                   1052: 
                   1053: callmonster(which)
                   1054: int    which;
                   1055: {
                   1056: struct monster Othermonster;           /* to find a name for mimics */
                   1057: 
                   1058:     which = MIN(which, 99);            /* make sure within range */
                   1059: 
                   1060:     /* fill structure */
                   1061:     fseek(Monstfp, (long) which * (long) SZ_MONSTERSTRUCT, 0);
                   1062:     fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
                   1063: 
                   1064:     /* handle some special monsters */
                   1065:     if (Curmonster.m_type == SM_MODNAR)
                   1066:        {
                   1067:        if (Player.p_specialtype < SC_COUNCIL)
                   1068:            /* randomize some stats */
                   1069:            {
                   1070:            Curmonster.m_strength *= drandom() + 0.5;
                   1071:            Curmonster.m_brains *= drandom() + 0.5;
                   1072:            Curmonster.m_speed *= drandom() + 0.5;
                   1073:            Curmonster.m_energy *= drandom() + 0.5;
                   1074:            Curmonster.m_experience *= drandom() + 0.5;
                   1075:            Curmonster.m_treasuretype =
                   1076:                (int) ROLL(0.0, (double) Curmonster.m_treasuretype);
                   1077:            }
                   1078:        else
                   1079:            /* make Modnar into Morgoth */
                   1080:            {
                   1081:            strcpy(Curmonster.m_name, "Morgoth");
                   1082:            Curmonster.m_strength = drandom() * (Player.p_maxenergy + Player.p_shield) / 1.4
                   1083:                + drandom() * (Player.p_maxenergy + Player.p_shield) / 1.5;
                   1084:            Curmonster.m_brains = Player.p_brains;
                   1085:            Curmonster.m_energy = Player.p_might * 30.0;
                   1086:            Curmonster.m_type = SM_MORGOTH;
                   1087:            Curmonster.m_speed = Player.p_speed * 1.1
                   1088:                + (Player.p_specialtype == SC_EXVALAR) ? Player.p_speed : 0.0;
                   1089:            Curmonster.m_flock = 0.0;
                   1090:            Curmonster.m_treasuretype = 0;
                   1091:            Curmonster.m_experience = 0.0;
                   1092:            }
                   1093:        }
                   1094:     else if (Curmonster.m_type == SM_MIMIC)
                   1095:        /* pick another name */
                   1096:        {
                   1097:        which = (int) ROLL(0.0, 100.0);
                   1098:        fseek(Monstfp, (long) which * (long) SZ_MONSTERSTRUCT, 0);
                   1099:        fread(&Othermonster, SZ_MONSTERSTRUCT, 1, Monstfp);
                   1100:        strcpy(Curmonster.m_name, Othermonster.m_name);
                   1101:        }
                   1102: 
                   1103:     truncstring(Curmonster.m_name);
                   1104: 
                   1105:     if (Curmonster.m_type != SM_MORGOTH)
                   1106:        /* adjust stats based on which circle player is in */
                   1107:        {
                   1108:        Curmonster.m_strength *= (1.0 + Circle / 2.0);
                   1109:        Curmonster.m_brains *= Circle;
                   1110:        Curmonster.m_speed += Circle * 1.e-9;
                   1111:        Curmonster.m_energy *= Circle;
                   1112:        Curmonster.m_experience *= Circle;
                   1113:        }
                   1114: 
                   1115:     if (Player.p_blindness)
                   1116:        /* cannot see monster if blind */
                   1117:        Enemyname = "A monster";
                   1118:     else
                   1119:        Enemyname = Curmonster.m_name;
                   1120: 
                   1121:     if (Player.p_speed <= 0.0)
                   1122:        /* make Player.p_speed positive */
                   1123:        {
                   1124:        Curmonster.m_speed += -Player.p_speed;
                   1125:        Player.p_speed = 1.0;
                   1126:        }
                   1127: 
                   1128:     /* fill up the rest of the structure */
                   1129:     Curmonster.m_o_strength = Curmonster.m_strength;
                   1130:     Curmonster.m_o_speed = Curmonster.m_maxspeed = Curmonster.m_speed;
                   1131:     Curmonster.m_o_energy = Curmonster.m_energy;
                   1132:     Curmonster.m_melee = Curmonster.m_skirmish = 0.0;
                   1133: }
                   1134: /**/
                   1135: /************************************************************************
                   1136: /
                   1137: / FUNCTION NAME: awardtreasure()
                   1138: /
                   1139: / FUNCTION: select a treasure
                   1140: /
                   1141: / AUTHOR: E. A. Estes, 12/4/85
                   1142: /
                   1143: / ARGUMENTS: none
                   1144: /
                   1145: / RETURN VALUE: none
                   1146: /
                   1147: / MODULES CALLED: pickmonster(), collecttaxes(), more(), cursedtreasure(), 
                   1148: /      floor(), wmove(), drandom(), sscanf(), printw(), altercoordinates(), 
                   1149: /      longjmp(), infloat(), waddstr(), getanswer(), getstring(), wclrtobot()
                   1150: /
                   1151: / GLOBAL INPUTS: Somebetter[], Curmonster, Whichmonster, Circle, Player, 
                   1152: /      *stdscr, Databuf[], *Statptr, Fightenv[]
                   1153: /
                   1154: / GLOBAL OUTPUTS: Whichmonster, Shield, Player
                   1155: /
                   1156: / DESCRIPTION:
                   1157: /      Roll up a treasure based upon monster type and size, and
                   1158: /      certain player statistics.
                   1159: /      Handle cursed treasure.
                   1160: /
                   1161: /************************************************************************/
                   1162: 
                   1163: awardtreasure()
                   1164: {
                   1165: register int   whichtreasure;          /* calculated treasure to grant */
                   1166: int    temp;                           /* temporary */
                   1167: int    ch;                             /* input */
                   1168: double treasuretype;                   /* monster's treasure type */
                   1169: double gold = 0.0;                     /* gold awarded */
                   1170: double gems = 0.0;                     /* gems awarded */
                   1171: double dtemp;                          /* for temporary calculations */
                   1172: 
                   1173:     whichtreasure = (int) ROLL(1.0, 3.0);      /* pick a treasure */
                   1174:     treasuretype = (double) Curmonster.m_treasuretype;
                   1175: 
                   1176:     move(4, 0);
                   1177:     clrtobot();
                   1178:     move(6, 0);
                   1179: 
                   1180:     if (drandom() > 0.65)
                   1181:        /* gold and gems */
                   1182:        {
                   1183:        if (Curmonster.m_treasuretype > 7)
                   1184:            /* gems */
                   1185:            {
                   1186:            gems = ROLL(1.0, (treasuretype - 7.0)
                   1187:                * (treasuretype - 7.0) * (Circle - 1.0) / 4.0);
                   1188:            printw("You have discovered %.0f gems!", gems);
                   1189:            }
                   1190:        else
                   1191:            /* gold */
                   1192:            {
                   1193:            gold = ROLL(treasuretype * 10.0, treasuretype
                   1194:                * treasuretype * 10.0 * (Circle - 1.0));
                   1195:            printw("You have found %.0f gold pieces.", gold);
                   1196:            }
                   1197: 
                   1198:        addstr("  Do you want to pick them up ? ");
                   1199:        ch = getanswer("NY", FALSE);
                   1200:        addstr("\n\n");
                   1201: 
                   1202:        if (ch == 'Y')
                   1203:            if (drandom() < treasuretype / 35.0 + 0.04)
                   1204:                /* cursed */
                   1205:                {
                   1206:                addstr("They were cursed!\n");
                   1207:                cursedtreasure();
                   1208:                }
                   1209:            else
                   1210:                collecttaxes(gold, gems);
                   1211: 
                   1212:        return;
                   1213:        }
                   1214:     else   
                   1215:        /* other treasures */
                   1216:        {
                   1217:        addstr("You have found some treasure.  Do you want to inspect it ? ");
                   1218:        ch = getanswer("NY", FALSE);
                   1219:        addstr("\n\n");
                   1220: 
                   1221:        if (ch != 'Y')
                   1222:            return;
                   1223:        else
                   1224:            if (drandom() < 0.08 && Curmonster.m_treasuretype != 4)
                   1225:                {
                   1226:                addstr("It was cursed!\n");
                   1227:                cursedtreasure();
                   1228:                return;
                   1229:                }
                   1230:            else
                   1231:                switch (Curmonster.m_treasuretype)
                   1232:                    {
                   1233:                    case 1:     /* treasure type 1 */
                   1234:                        switch (whichtreasure)
                   1235:                            {
                   1236:                            case 1:
                   1237:                                addstr("You've discovered a power booster!\n");
                   1238:                                Player.p_mana += ROLL(Circle * 4.0, Circle * 30.0);
                   1239:                                break;
                   1240: 
                   1241:                            case 2:
                   1242:                                addstr("You have encountered a druid.\n");
                   1243:                                Player.p_experience +=
                   1244:                                    ROLL(0.0, 2000.0 + Circle * 400.0);
                   1245:                                break;
                   1246: 
                   1247:                            case 3:
                   1248:                                addstr("You have found a holy orb.\n");
                   1249:                                Player.p_sin = MAX(0.0, Player.p_sin - 0.25);
                   1250:                                break;
                   1251:                            }
                   1252:                        break;
                   1253:                    /* end treasure type 1 */
                   1254: 
                   1255:                    case 2:     /* treasure type 2 */
                   1256:                        switch (whichtreasure)
                   1257:                            {
                   1258:                            case 1:
                   1259:                                addstr("You have found an amulet.\n");
                   1260:                                ++Player.p_amulets;
                   1261:                                break;
                   1262: 
                   1263:                            case 2:
                   1264:                                addstr("You've found some holy water!\n");
                   1265:                                ++Player.p_holywater;
                   1266:                                break;
                   1267: 
                   1268:                            case 3:
                   1269:                                addstr("You've met a hermit!\n");
                   1270:                                Player.p_sin *= 0.75;
                   1271:                                Player.p_mana += 12.0 * Circle;
                   1272:                                break;
                   1273:                            }
                   1274:                        break;
                   1275:                    /* end treasure type 2 */
                   1276: 
                   1277:                    case 3:     /* treasure type 3 */
                   1278:                        switch (whichtreasure)
                   1279:                            {
                   1280:                            case 1:
                   1281:                                dtemp = ROLL(7.0, 30.0 + Circle / 10.0);
                   1282:                                printw("You've found a +%.0f shield!\n", dtemp);
                   1283:                                if (dtemp >= Player.p_shield)
                   1284:                                    Player.p_shield = dtemp;
                   1285:                                else
                   1286:                                    SOMEBETTER();
                   1287:                                break;
                   1288: 
                   1289:                            case 2:
                   1290:                                addstr("You have rescued a virgin.  Will you be honorable ? ");
                   1291:                                ch = getanswer("NY", FALSE);
                   1292:                                addstr("\n\n");
                   1293:                                if (ch == 'Y')
                   1294:                                    Player.p_virgin = TRUE;
                   1295:                                else
                   1296:                                    {
                   1297:                                    Player.p_experience += 2000.0 * Circle;
                   1298:                                    ++Player.p_sin;
                   1299:                                    }
                   1300:                                break;
                   1301: 
                   1302:                            case 3:
                   1303:                                addstr("You've discovered some athelas!\n");
                   1304:                                --Player.p_poison;
                   1305:                                break;
                   1306:                            }
                   1307:                        break;
                   1308:                    /* end treasure type 3 */
                   1309: 
                   1310:                    case 4:     /* treasure type 4 */
                   1311:                        addstr("You've found a scroll.  Will you read it ? ");
                   1312:                        ch = getanswer("NY", FALSE);
                   1313:                        addstr("\n\n");
                   1314: 
                   1315:                        if (ch == 'Y')
                   1316:                            switch ((int) ROLL(1, 6))
                   1317:                                {
                   1318:                                case 1:
                   1319:                                    addstr("It throws up a shield for you next monster.\n");
                   1320:                                    getyx(stdscr, whichtreasure, ch);
                   1321:                                    more(whichtreasure);
                   1322:                                    Shield =
                   1323:                                        (Player.p_maxenergy + Player.p_energy) * 5.5 + Circle * 50.0;
                   1324:                                    Whichmonster = pickmonster();
                   1325:                                    longjmp(Fightenv, 0);
                   1326:                                    /*NOTREACHED*/
                   1327: 
                   1328:                                case 2:
                   1329:                                    addstr("It makes you invisible for you next monster.\n");
                   1330:                                    getyx(stdscr, whichtreasure, ch);
                   1331:                                    more(whichtreasure);
                   1332:                                    Player.p_speed = 1e6;
                   1333:                                    Whichmonster = pickmonster();
                   1334:                                    longjmp(Fightenv, 0);
                   1335:                                    /*NOTREACHED*/
                   1336: 
                   1337:                                case 3:
                   1338:                                    addstr("It increases your strength ten fold to fight your next monster.\n");
                   1339:                                    getyx(stdscr, whichtreasure, ch);
                   1340:                                    more(whichtreasure);
                   1341:                                    Player.p_might *= 10.0;
                   1342:                                    Whichmonster = pickmonster();
                   1343:                                    longjmp(Fightenv, 0);
                   1344:                                    /*NOTREACHED*/
                   1345: 
                   1346:                                case 4:
                   1347:                                    addstr("It is a general knowledge scroll.\n");
                   1348:                                    Player.p_brains += ROLL(2.0, Circle);
                   1349:                                    Player.p_magiclvl += ROLL(1.0, Circle / 2.0);
                   1350:                                    break;
                   1351: 
                   1352:                                case 5:
                   1353:                                    addstr("It tells you how to pick your next monster.\n");
                   1354:                                    addstr("Which monster do you want [0-99] ? ");
                   1355:                                    Whichmonster = (int) infloat();
                   1356:                                    Whichmonster = MIN(99, MAX(0, Whichmonster));
                   1357:                                    longjmp(Fightenv, 0);
                   1358: 
                   1359:                                case 6:
                   1360:                                    addstr("It was cursed!\n");
                   1361:                                    cursedtreasure();
                   1362:                                    break;
                   1363:                                }
                   1364:                            break;
                   1365:                    /* end treasure type 4 */
                   1366: 
                   1367:                    case 5:     /* treasure type 5 */
                   1368:                        switch (whichtreasure)
                   1369:                            {
                   1370:                            case 1:
                   1371:                                dtemp = ROLL(Circle / 4.0 + 5.0, Circle / 2.0 + 9.0);
                   1372:                                printw("You've discovered a +%.0f dagger.\n", dtemp);
                   1373:                                if (dtemp >= Player.p_sword)
                   1374:                                    Player.p_sword = dtemp;
                   1375:                                else
                   1376:                                    SOMEBETTER();
                   1377:                                break;
                   1378: 
                   1379:                            case 2:
                   1380:                                dtemp = ROLL(7.5 + Circle * 3.0, Circle * 2.0 + 160.0);
                   1381:                                printw("You have found some +%.0f armour!\n", dtemp);
                   1382:                                if (dtemp >= Player.p_shield)
                   1383:                                    Player.p_shield = dtemp;
                   1384:                                else
                   1385:                                    SOMEBETTER();
                   1386:                                break;
                   1387: 
                   1388:                            case 3:
                   1389:                                addstr("You've found a tablet.\n");
                   1390:                                Player.p_brains += 4.5 * Circle;
                   1391:                                break;
                   1392:                            }
                   1393:                        break;
                   1394:                    /* end treasure type 5 */
                   1395: 
                   1396:                    case 6:     /* treasure type 6 */
                   1397:                        switch (whichtreasure)
                   1398:                            {
                   1399:                            case 1:
                   1400:                                addstr("You've found a priest.\n");
                   1401:                                Player.p_energy = Player.p_maxenergy + Player.p_shield;
                   1402:                                Player.p_sin /= 2.0;
                   1403:                                Player.p_mana += 24.0 * Circle;
                   1404:                                Player.p_brains += Circle;
                   1405:                                break;
                   1406: 
                   1407:                            case 2:
                   1408:                                addstr("You have come upon Robin Hood!\n");
                   1409:                                Player.p_shield += Circle * 2.0;
                   1410:                                Player.p_strength += Circle / 2.5 + 1.0;
                   1411:                                break;
                   1412: 
                   1413:                            case 3:
                   1414:                                dtemp = ROLL(2.0 + Circle / 4.0, Circle / 1.2 + 10.0);
                   1415:                                printw("You have found a +%.0f axe!\n", dtemp);
                   1416:                                if (dtemp >= Player.p_sword)
                   1417:                                    Player.p_sword = dtemp;
                   1418:                                else
                   1419:                                    SOMEBETTER();
                   1420:                                break;
                   1421:                            }
                   1422:                        break;
                   1423:                    /* end treasure type 6 */
                   1424: 
                   1425:                    case 7:     /* treasure type 7 */
                   1426:                        switch (whichtreasure)
                   1427:                            {
                   1428:                            case 1:
                   1429:                                addstr("You've discovered a charm!\n");
                   1430:                                ++Player.p_charms;
                   1431:                                break;
                   1432: 
                   1433:                            case 2:
                   1434:                                addstr("You have encountered Merlyn!\n");
                   1435:                                Player.p_brains += Circle + 5.0;
                   1436:                                Player.p_magiclvl += Circle / 3.0 + 5.0;
                   1437:                                Player.p_mana += Circle * 10.0;
                   1438:                                break;
                   1439: 
                   1440:                            case 3:
                   1441:                                dtemp = ROLL(5.0 + Circle / 3.0, Circle / 1.5 + 20.0);
                   1442:                                printw("You have found a +%.0f war hammer!\n", dtemp);
                   1443:                                if (dtemp >= Player.p_sword)
                   1444:                                    Player.p_sword = dtemp;
                   1445:                                else
                   1446:                                    SOMEBETTER();
                   1447:                                break;
                   1448:                            }
                   1449:                        break;
                   1450:                    /* end treasure type 7 */
                   1451: 
                   1452:                    case 8:     /* treasure type 8 */
                   1453:                        switch (whichtreasure)
                   1454:                            {
                   1455:                            case 1:
                   1456:                                addstr("You have found a healing potion.\n");
                   1457:                                Player.p_poison = MIN(-2.0, Player.p_poison - 2.0);
                   1458:                                break;
                   1459: 
                   1460:                            case 2:
                   1461:                                addstr("You have discovered a transporter.  Do you wish to go anywhere ? ");
                   1462:                                ch = getanswer("NY", FALSE);
                   1463:                                addstr("\n\n");
                   1464:                                if (ch == 'Y')
                   1465:                                    {
                   1466:                                    double x, y;
                   1467: 
                   1468:                                    addstr("X Y Coordinates ? ");
                   1469:                                    getstring(Databuf, SZ_DATABUF);
                   1470:                                    sscanf(Databuf, "%lf %lf", &x, &y);
                   1471:                                    altercoordinates(x, y, A_FORCED);
                   1472:                                    }
                   1473:                                break;
                   1474: 
                   1475:                            case 3:
                   1476:                                dtemp = ROLL(10.0 + Circle / 1.2, Circle * 3.0 + 30.0);
                   1477:                                printw("You've found a +%.0f sword!\n", dtemp);
                   1478:                                if (dtemp >= Player.p_sword)
                   1479:                                    Player.p_sword = dtemp;
                   1480:                                else
                   1481:                                    SOMEBETTER();
                   1482:                                break;
                   1483:                            }
                   1484:                        break;
                   1485:                    /* end treasure type 8 */
                   1486: 
                   1487:                    case 10:
                   1488:                    case 11:
                   1489:                    case 12:
                   1490:                    case 13:    /* treasure types 10 - 13 */
                   1491:                        if (drandom() < 0.33)
                   1492:                            {
                   1493:                            if (Curmonster.m_treasuretype == 10)
                   1494:                                {
                   1495:                                addstr("You've found a pair of elven boots!\n");
                   1496:                                Player.p_quickness += 2.0;
                   1497:                                break;
                   1498:                                }
                   1499:                            else if (Curmonster.m_treasuretype == 11
                   1500:                                && !Player.p_palantir)
                   1501:                                {
                   1502:                                addstr("You've acquired Saruman's palantir.\n");
                   1503:                                Player.p_palantir = TRUE;
                   1504:                                break;
                   1505:                                }
                   1506:                            else if (Player.p_ring.ring_type == R_NONE
                   1507:                                && Player.p_specialtype < SC_COUNCIL
                   1508:                                && (Curmonster.m_treasuretype == 12
                   1509:                                || Curmonster.m_treasuretype == 13))
                   1510:                                /* roll up a ring */
                   1511:                                {
                   1512:                                if (drandom() < 0.8)
                   1513:                                    /* regular rings */
                   1514:                                    {
                   1515:                                    if (Curmonster.m_treasuretype == 12)
                   1516:                                        {
                   1517:                                        whichtreasure = R_NAZREG;
                   1518:                                        temp = 35;
                   1519:                                        }
                   1520:                                    else
                   1521:                                        {
                   1522:                                        whichtreasure = R_DLREG;
                   1523:                                        temp = 0;
                   1524:                                        }
                   1525:                                    }
                   1526:                                else
                   1527:                                    /* bad rings */
                   1528:                                    {
                   1529:                                    whichtreasure = R_BAD;
                   1530:                                    temp = 15 + Statptr->c_ringduration + (int) ROLL(0,5);
                   1531:                                    }
                   1532: 
                   1533:                                addstr("You've discovered a ring.  Will you pick it up ? ");
                   1534:                                ch = getanswer("NY", FALSE);
                   1535:                                addstr("\n\n");
                   1536: 
                   1537:                                if (ch == 'Y')
                   1538:                                    {
                   1539:                                    Player.p_ring.ring_type = whichtreasure;
                   1540:                                    Player.p_ring.ring_duration = temp;
                   1541:                                    }
                   1542: 
                   1543:                                break;
                   1544:                                }
                   1545:                            }
                   1546:                        /* end treasure types 10 - 13 */
                   1547:                        /* fall through to treasure type 9 if no treasure from above */
                   1548: 
                   1549:                        case 9: /* treasure type 9 */
                   1550:                            switch (whichtreasure)
                   1551:                                {
                   1552:                                case 1:
                   1553:                                    if (Player.p_level <= 1000.0
                   1554:                                        && Player.p_crowns <= 3
                   1555:                                        && Player.p_level >= 10.0)
                   1556:                                        {
                   1557:                                        addstr("You have found a golden crown!\n");
                   1558:                                        ++Player.p_crowns;
                   1559:                                        break;
                   1560:                                        }
                   1561:                                    /* fall through otherwise */
                   1562: 
                   1563:                                case 2:
                   1564:                                    addstr("You've been blessed!\n");
                   1565:                                    Player.p_blessing = TRUE;
                   1566:                                    Player.p_sin /= 3.0;
                   1567:                                    Player.p_energy = Player.p_maxenergy + Player.p_shield;
                   1568:                                    Player.p_mana += 100.0 * Circle;
                   1569:                                    break;
                   1570: 
                   1571:                                case 3:
                   1572:                                    dtemp = ROLL(1.0, Circle / 5.0 + 5.0);
                   1573:                                    dtemp = MIN(dtemp, 99.0);
                   1574:                                    printw("You have discovered some +%.0f quicksilver!\n",dtemp);
                   1575:                                    if (dtemp >= Player.p_quksilver)
                   1576:                                        Player.p_quksilver = dtemp;
                   1577:                                    else
                   1578:                                        SOMEBETTER();
                   1579:                                    break;
                   1580:                                }
                   1581:                            break;
                   1582:                    /* end treasure type 9 */
                   1583:                    }
                   1584:        }
                   1585: }
                   1586: /**/
                   1587: /************************************************************************
                   1588: /
                   1589: / FUNCTION NAME: cursedtreasure()
                   1590: /
                   1591: / FUNCTION: take care of cursed treasure
                   1592: /
                   1593: / AUTHOR: E. A. Estes, 12/4/85
                   1594: /
                   1595: / ARGUMENTS: none
                   1596: /
                   1597: / RETURN VALUE: none
                   1598: /
                   1599: / MODULES CALLED: waddstr()
                   1600: /
                   1601: / GLOBAL INPUTS: Player, *stdscr
                   1602: /
                   1603: / GLOBAL OUTPUTS: Player
                   1604: /
                   1605: / DESCRIPTION:
                   1606: /      Handle cursed treasure.  Look for amulets and charms to save
                   1607: /      the player from the curse.
                   1608: /
                   1609: /************************************************************************/
                   1610: 
                   1611: cursedtreasure()
                   1612: {
                   1613:     if (Player.p_charms > 0)
                   1614:        {
                   1615:        addstr("But your charm saved you!\n");
                   1616:        --Player.p_charms;
                   1617:        }
                   1618:     else if (Player.p_amulets > 0)
                   1619:        {
                   1620:        addstr("But your amulet saved you!\n");
                   1621:        --Player.p_amulets;
                   1622:        }
                   1623:     else
                   1624:        {
                   1625:        Player.p_energy = (Player.p_maxenergy + Player.p_shield) / 10.0;
                   1626:        Player.p_poison += 0.25;
                   1627:        }
                   1628: }
                   1629: /**/
                   1630: /************************************************************************
                   1631: /
                   1632: / FUNCTION NAME: scramblestats()
                   1633: /
                   1634: / FUNCTION: scramble some selected statistics
                   1635: /
                   1636: / AUTHOR: E. A. Estes, 12/4/85
                   1637: /
                   1638: / ARGUMENTS: none
                   1639: /
                   1640: / RETURN VALUE: none
                   1641: /
                   1642: / MODULES CALLED: floor(), drandom()
                   1643: /
                   1644: / GLOBAL INPUTS: Player
                   1645: /
                   1646: / GLOBAL OUTPUTS: Player
                   1647: /
                   1648: / DESCRIPTION:
                   1649: /      Swap a few player statistics randomly.
                   1650: /
                   1651: /************************************************************************/
                   1652: 
                   1653: scramblestats()
                   1654: {
                   1655: double dbuf[6];                /* to put statistic in */
                   1656: double dtemp1, dtemp2;         /* for swapping values */
                   1657: register int   first, second;  /* indices for swapping */
                   1658: register double  *dptr;                /* pointer for filling and emptying buf[] */
                   1659: 
                   1660:     /* fill buffer */
                   1661:     dptr = &dbuf[0];
                   1662:     *dptr++ = Player.p_strength;
                   1663:     *dptr++ = Player.p_mana;
                   1664:     *dptr++ = Player.p_brains;
                   1665:     *dptr++ = Player.p_magiclvl;
                   1666:     *dptr++ = Player.p_energy;
                   1667:     *dptr = Player.p_sin;
                   1668: 
                   1669:     /* pick values to swap */
                   1670:     first = (int) ROLL(0, 5);
                   1671:     second = (int) ROLL(0, 5);
                   1672: 
                   1673:     /* swap values */
                   1674:     dptr = &dbuf[0];
                   1675:     dtemp1 = dptr[first];
                   1676:     /* this expression is split to prevent a compiler loop on some compilers */
                   1677:     dtemp2 = dptr[second];
                   1678:     dptr[first] = dtemp2;
                   1679:     dptr[second] = dtemp1;
                   1680: 
                   1681:     /* empty buffer */
                   1682:     Player.p_strength = *dptr++;
                   1683:     Player.p_mana = *dptr++;
                   1684:     Player.p_brains = *dptr++;
                   1685:     Player.p_magiclvl = *dptr++;
                   1686:     Player.p_energy = *dptr++;
                   1687:     Player.p_sin = *dptr;
                   1688: }

unix.superglobalmegacorp.com

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