Annotation of 43BSDTahoe/games/phantasia/interplayer.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * interplayer.c - player to player routines for Phantasia
                      3:  */
                      4: 
                      5: #include "include.h"
                      6: 
                      7: /************************************************************************
                      8: /
                      9: / FUNCTION NAME: checkbattle()
                     10: /
                     11: / FUNCTION: check to see if current player should battle another
                     12: /
                     13: / AUTHOR: E. A. Estes, 12/4/85
                     14: /
                     15: / ARGUMENTS: none
                     16: /
                     17: / RETURN VALUE: none
                     18: /
                     19: / MODULES CALLED: battleplayer(), fread(), fseek()
                     20: /
                     21: / GLOBAL INPUTS: Other, Users, Player, Fileloc, *Playersfp
                     22: /
                     23: / GLOBAL OUTPUTS: Users
                     24: /
                     25: / DESCRIPTION:
                     26: /      Seach player file for a foe at the same coordinates as the
                     27: /      current player.
                     28: /      Also update user count.
                     29: /
                     30: /************************************************************************/
                     31: 
                     32: checkbattle()
                     33: {
                     34: long   foeloc = 0L;            /* location in file of person to fight */
                     35: 
                     36:     Users = 0;
                     37:     fseek(Playersfp, 0L, 0);
                     38: 
                     39:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                     40:        {
                     41:        if (Other.p_status != S_OFF
                     42:            && Other.p_status != S_NOTUSED
                     43:            && Other.p_status != S_HUNGUP
                     44:            && (Other.p_status != S_CLOAKED || Other.p_specialtype != SC_VALAR))
                     45:            /* player is on and not a cloaked valar */
                     46:            {
                     47:            ++Users;
                     48: 
                     49:            if (Player.p_x == Other.p_x
                     50:                && Player.p_y == Other.p_y
                     51:                /* same coordinates */
                     52:                && foeloc != Fileloc
                     53:                /* not self */
                     54:                && Player.p_status == S_PLAYING
                     55:                && (Other.p_status == S_PLAYING || Other.p_status == S_INBATTLE)
                     56:                /* both are playing */
                     57:                && Other.p_specialtype != SC_VALAR
                     58:                && Player.p_specialtype != SC_VALAR)
                     59:                /* neither is valar */
                     60:                {
                     61:                battleplayer(foeloc);
                     62:                return;
                     63:                }
                     64:            }
                     65:        foeloc += SZ_PLAYERSTRUCT;
                     66:        }
                     67: }
                     68: /**/
                     69: /************************************************************************
                     70: /
                     71: / FUNCTION NAME: battleplayer()
                     72: /
                     73: / FUNCTION: inter-terminal battle with another player
                     74: /
                     75: / AUTHOR: E. A. Estes, 2/15/86
                     76: /
                     77: / ARGUMENTS:
                     78: /      long foeplace - location in player file of person to battle
                     79: /
                     80: / RETURN VALUE: none
                     81: /
                     82: / MODULES CALLED: readrecord(), readmessage(), writerecord(), collecttaxes(), 
                     83: /      displaystats(), fabs(), more(), death(), sleep(), wmove(), waddch(), printw(), 
                     84: /      myturn(), altercoordinates(), waddstr(), wrefresh(), mvprintw(), 
                     85: /      getanswer(), wclrtoeol(), wclrtobot()
                     86: /
                     87: / GLOBAL INPUTS: Foestrikes, LINES, Lines, Other, Shield, Player, *stdscr, 
                     88: /      Fileloc, *Enemyname
                     89: /
                     90: / GLOBAL OUTPUTS: Foestrikes, Lines, Shield, Player, Luckout, *Enemyname
                     91: /
                     92: / DESCRIPTION:
                     93: /      Inter-terminal battle is a very fragile and slightly klugy thing.
                     94: /      At any time, one player is master and the other is slave.
                     95: /      We pick who is master first by speed and level.  After that,
                     96: /      the slave waits for the master to relinquish its turn, and
                     97: /      the slave becomes master, and so on.
                     98: /
                     99: /      The items in the player structure which control the handshake are:
                    100: /          p_tampered:
                    101: /              master increments this to relinquish control
                    102: /          p_istat:
                    103: /              master sets this to specify particular action
                    104: /          p_1scratch:
                    105: /              set to total damage inflicted so far; changes to indicate action
                    106: /
                    107: /************************************************************************/
                    108: 
                    109: battleplayer(foeplace)
                    110: long   foeplace;
                    111: {
                    112: double dtemp;          /* for temporary calculations */
                    113: double oldhits = 0.0;  /* previous damage inflicted by foe */
                    114: register int   loop;   /* for timing out */
                    115: int    ch;             /* input */
                    116: short  oldtampered;    /* old value of foe's p_tampered */
                    117: 
                    118:     Lines = 8;
                    119:     Luckout = FALSE;
                    120:     mvaddstr(4, 0, "Preparing for battle!\n");
                    121:     refresh();
                    122: 
                    123: #ifdef SYS5
                    124:     flushinp();
                    125: #endif
                    126: 
                    127:     /* set up variables, file, etc. */
                    128:     Player.p_status = S_INBATTLE;
                    129:     Shield = Player.p_energy;
                    130: 
                    131:     /* if p_tampered is not 0, someone else may try to change it (king, etc.) */
                    132:     Player.p_tampered = oldtampered = 1;
                    133:     Player.p_1scratch = 0.0;
                    134:     Player.p_istat = I_OFF;
                    135: 
                    136:     readrecord(&Other, foeplace);
                    137:     if (fabs(Player.p_level - Other.p_level) > 20.0)
                    138:        /* see if players are greatly mismatched */
                    139:        {
                    140:        dtemp = (Player.p_level - Other.p_level) / MAX(Player.p_level, Other.p_level);
                    141:        if (dtemp < -0.5)
                    142:            /* foe outweighs this one */
                    143:            Player.p_speed *= 2.0;
                    144:        }
                    145: 
                    146:     writerecord(&Player, Fileloc);             /* write out all our info */
                    147: 
                    148:     if (Player.p_blindness)
                    149:        Enemyname = "someone";
                    150:     else
                    151:        Enemyname = Other.p_name;
                    152: 
                    153:     mvprintw(6, 0, "You have encountered %s   Level: %.0f\n", Enemyname, Other.p_level);
                    154:     refresh();
                    155: 
                    156:     for (loop = 0; Other.p_status != S_INBATTLE && loop < 30; ++loop)
                    157:        /* wait for foe to respond */
                    158:        {
                    159:        readrecord(&Other, foeplace);
                    160:        sleep(1);
                    161:        }
                    162: 
                    163:     if (Other.p_status != S_INBATTLE)
                    164:        /* foe did not respond */
                    165:        {
                    166:        mvprintw(5, 0, "%s is not responding.\n", Enemyname);
                    167:        goto LEAVE;
                    168:        }
                    169:     /* else, we are ready to battle */
                    170: 
                    171:     move(4, 0);
                    172:     clrtoeol();
                    173: 
                    174:     /*
                    175:      * determine who is first master
                    176:      * if neither player is faster, check level
                    177:      * if neither level is greater, battle is not allowed
                    178:      * (this should never happen, but we have to handle it)
                    179:      */
                    180:     if (Player.p_speed > Other.p_speed)
                    181:        Foestrikes = FALSE;
                    182:     else if (Other.p_speed > Player.p_speed)
                    183:        Foestrikes = TRUE;
                    184:     else if (Player.p_level > Other.p_level)
                    185:        Foestrikes = FALSE;
                    186:     else if (Other.p_level > Player.p_level)
                    187:        Foestrikes = TRUE;
                    188:     else
                    189:        /* no one is faster */
                    190:        {
                    191:        printw("You can't fight %s yet.", Enemyname);
                    192:        goto LEAVE;
                    193:        }
                    194: 
                    195:     for (;;)
                    196:        {
                    197:        displaystats();
                    198:        readmessage();
                    199:        mvprintw(1, 26, "%20.0f", Shield);      /* overprint energy */
                    200: 
                    201:        if (!Foestrikes)
                    202:            /* take action against foe */
                    203:            myturn();
                    204:        else
                    205:            /* wait for foe to take action */
                    206:            {
                    207:            mvaddstr(4, 0, "Waiting...\n");
                    208:            clrtoeol();
                    209:            refresh();
                    210: 
                    211:            for (loop = 0; loop < 20; ++loop)
                    212:                /* wait for foe to act */
                    213:                {
                    214:                readrecord(&Other, foeplace);
                    215:                if (Other.p_1scratch != oldhits)
                    216:                    /* p_1scratch changes to indicate action */
                    217:                    break;
                    218:                else
                    219:                    /* wait and try again */
                    220:                    {
                    221:                    sleep(1);
                    222:                    addch('.');
                    223:                    refresh();
                    224:                    }
                    225:                }
                    226: 
                    227:            if (Other.p_1scratch == oldhits)
                    228:                {
                    229:                /* timeout */
                    230:                mvaddstr(22, 0, "Timeout: waiting for response.  Do you want to wait ? ");
                    231:                ch = getanswer("NY", FALSE);
                    232:                move(22, 0);
                    233:                clrtobot();
                    234:                if (ch == 'Y')
                    235:                    continue;
                    236:                else
                    237:                    break;
                    238:                }
                    239:            else
                    240:                /* foe took action */
                    241:                {
                    242:                switch (Other.p_istat)
                    243:                    {
                    244:                    case I_RAN:         /* foe ran away */
                    245:                        mvprintw(Lines++, 0, "%s ran away!", Enemyname);
                    246:                        break;
                    247: 
                    248:                    case I_STUCK:       /* foe tried to run, but couldn't */
                    249:                        mvprintw(Lines++, 0, "%s tried to run away.", Enemyname);
                    250:                        break;
                    251: 
                    252:                    case I_BLEWIT:      /* foe tried to luckout, but didn't */
                    253:                        mvprintw(Lines++, 0, "%s tried to luckout!", Enemyname);
                    254:                        break;
                    255: 
                    256:                    default:
                    257:                        dtemp = Other.p_1scratch - oldhits;
                    258:                        mvprintw(Lines++, 0, "%s hit you %.0f times!", Enemyname, dtemp);
                    259:                        Shield -= dtemp;
                    260:                        break;
                    261:                    }
                    262: 
                    263:                oldhits = Other.p_1scratch;     /* keep track of old hits */
                    264: 
                    265:                if (Other.p_tampered != oldtampered)
                    266:                    /* p_tampered changes to relinquish turn */
                    267:                    {
                    268:                    oldtampered = Other.p_tampered;
                    269:                    Foestrikes = FALSE;
                    270:                    }
                    271:                }
                    272:            }
                    273: 
                    274:        /* decide what happens next */
                    275:        refresh();
                    276:        if (Lines > LINES - 2)
                    277:            {
                    278:            more(Lines);
                    279:            move(Lines = 8, 0);
                    280:            clrtobot();
                    281:            }
                    282: 
                    283:        if (Other.p_istat == I_KILLED || Shield < 0.0)
                    284:            /* we died */
                    285:            {
                    286:            Shield = -2.0;              /* insure this value is negative */
                    287:            break;
                    288:            }
                    289: 
                    290:        if (Player.p_istat == I_KILLED)
                    291:            /* we killed foe; award treasre */
                    292:            {
                    293:            mvprintw(Lines++, 0, "You killed %s!", Enemyname);
                    294:            Player.p_experience += Other.p_experience;
                    295:            Player.p_crowns += (Player.p_level < 1000.0) ? Other.p_crowns : 0;
                    296:            Player.p_amulets += Other.p_amulets;
                    297:            Player.p_charms += Other.p_charms;
                    298:            collecttaxes(Other.p_gold, Other.p_gems);
                    299:            Player.p_sword = MAX(Player.p_sword, Other.p_sword);
                    300:            Player.p_shield = MAX(Player.p_shield, Other.p_shield);
                    301:            Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver);
                    302:            if (Other.p_virgin && !Player.p_virgin)
                    303:                {
                    304:                mvaddstr(Lines++, 0, "You have rescued a virgin.  Will you be honorable ? ");
                    305:                if ((ch = getanswer("YN", FALSE)) == 'Y')
                    306:                    Player.p_virgin = TRUE;
                    307:                else
                    308:                    {
                    309:                    ++Player.p_sin;
                    310:                    Player.p_experience += 8000.0;
                    311:                    }
                    312:                }
                    313:            sleep(3);                   /* give other person time to die */
                    314:            break;
                    315:            }
                    316:        else if (Player.p_istat == I_RAN || Other.p_istat == I_RAN)
                    317:            /* either player ran away */
                    318:            break;
                    319:        }
                    320: 
                    321: LEAVE:
                    322:     /* clean up things and leave */
                    323:     writerecord(&Player, Fileloc);     /* update a final time */
                    324:     altercoordinates(0.0, 0.0, A_NEAR);        /* move away from battle site */
                    325:     Player.p_energy = Shield;          /* set energy to actual value */
                    326:     Player.p_tampered = T_OFF;         /* clear p_tampered */
                    327: 
                    328:     more(Lines);                       /* pause */
                    329: 
                    330:     move(4, 0);
                    331:     clrtobot();                                /* clear bottom area of screen */
                    332: 
                    333:     if (Player.p_energy < 0.0)
                    334:        /* we are dead */
                    335:        death("Interterminal battle");
                    336: }
                    337: /**/
                    338: /************************************************************************
                    339: /
                    340: / FUNCTION NAME: myturn()
                    341: /
                    342: / FUNCTION: process players action against foe in battle
                    343: /
                    344: / AUTHOR: E. A. Estes, 2/7/86
                    345: /
                    346: / ARGUMENTS: none
                    347: /
                    348: / RETURN VALUE: none
                    349: /
                    350: / MODULES CALLED: writerecord(), inputoption(), floor(), wmove(), drandom(), 
                    351: /      waddstr(), wrefresh(), mvprintw(), wclrtoeol(), wclrtobot()
                    352: /
                    353: / GLOBAL INPUTS: Lines, Other, Player, *stdscr, Fileloc, Luckout, 
                    354: /      *Enemyname
                    355: /
                    356: / GLOBAL OUTPUTS: Foestrikes, Lines, Player, Luckout
                    357: /
                    358: / DESCRIPTION:
                    359: /      Take action action against foe, and decide who is master
                    360: /      for next iteration.
                    361: /
                    362: /************************************************************************/
                    363: 
                    364: myturn()
                    365: {
                    366: double dtemp;          /* for temporary calculations */
                    367: int    ch;             /* input */
                    368: 
                    369:     mvaddstr(7, 0, "1:Fight  2:Run Away!  3:Power Blast  ");
                    370:     if (Luckout)
                    371:        clrtoeol();
                    372:     else
                    373:        addstr("4:Luckout  ");
                    374: 
                    375:     ch = inputoption();
                    376:     move(Lines = 8, 0);
                    377:     clrtobot();
                    378: 
                    379:     switch (ch)
                    380:        {
                    381:        default:        /* fight */
                    382:            dtemp = ROLL(2.0, Player.p_might);
                    383: HIT:           
                    384:            mvprintw(Lines++, 0, "You hit %s %.0f times!", Enemyname, dtemp);
                    385:            Player.p_sin += 0.5;
                    386:            Player.p_1scratch += dtemp;
                    387:            Player.p_istat = I_OFF;
                    388:            break;
                    389: 
                    390:        case '2':       /* run away */
                    391:            Player.p_1scratch -= 1.0;   /* change this to indicate action */
                    392:            if (drandom() > 0.25)
                    393:                {
                    394:                mvaddstr(Lines++, 0, "You got away!");
                    395:                Player.p_istat = I_RAN;
                    396:                }
                    397:            else
                    398:                {
                    399:                mvprintw(Lines++, 0, "%s is still after you!", Enemyname);
                    400:                Player.p_istat = I_STUCK;
                    401:                }
                    402:            break;
                    403: 
                    404:        case '3':       /* power blast */
                    405:            dtemp = MIN(Player.p_mana, Player.p_level * 5.0);
                    406:            Player.p_mana -= dtemp;
                    407:            dtemp *= (drandom() + 0.5) * Player.p_magiclvl * 0.2 + 2.0;
                    408:            mvprintw(Lines++, 0, "You blasted %s !", Enemyname);
                    409:            goto HIT;
                    410: 
                    411:        case '4':       /* luckout */
                    412:            if (Luckout || drandom() > 0.1)
                    413:                {
                    414:                if (Luckout)
                    415:                    mvaddstr(Lines++, 0, "You already tried that!");
                    416:                else
                    417:                    {
                    418:                    mvaddstr(Lines++, 0, "Not this time . . .");
                    419:                    Luckout = TRUE;
                    420:                    }
                    421: 
                    422:                Player.p_1scratch -= 1.0;
                    423:                Player.p_istat = I_BLEWIT;
                    424:                }
                    425:            else
                    426:                {
                    427:                mvaddstr(Lines++, 0, "You just lucked out!");
                    428:                Player.p_1scratch = Other.p_energy * 1.1;
                    429:                }
                    430:            break;
                    431:        }
                    432: 
                    433:     refresh();
                    434:     Player.p_1scratch = floor(Player.p_1scratch);      /* clean up any mess */
                    435: 
                    436:     if (Player.p_1scratch > Other.p_energy)
                    437:        Player.p_istat = I_KILLED;
                    438:     else if (drandom() * Player.p_speed < drandom() * Other.p_speed)
                    439:        /* relinquish control */
                    440:        {
                    441:        ++Player.p_tampered;
                    442:        Foestrikes = TRUE;
                    443:        }
                    444: 
                    445:     writerecord(&Player, Fileloc);                     /* let foe know what we did */
                    446: }
                    447: /**/
                    448: /************************************************************************
                    449: /
                    450: / FUNCTION NAME: checktampered()
                    451: /
                    452: / FUNCTION: check if current player has been tampered with
                    453: /
                    454: / AUTHOR: E. A. Estes, 12/4/85
                    455: /
                    456: / ARGUMENTS: none
                    457: /
                    458: / RETURN VALUE: none
                    459: /
                    460: / MODULES CALLED: readrecord(), fread(), fseek(), tampered(), writevoid()
                    461: /
                    462: / GLOBAL INPUTS: *Energyvoidfp, Other, Player, Fileloc, Enrgyvoid
                    463: /
                    464: / GLOBAL OUTPUTS: Enrgyvoid
                    465: /
                    466: / DESCRIPTION:
                    467: /      Check for energy voids, holy grail, and tampering by other
                    468: /      players.
                    469: /
                    470: /************************************************************************/
                    471: 
                    472: checktampered()
                    473: {
                    474: long   loc = 0L;               /* location in energy void file */
                    475: 
                    476:     /* first check for energy voids */
                    477:     fseek(Energyvoidfp, 0L, 0);
                    478:     while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
                    479:        if (Enrgyvoid.ev_active
                    480:            && Enrgyvoid.ev_x == Player.p_x
                    481:            && Enrgyvoid.ev_y == Player.p_y)
                    482:            /* sitting on one */
                    483:            {
                    484:            if (loc > 0L)
                    485:                /* not the holy grail; inactivate energy void */
                    486:                {
                    487:                Enrgyvoid.ev_active = FALSE;
                    488:                writevoid(&Enrgyvoid, loc);
                    489:                tampered(T_NRGVOID, 0.0, 0.0);
                    490:                }
                    491:            else if (Player.p_status != S_CLOAKED)
                    492:                /* holy grail */
                    493:                tampered(T_GRAIL, 0.0, 0.0);
                    494:            break;
                    495:            }
                    496:        else
                    497:            loc += SZ_VOIDSTRUCT;
                    498: 
                    499:     /* now check for other things */
                    500:     readrecord(&Other, Fileloc);
                    501:     if (Other.p_tampered != T_OFF)
                    502:        tampered(Other.p_tampered, Other.p_1scratch, Other.p_2scratch);
                    503: }
                    504: /**/
                    505: /************************************************************************
                    506: /
                    507: / FUNCTION NAME: tampered()
                    508: /
                    509: / FUNCTION: take care of tampering by other players
                    510: /
                    511: / AUTHOR: E. A. Estes, 12/4/85
                    512: /
                    513: / ARGUMENTS:
                    514: /      int what - what type of tampering
                    515: /      double arg1, arg2 - rest of tampering info
                    516: /
                    517: / RETURN VALUE: none
                    518: /
                    519: / MODULES CALLED: writerecord(), more(), fread(), death(), fseek(), sleep(), 
                    520: /      floor(), wmove(), waddch(), drandom(), printw(), altercoordinates(), 
                    521: /      waddstr(), wrefresh(), encounter(), writevoid()
                    522: /
                    523: / GLOBAL INPUTS: Other, Player, *stdscr, Enrgyvoid, *Playersfp
                    524: /
                    525: / GLOBAL OUTPUTS: Other, Player, Changed, Enrgyvoid
                    526: /
                    527: / DESCRIPTION:
                    528: /      Take care of energy voids, holy grail, decree and intervention
                    529: /      action on current player.
                    530: /
                    531: /************************************************************************/
                    532: 
                    533: tampered(what, arg1, arg2)
                    534: int    what;
                    535: double arg1;
                    536: double arg2;
                    537: {
                    538: long   loc;                    /* location in file of other players */
                    539: 
                    540:     Changed = TRUE;
                    541:     move(4,0);
                    542: 
                    543:     Player.p_tampered = T_OFF; /* no longer tampered with */
                    544: 
                    545:     switch (what)
                    546:        {
                    547:        case T_NRGVOID:
                    548:            addstr("You've hit an energy void !\n");
                    549:            Player.p_mana /= 3.0;
                    550:            Player.p_energy /= 2.0;
                    551:            Player.p_gold = floor(Player.p_gold/1.25) + 0.1;
                    552:            altercoordinates(0.0, 0.0, A_NEAR);
                    553:            break;
                    554: 
                    555:        case T_TRANSPORT:
                    556:            addstr("The king transported you !  ");
                    557:            if (Player.p_charms > 0)
                    558:                {
                    559:                addstr("But your charm saved you. . .\n");
                    560:                --Player.p_charms;
                    561:                }
                    562:            else
                    563:                {
                    564:                altercoordinates(0.0, 0.0, A_FAR);
                    565:                addch('\n');
                    566:                }
                    567:            break;
                    568: 
                    569:        case T_BESTOW:
                    570:            printw("The king has bestowed %.0f gold pieces on you !\n", arg1);
                    571:            Player.p_gold += arg1;
                    572:            break;
                    573: 
                    574:        case T_CURSED:
                    575:            addstr("You've been cursed !  ");
                    576:            if (Player.p_blessing)
                    577:                {
                    578:                addstr("But your blessing saved you. . .\n");
                    579:                Player.p_blessing = FALSE;
                    580:                }
                    581:            else
                    582:                {
                    583:                addch('\n');
                    584:                Player.p_poison += 2.0;
                    585:                Player.p_energy = 10.0;
                    586:                Player.p_maxenergy  *= 0.95;
                    587:                Player.p_status = S_PLAYING;    /* no longer cloaked */
                    588:                }
                    589:            break;
                    590: 
                    591:        case T_VAPORIZED:
                    592:            addstr("You have been vaporized!\n");
                    593:            more(7);
                    594:            death("Vaporization");
                    595:            break;
                    596: 
                    597:        case T_MONSTER:
                    598:            addstr("The Valar zapped you with a monster!\n");
                    599:            more(7);
                    600:            encounter((int) arg1);
                    601:            return;
                    602: 
                    603:        case T_BLESSED:
                    604:            addstr("The Valar has blessed you!\n");
                    605:            Player.p_energy = (Player.p_maxenergy *= 1.05) + Player.p_shield;
                    606:            Player.p_mana += 500.0;
                    607:            Player.p_strength += 0.5;
                    608:            Player.p_brains += 0.5;
                    609:            Player.p_magiclvl += 0.5;
                    610:            Player.p_poison = MIN(0.5, Player.p_poison);
                    611:            break;
                    612: 
                    613:        case T_RELOCATE:
                    614:            addstr("You've been relocated. . .\n");
                    615:            altercoordinates(arg1, arg2, A_FORCED);
                    616:            break;
                    617: 
                    618:        case T_HEAL:
                    619:            addstr("You've been healed!\n");
                    620:            Player.p_poison -=  0.25;
                    621:            Player.p_energy = Player.p_maxenergy + Player.p_shield;
                    622:            break;
                    623: 
                    624:        case T_EXVALAR:
                    625:            addstr("You are no longer Valar!\n");
                    626:            Player.p_specialtype = SC_COUNCIL;
                    627:            break;
                    628: 
                    629:        case T_GRAIL:
                    630:            addstr("You have found The Holy Grail!!\n");
                    631:            if (Player.p_specialtype < SC_COUNCIL)
                    632:                /* must be council of wise to behold grail */
                    633:                {
                    634:                addstr("However, you are not experienced enough to behold it.\n");
                    635:                Player.p_sin *= Player.p_sin;
                    636:                Player.p_mana +=  1000;
                    637:                }
                    638:            else if (Player.p_specialtype == SC_VALAR
                    639:                || Player.p_specialtype == SC_EXVALAR)
                    640:                {
                    641:                addstr("You have made it to the position of Valar once already.\n");
                    642:                addstr("The Grail is of no more use to you now.\n");
                    643:                }
                    644:            else
                    645:                {
                    646:                addstr("It is now time to see if you are worthy to behold it. . .\n");
                    647:                refresh();
                    648:                sleep(4);
                    649: 
                    650:                if (drandom() / 2.0 < Player.p_sin)
                    651:                    {
                    652:                    addstr("You have failed!\n");
                    653:                    Player.p_strength =
                    654:                    Player.p_mana =
                    655:                    Player.p_energy =
                    656:                    Player.p_maxenergy =
                    657:                    Player.p_magiclvl = 
                    658:                    Player.p_brains =
                    659:                    Player.p_experience =
                    660:                    Player.p_quickness = 1.0;
                    661: 
                    662:                    altercoordinates(1.0, 1.0, A_FORCED);
                    663:                    Player.p_level = 0.0;
                    664:                    }
                    665:                else
                    666:                    {
                    667:                    addstr("You made to position of Valar!\n");
                    668:                    Player.p_specialtype = SC_VALAR;
                    669:                    Player.p_lives = 5;
                    670:                    fseek(Playersfp, 0L, 0);
                    671:                    loc = 0L;
                    672:                    while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    673:                        /* search for existing valar */
                    674:                        if (Other.p_specialtype == SC_VALAR
                    675:                            && Other.p_status != S_NOTUSED)
                    676:                            /* found old valar */
                    677:                            {
                    678:                            Other.p_tampered = T_EXVALAR;
                    679:                            writerecord(&Other, loc);
                    680:                            break;
                    681:                            }
                    682:                        else
                    683:                            loc += SZ_PLAYERSTRUCT;
                    684:                    }
                    685:                }
                    686: 
                    687:            /* move grail to new location */
                    688:            Enrgyvoid.ev_active = TRUE;
                    689:            Enrgyvoid.ev_x = ROLL(-1.0e6, 2.0e6);
                    690:            Enrgyvoid.ev_y = ROLL(-1.0e6, 2.0e6);
                    691:            writevoid(&Enrgyvoid, 0L);
                    692:            break;
                    693:        }
                    694:     refresh();
                    695:     sleep(2);
                    696: }
                    697: /**/
                    698: /************************************************************************
                    699: /
                    700: / FUNCTION NAME: userlist()
                    701: /
                    702: / FUNCTION: print list of players and locations
                    703: /
                    704: / AUTHOR: E. A. Estes, 2/28/86
                    705: /
                    706: / ARGUMENTS:
                    707: /      bool ingameflag - set if called while playing
                    708: /
                    709: / RETURN VALUE: none
                    710: /
                    711: / MODULES CALLED: descrstatus(), descrlocation(), more(), fread(), fseek(), 
                    712: /      floor(), wmove(), printw(), waddstr(), distance(), wrefresh(), 
                    713: /      descrtype(), wclrtobot()
                    714: /
                    715: / GLOBAL INPUTS: LINES, Other, Circle, Wizard, Player, *stdscr, *Playersfp
                    716: /
                    717: / GLOBAL OUTPUTS: none
                    718: /
                    719: / DESCRIPTION:
                    720: /      We can only see the coordinate of those closer to the origin
                    721: /      from us.
                    722: /      Kings and council of the wise can see and can be seen by everyone.
                    723: /      Palantirs are good for seeing everyone; and the valar can use
                    724: /      one to see through a 'cloak' spell.
                    725: /      The valar has no coordinates, and is completely invisible if
                    726: /      cloaked.
                    727: /
                    728: /************************************************************************/
                    729: 
                    730: userlist(ingameflag)
                    731: bool   ingameflag;
                    732: {
                    733: register int   numusers = 0;   /* number of users on file */
                    734: 
                    735:     if (ingameflag && Player.p_blindness)
                    736:        {
                    737:        mvaddstr(8, 0, "You cannot see anyone.\n");
                    738:        return;
                    739:        }
                    740: 
                    741:     fseek(Playersfp, 0L, 0);
                    742:     mvaddstr(8, 0,
                    743:        "Name                         X         Y    Lvl Type Login    Status\n");
                    744: 
                    745:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    746:        {
                    747:        if (Other.p_status == S_NOTUSED
                    748:            /* record is unused */
                    749:            || (Other.p_specialtype == SC_VALAR && Other.p_status == S_CLOAKED))
                    750:            /* cloaked valar */
                    751:            {
                    752:            if (!Wizard)
                    753:                /* wizard can see everything on file */
                    754:                continue;
                    755:            }
                    756: 
                    757:            ++numusers;
                    758: 
                    759:            if (ingameflag &&
                    760:                /* must be playing for the rest of these conditions */
                    761:                (Player.p_specialtype >= SC_KING
                    762:                /* kings and higher can see others */
                    763:                || Other.p_specialtype >= SC_KING
                    764:                /* kings and higher can be seen by others */
                    765:                || Circle >= CIRCLE(Other.p_x, Other.p_y)
                    766:                /* those nearer the origin can be seen */
                    767:                || Player.p_palantir)
                    768:                /* palantir enables one to see others */
                    769:                && (Other.p_status != S_CLOAKED 
                    770:                    || (Player.p_specialtype == SC_VALAR && Player.p_palantir))
                    771:                /* not cloaked; valar can see through cloak with a palantir */
                    772:                && Other.p_specialtype != SC_VALAR)
                    773:                /* not a valar */
                    774:                /* coordinates should be printed */
                    775:                printw("%-20s  %8.0f  %8.0f ",
                    776:                    Other.p_name, Other.p_x, Other.p_y);
                    777:            else
                    778:                /* cannot see player's coordinates */
                    779:                printw("%-20s %19.19s ",
                    780:                    Other.p_name, descrlocation(&Other, TRUE));
                    781:        
                    782:        printw("%6.0f %s  %-9.9s%s\n", Other.p_level, descrtype(&Other, TRUE),
                    783:            Other.p_login, descrstatus(&Other));
                    784: 
                    785:        if ((numusers % (LINES - 10)) == 0)
                    786:            {
                    787:            more(LINES - 1);
                    788:            move(9, 0);
                    789:            clrtobot();
                    790:            }
                    791:        }
                    792: 
                    793:     printw("Total players on file = %d\n", numusers);
                    794:     refresh();
                    795: }
                    796: /**/
                    797: /************************************************************************
                    798: /
                    799: / FUNCTION NAME: throneroom()
                    800: /
                    801: / FUNCTION: king stuff upon entering throne
                    802: /
                    803: / AUTHOR: E. A. Estes, 12/16/85
                    804: /
                    805: / ARGUMENTS: none
                    806: /
                    807: / RETURN VALUE: none
                    808: /
                    809: / MODULES CALLED: writerecord(), fread(), fseek(), fopen(), wmove(), fclose(), 
                    810: /      fwrite(), altercoordinates(), waddstr(), fprintf()
                    811: /
                    812: / GLOBAL INPUTS: *Energyvoidfp, Other, Player, *stdscr, Voidfile[], 
                    813: /      Messfile[], Enrgyvoid, *Playersfp
                    814: /
                    815: / GLOBAL OUTPUTS: Other, Player, Changed
                    816: /
                    817: / DESCRIPTION:
                    818: /      If player is not already king, make him/her so if the old king
                    819: /      is not playing.
                    820: /      Clear energy voids with new king.
                    821: /      Print 'decree' prompt.
                    822: /
                    823: /************************************************************************/
                    824: 
                    825: throneroom()
                    826: {
                    827: FILE   *fp;                    /* to clear energy voids */
                    828: long   loc = 0L;               /* location of old king in player file */
                    829: 
                    830:     if (Player.p_specialtype < SC_KING)
                    831:        /* not already king -- assumes crown */
                    832:        {
                    833:        fseek(Playersfp, 0L, 0);
                    834:        while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    835:            if (Other.p_specialtype == SC_KING && Other.p_status != S_NOTUSED)
                    836:                /* found old king */
                    837:                {
                    838:                if (Other.p_status != S_OFF)
                    839:                    /* old king is playing */
                    840:                    {
                    841:                    mvaddstr( 4, 0, "The king is playing, so you cannot steal his throne\n");
                    842:                    altercoordinates(0.0, 0.0, A_NEAR);
                    843:                    move(6, 0);
                    844:                    return;
                    845:                    }
                    846:                else
                    847:                    /* old king is not playing - remove him/her */
                    848:                    {
                    849:                    Other.p_specialtype = SC_NONE;
                    850:                    if (Other.p_crowns)
                    851:                        --Other.p_crowns;
                    852:                    writerecord(&Other, loc);
                    853:                    break;
                    854:                    }
                    855:                }
                    856:            else
                    857:                loc += SZ_PLAYERSTRUCT;
                    858: 
                    859:        /* make player new king */
                    860:        Changed = TRUE;
                    861:        Player.p_specialtype = SC_KING;
                    862:        mvaddstr(4, 0, "You have become king!\n");
                    863: 
                    864:        /* let everyone else know */
                    865:        fp = fopen(Messfile, "w");
                    866:        fprintf(fp, "All hail the new king!");
                    867:        fclose(fp);
                    868: 
                    869:        /* clear all energy voids; retain location of holy grail */
                    870:        fseek(Energyvoidfp, 0L, 0);
                    871:        fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
                    872:        fp = fopen(Voidfile, "w");
                    873:        fwrite((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, fp);
                    874:        fclose(fp);
                    875:        }
                    876: 
                    877:     mvaddstr(6, 0, "0:Decree  ");
                    878: }
                    879: /**/
                    880: /************************************************************************
                    881: /
                    882: / FUNCTION NAME: dotampered()
                    883: /
                    884: / FUNCTION: king and valar special options
                    885: /
                    886: / AUTHOR: E. A. Estes, 2/28/86
                    887: /
                    888: / ARGUMENTS: none
                    889: /
                    890: / RETURN VALUE: none
                    891: /
                    892: / MODULES CALLED: writerecord(), truncstring(), fread(), fseek(), fopen(), 
                    893: /      floor(), wmove(), drandom(), fclose(), fwrite(), sscanf(), strcmp(), 
                    894: /      infloat(), waddstr(), findname(), distance(), userlist(), mvprintw(), 
                    895: /      allocvoid(), getanswer(), getstring(), wclrtoeol(), writevoid()
                    896: /
                    897: / GLOBAL INPUTS: *Energyvoidfp, Other, Illcmd[], Wizard, Player, *stdscr, 
                    898: /      Databuf[], Goldfile[], Enrgyvoid
                    899: /
                    900: / GLOBAL OUTPUTS: Other, Player, Enrgyvoid
                    901: /
                    902: / DESCRIPTION:
                    903: /      Tamper with other players.  Handle king/valar specific options.
                    904: /
                    905: /************************************************************************/
                    906: 
                    907: dotampered()
                    908: {
                    909: short  tamper;                 /* value for tampering with other players */
                    910: char   *option;                        /* pointer to option description */
                    911: double temp1 = 0.0, temp2 = 0.0;       /* other tampering values */
                    912: int    ch;                             /* input */
                    913: long   loc;                            /* location in energy void file */
                    914: FILE   *fp;                            /* for opening gold file */
                    915: 
                    916:     move(6, 0);
                    917:     clrtoeol();
                    918:     if (Player.p_specialtype < SC_COUNCIL && !Wizard)
                    919:        /* king options */
                    920:        {
                    921:        addstr("1:Transport  2:Curse  3:Energy Void  4:Bestow  5:Collect Taxes  ");
                    922: 
                    923:        ch = getanswer(" ", TRUE);
                    924:        move(6, 0);
                    925:        clrtoeol();
                    926:        move(4, 0);
                    927:        switch (ch)
                    928:            {
                    929:            case '1':   /* transport someone */
                    930:                tamper = T_TRANSPORT;
                    931:                option = "transport";
                    932:                break;
                    933: 
                    934:            case '2':   /* curse another */
                    935:                tamper = T_CURSED;
                    936:                option = "curse";
                    937:                break;
                    938: 
                    939:            case '3':   /* create energy void */
                    940:                if ((loc = allocvoid()) > 20L * SZ_VOIDSTRUCT)
                    941:                    /* can only have 20 void active at once */
                    942:                    mvaddstr(5, 0, "Sorry, void creation limit reached.\n");
                    943:                else
                    944:                    {
                    945:                    addstr("Enter the X Y coordinates of void ? ");
                    946:                    getstring(Databuf, SZ_DATABUF);
                    947:                    sscanf(Databuf, "%lf %lf", &temp1, &temp2);
                    948:                    Enrgyvoid.ev_x = floor(temp1);
                    949:                    Enrgyvoid.ev_y = floor(temp2);
                    950:                    Enrgyvoid.ev_active = TRUE;
                    951:                    writevoid(&Enrgyvoid, loc);
                    952:                    mvaddstr(5, 0, "It is done.\n");
                    953:                    }
                    954:                return;
                    955: 
                    956:            case '4':   /* bestow gold to subject */
                    957:                tamper = T_BESTOW;
                    958:                addstr("How much gold to bestow ? ");
                    959:                temp1 = infloat();
                    960:                if (temp1 > Player.p_gold || temp1 < 0)
                    961:                    {
                    962:                    mvaddstr(5, 0, "You don't have that !\n");
                    963:                    return;
                    964:                    }
                    965: 
                    966:                /* adjust gold after we are sure it will be given to someone */
                    967:                option = "give gold to";
                    968:                break;
                    969: 
                    970:            case '5':   /* collect accumulated taxes */
                    971:                if ((fp = fopen(Goldfile, "r+")) != NULL)
                    972:                    /* collect taxes */
                    973:                    {
                    974:                    fread((char *) &temp1, sizeof(double), 1, fp);
                    975:                    fseek(fp, 0L, 0);
                    976:                    /* clear out value */
                    977:                    temp2 = 0.0;
                    978:                    fwrite((char *) &temp2, sizeof(double), 1, fp);
                    979:                    fclose(fp);
                    980:                    }
                    981: 
                    982:                mvprintw(4, 0, "You have collected %.0f in gold.\n", temp1);
                    983:                Player.p_gold += floor(temp1);
                    984:                return;
                    985: 
                    986:            default:
                    987:                return;
                    988:            }
                    989:        /* end of king options */
                    990:        }
                    991:     else
                    992:        /* council of wise, valar, wizard options */
                    993:        {
                    994:        addstr("1:Heal  ");
                    995:        if (Player.p_palantir || Wizard)
                    996:            addstr("2:Seek Grail  ");
                    997:        if (Player.p_specialtype == SC_VALAR || Wizard)
                    998:            addstr("3:Throw Monster  4:Relocate  5:Bless  ");
                    999:        if (Wizard)
                   1000:            addstr("6:Vaporize  ");
                   1001: 
                   1002:        ch = getanswer(" ", TRUE);
                   1003:        if (!Wizard)
                   1004:            {
                   1005:            if (ch > '2' && Player.p_specialtype != SC_VALAR)
                   1006:                {
                   1007:                ILLCMD();
                   1008:                return;
                   1009:                }
                   1010: 
                   1011:            if (Player.p_mana < MM_INTERVENE)
                   1012:                {
                   1013:                mvaddstr(5, 0, "No mana left.\n");
                   1014:                return;
                   1015:                }
                   1016:            else
                   1017:                Player.p_mana -= MM_INTERVENE;
                   1018:            }
                   1019: 
                   1020:        switch (ch)
                   1021:            {
                   1022:            case '1':   /* heal another */
                   1023:                tamper = T_HEAL;
                   1024:                option = "heal";
                   1025:                break;
                   1026: 
                   1027:            case '2':   /* seek grail */
                   1028:                if (Player.p_palantir)
                   1029:                    /* need a palantir to seek */
                   1030:                    {
                   1031:                    fseek(Energyvoidfp, 0L, 0);
                   1032:                    fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp);
                   1033:                    temp1 = distance(Player.p_x, Enrgyvoid.ev_x, Player.p_y, Enrgyvoid.ev_y);
                   1034:                    temp1 += ROLL(-temp1 / 10.0, temp1 / 5.0);  /* add some error */
                   1035:                    mvprintw(5, 0, "The palantir says the Grail is about %.0f away.\n", temp1);
                   1036:                    }
                   1037:                else
                   1038:                    /* no palantir */
                   1039:                    mvaddstr(5, 0, "You need a palantir to seek the Grail.\n");
                   1040:                return;
                   1041: 
                   1042:            case '3':   /* lob monster at someone */
                   1043:                mvaddstr(4, 0, "Which monster [0-99] ? ");
                   1044:                temp1 = infloat();
                   1045:                temp1 = MAX(0.0, MIN(99.0, temp1));
                   1046:                tamper = T_MONSTER;
                   1047:                option = "throw a monster at";
                   1048:                break;
                   1049: 
                   1050:            case '4':   /* move another player */
                   1051:                mvaddstr(4, 0, "New X Y coordinates ? ");
                   1052:                getstring(Databuf, SZ_DATABUF);
                   1053:                sscanf(Databuf, "%lf %lf", &temp1, &temp2);
                   1054:                tamper = T_RELOCATE;
                   1055:                option = "relocate";
                   1056:                break;
                   1057: 
                   1058:            case '5':   /* bless a player */
                   1059:                tamper = T_BLESSED;
                   1060:                option = "bless";
                   1061:                break;
                   1062: 
                   1063:            case '6':   /* kill off a player */
                   1064:                if (Wizard)
                   1065:                    {
                   1066:                    tamper = T_VAPORIZED;
                   1067:                    option = "vaporize";
                   1068:                    break;
                   1069:                    }
                   1070:                else
                   1071:                    return;
                   1072: 
                   1073:            default:
                   1074:                return;
                   1075:            }
                   1076: 
                   1077:        /* adjust age after we are sure intervention will be done */
                   1078:        /* end of valar, etc. options */
                   1079:        }
                   1080: 
                   1081:     for (;;)
                   1082:        /* prompt for player to affect */
                   1083:        {
                   1084:        mvprintw(4, 0, "Who do you want to %s ? ", option);
                   1085:        getstring(Databuf, SZ_DATABUF);
                   1086:        truncstring(Databuf);
                   1087: 
                   1088:        if (Databuf[0] == '\0')
                   1089:            userlist(TRUE);
                   1090:        else
                   1091:            break;
                   1092:        }
                   1093: 
                   1094:     if (strcmp(Player.p_name, Databuf) != 0)
                   1095:        /* name other than self */
                   1096:        {
                   1097:        if ((loc = findname(Databuf, &Other)) >= 0L)
                   1098:            {
                   1099:            if (Other.p_tampered != T_OFF)
                   1100:                {
                   1101:                mvaddstr(5, 0, "That person has something pending already.\n");
                   1102:                return;
                   1103:                }
                   1104:            else
                   1105:                {
                   1106:                if (tamper == T_RELOCATE
                   1107:                    && CIRCLE(temp1, temp2) < CIRCLE(Other.p_x, Other.p_y)
                   1108:                    && !Wizard)
                   1109:                    mvaddstr(5, 0, "Cannot move someone closer to the Lord's Chamber.\n");
                   1110:                else
                   1111:                    {
                   1112:                    if (tamper == T_BESTOW) Player.p_gold -= floor(temp1);
                   1113:                    if (!Wizard && (tamper == T_HEAL || tamper == T_MONSTER ||
                   1114:                        tamper == T_RELOCATE || tamper == T_BLESSED))
                   1115:                                Player.p_age += N_AGE;  /* age penalty */
                   1116:                    Other.p_tampered = tamper;
                   1117:                    Other.p_1scratch = floor(temp1);
                   1118:                    Other.p_2scratch = floor(temp2);
                   1119:                    writerecord(&Other, loc);
                   1120:                    mvaddstr(5, 0, "It is done.\n");
                   1121:                    }
                   1122:                return;
                   1123:                }
                   1124:            }
                   1125:        else
                   1126:            /* player not found */
                   1127:            mvaddstr(5, 0, "There is no one by that name.\n");
                   1128:        }
                   1129:     else
                   1130:        /* self */
                   1131:        mvaddstr(5, 0, "You may not do it to yourself!\n");
                   1132: }
                   1133: /**/
                   1134: /************************************************************************
                   1135: /
                   1136: / FUNCTION NAME: writevoid()
                   1137: /
                   1138: / FUNCTION: update energy void entry in energy void file
                   1139: /
                   1140: / AUTHOR: E. A. Estes, 12/4/85
                   1141: /
                   1142: / ARGUMENTS:
                   1143: /      struct energyvoid *vp - pointer to structure to write to file
                   1144: /      long loc - location in file to update
                   1145: /
                   1146: / RETURN VALUE: none
                   1147: /
                   1148: / MODULES CALLED: fseek(), fwrite(), fflush()
                   1149: /
                   1150: / GLOBAL INPUTS: *Energyvoidfp
                   1151: /
                   1152: / GLOBAL OUTPUTS: none
                   1153: /
                   1154: / DESCRIPTION:
                   1155: /      Write out energy void structure at specified location.
                   1156: /
                   1157: /************************************************************************/
                   1158: 
                   1159: writevoid(vp, loc)
                   1160: register struct energyvoid     *vp;
                   1161: long   loc;
                   1162: {
                   1163: 
                   1164:     fseek(Energyvoidfp, loc, 0);
                   1165:     fwrite((char *) vp, SZ_VOIDSTRUCT, 1, Energyvoidfp);
                   1166:     fflush(Energyvoidfp);
                   1167:     fseek(Energyvoidfp, 0L, 0);
                   1168: }
                   1169: /**/
                   1170: /************************************************************************
                   1171: /
                   1172: / FUNCTION NAME: allocvoid()
                   1173: /
                   1174: / FUNCTION: allocate space for a new energy void
                   1175: /
                   1176: / AUTHOR: E. A. Estes, 12/4/85
                   1177: /
                   1178: / ARGUMENTS: none
                   1179: /
                   1180: / RETURN VALUE: location of new energy void space
                   1181: /
                   1182: / MODULES CALLED: fread(), fseek()
                   1183: /
                   1184: / GLOBAL INPUTS: *Energyvoidfp, Enrgyvoid
                   1185: /
                   1186: / GLOBAL OUTPUTS: none
                   1187: /
                   1188: / DESCRIPTION:
                   1189: /      Search energy void file for an inactive entry and return its
                   1190: /      location.
                   1191: /      If no inactive ones are found, return one more than last location.
                   1192: /
                   1193: /************************************************************************/
                   1194: 
                   1195: long
                   1196: allocvoid()
                   1197: {
                   1198: long   loc = 0L;               /* location of new energy void */
                   1199: 
                   1200:     fseek(Energyvoidfp, 0L, 0);
                   1201:     while (fread((char *) &Enrgyvoid, SZ_VOIDSTRUCT, 1, Energyvoidfp) == 1)
                   1202:        if (Enrgyvoid.ev_active)
                   1203:            loc += SZ_VOIDSTRUCT;
                   1204:        else
                   1205:            break;
                   1206: 
                   1207:     return(loc);
                   1208: }

unix.superglobalmegacorp.com

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