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

1.1       root        1: /*
                      2:  * misc.c  Phantasia miscellaneous support routines
                      3:  */
                      4: 
                      5: #include "include.h"
                      6: 
                      7: /************************************************************************
                      8: /
                      9: / FUNCTION NAME: movelevel()
                     10: /
                     11: / FUNCTION: move player to new level
                     12: /
                     13: / AUTHOR: E. A. Estes, 12/4/85
                     14: /
                     15: / ARGUMENTS: none
                     16: /
                     17: / RETURN VALUE: none
                     18: /
                     19: / MODULES CALLED: death(), floor(), wmove(), drandom(), waddstr(), explevel()
                     20: /
                     21: / GLOBAL INPUTS: Player, *stdscr, *Statptr, Stattable[]
                     22: /
                     23: / GLOBAL OUTPUTS: Player, Changed
                     24: /
                     25: / DESCRIPTION:
                     26: /      Use lookup table to increment important statistics when
                     27: /      progressing to new experience level.
                     28: /      Players are rested to maximum as a bonus for making a new
                     29: /      level.
                     30: /      Check for council of wise, and being too big to be king.
                     31: /
                     32: /************************************************************************/
                     33: 
                     34: movelevel()
                     35: {
                     36: register struct charstats      *statptr;       /* for pointing into Stattable */
                     37: double new;                    /* new level */
                     38: double inc;                    /* increment between new and old levels */
                     39: 
                     40:     Changed = TRUE;
                     41: 
                     42:     if (Player.p_type == C_EXPER)
                     43:        /* roll a type to use for increment */
                     44:        statptr = &Stattable[(int) ROLL(C_MAGIC, C_HALFLING - C_MAGIC + 1)];
                     45:     else
                     46:        statptr = Statptr;
                     47: 
                     48:     new = explevel(Player.p_experience);
                     49:     inc = new - Player.p_level;
                     50:     Player.p_level = new;
                     51: 
                     52:     /* add increments to statistics */
                     53:     Player.p_strength += statptr->c_strength.increase * inc;
                     54:     Player.p_mana += statptr->c_mana.increase * inc;
                     55:     Player.p_brains += statptr->c_brains.increase * inc;
                     56:     Player.p_magiclvl += statptr->c_magiclvl.increase * inc;
                     57:     Player.p_maxenergy += statptr->c_energy.increase * inc;
                     58: 
                     59:     /* rest to maximum upon reaching new level */
                     60:     Player.p_energy = Player.p_maxenergy + Player.p_shield;
                     61: 
                     62:     if (Player.p_crowns > 0 && Player.p_level >= 1000.0)
                     63:        /* no longer able to be king -- turn crowns into cash */
                     64:        {
                     65:        Player.p_gold += ((double) Player.p_crowns) * 5000.0;
                     66:        Player.p_crowns = 0;
                     67:        }
                     68: 
                     69:     if (Player.p_level >= 3000.0 && Player.p_specialtype < SC_COUNCIL)
                     70:        /* make a member of the council */
                     71:        {
                     72:        mvaddstr(6, 0, "You have made it to the Council of the Wise.\n");
                     73:        addstr("Good Luck on your search for the Holy Grail.\n");
                     74: 
                     75:        Player.p_specialtype = SC_COUNCIL;
                     76: 
                     77:        /* no rings for council and above */
                     78:        Player.p_ring.ring_type = R_NONE;
                     79:        Player.p_ring.ring_duration = 0;
                     80: 
                     81:        Player.p_lives = 3;             /* three extra lives */
                     82:        }
                     83: 
                     84:     if (Player.p_level > 9999.0 && Player.p_specialtype != SC_VALAR)
                     85:        death("Old age");
                     86: }
                     87: /**/
                     88: /************************************************************************
                     89: /
                     90: / FUNCTION NAME: descrlocation()
                     91: /
                     92: / FUNCTION: return a formatted description of location
                     93: /
                     94: / AUTHOR: E. A. Estes, 12/4/85
                     95: /
                     96: / ARGUMENTS:
                     97: /      struct player playerp - pointer to player structure
                     98: /      bool shortflag - set if short form is desired
                     99: /
                    100: / RETURN VALUE: pointer to string containing result
                    101: /
                    102: / MODULES CALLED: fabs(), floor(), sprintf(), distance()
                    103: /
                    104: / GLOBAL INPUTS: Databuf[]
                    105: /
                    106: / GLOBAL OUTPUTS: none
                    107: /
                    108: / DESCRIPTION:
                    109: /      Look at coordinates and return an appropriately formatted
                    110: /      string.
                    111: /
                    112: /************************************************************************/
                    113: 
                    114: char   *
                    115: descrlocation(playerp, shortflag)
                    116: struct player  *playerp;
                    117: bool   shortflag;
                    118: {
                    119: double circle;                 /* corresponding circle for coordinates */
                    120: register int   quadrant;       /* quandrant of grid */
                    121: register char  *label;         /* pointer to place name */
                    122: static char    *nametable[4][4] =   /* names of places */
                    123:        {
                    124:        "Anorien",      "Ithilien",     "Rohan",        "Lorien",
                    125:        "Gondor",       "Mordor",       "Dunland",      "Rovanion",
                    126:        "South Gondor", "Khand",        "Eriador",      "The Iron Hills",
                    127:        "Far Harad",    "Near Harad",   "The Northern Waste", "Rhun"
                    128:        };
                    129: 
                    130:     if (playerp->p_specialtype == SC_VALAR)
                    131:        return(" is in Valhala");
                    132:     else if ((circle = CIRCLE(playerp->p_x, playerp->p_y)) >= 1000.0)
                    133:        {
                    134:        if (MAX(fabs(playerp->p_x), fabs(playerp->p_y)) > D_BEYOND)
                    135:            label = "The Point of No Return";
                    136:        else
                    137:            label = "The Ashen Mountains";
                    138:        }
                    139:     else if (circle >= 55)
                    140:        label = "Morannon";
                    141:     else if (circle >= 35)
                    142:        label = "Kennaquahair";
                    143:     else if (circle >= 20)
                    144:        label = "The Dead Marshes";
                    145:     else if (circle >= 9)
                    146:        label = "The Outer Waste";
                    147:     else if (circle >= 5)
                    148:        label = "The Moors Adventurous";
                    149:     else
                    150:        {
                    151:        if (playerp->p_x == 0.0 && playerp->p_y == 0.0)
                    152:            label = "The Lord's Chamber";
                    153:        else
                    154:            {
                    155:            /* this expression is split to prevent compiler loop with some compilers */
                    156:            quadrant = ((playerp->p_x > 0.0) ? 1 : 0);
                    157:            quadrant += ((playerp->p_y >= 0.0) ? 2 : 0);
                    158:            label = nametable[((int) circle) - 1][quadrant];
                    159:            }
                    160:        }
                    161: 
                    162:     if (shortflag)
                    163:        sprintf(Databuf, "%.29s", label);
                    164:     else
                    165:        sprintf(Databuf, " is in %s  (%.0f,%.0f)", label, playerp->p_x, playerp->p_y);
                    166: 
                    167:     return(Databuf);
                    168: }
                    169: /**/
                    170: /************************************************************************
                    171: /
                    172: / FUNCTION NAME: tradingpost()
                    173: /
                    174: / FUNCTION: do trading post stuff
                    175: /
                    176: / AUTHOR: E. A. Estes, 12/4/85
                    177: /
                    178: / ARGUMENTS: none
                    179: /
                    180: / RETURN VALUE: none
                    181: /
                    182: / MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(), 
                    183: /      sleep(), floor(), wmove(), drandom(), wclear(), printw(), 
                    184: /      altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(), 
                    185: /      wclrtoeol(), wclrtobot()
                    186: /
                    187: / GLOBAL INPUTS: Menu[], Circle, Player, *stdscr, Fileloc, Nobetter[]
                    188: /
                    189: / GLOBAL OUTPUTS: Player
                    190: /
                    191: / DESCRIPTION:
                    192: /      Different trading posts have different items.
                    193: /      Merchants cannot be cheated, but they can be dishonest
                    194: /      themselves.
                    195: /
                    196: /      Shields, swords, and quicksilver are not cumulative.  This is
                    197: /      one major area of complaint, but there are two reasons for this:
                    198: /              1) It becomes MUCH too easy to make very large versions
                    199: /                 of these items.
                    200: /              2) In the real world, one cannot simply weld two swords
                    201: /                 together to make a bigger one.
                    202: /
                    203: /      At one time, it was possible to sell old weapons at half the purchase
                    204: /      price.  This resulted in huge amounts of gold floating around,
                    205: /      and the game lost much of its challenge.
                    206: /
                    207: /      Also, purchasing gems defeats the whole purpose of gold.  Gold
                    208: /      is small change for lower level players.  They really shouldn't
                    209: /      be able to accumulate more than enough gold for a small sword or
                    210: /      a few books.  Higher level players shouldn't even bother to pick
                    211: /      up gold, except maybe to buy mana once in a while.
                    212: /
                    213: /************************************************************************/
                    214: 
                    215: tradingpost()
                    216: {
                    217: double numitems;       /* number of items to purchase */
                    218: double cost;           /* cost of purchase */
                    219: double blessingcost;   /* cost of blessing */
                    220: int    ch;             /* input */
                    221: register int   size;   /* size of the trading post */
                    222: register int   loop;   /* loop counter */
                    223: int    cheat = 0;      /* number of times player has tried to cheat */
                    224: bool   dishonest = FALSE;/* set when merchant is dishonest */
                    225: 
                    226:     Player.p_status = S_TRADING;
                    227:     writerecord(&Player, Fileloc);
                    228: 
                    229:     clear();
                    230:     addstr("You are at a trading post. All purchases must be made with gold.");
                    231: 
                    232:     size = sqrt(fabs(Player.p_x / 100)) + 1;
                    233:     size = MIN(7, size);
                    234: 
                    235:     /* set up cost of blessing */
                    236:     blessingcost = 1000.0 * (Player.p_level + 5.0);
                    237: 
                    238:     /* print Menu */
                    239:     move(7, 0);
                    240:     for (loop = 0; loop < size; ++loop)
                    241:        /* print Menu */
                    242:        {
                    243:        if (loop == 6)
                    244:            cost = blessingcost;
                    245:        else
                    246:            cost = Menu[loop].cost;
                    247:        printw("(%d) %-12s: %6.0f\n", loop + 1, Menu[loop].item, cost);
                    248:        }
                    249: 
                    250:     mvprintw(5, 0, "L:Leave  P:Purchase  S:Sell Gems ? ");
                    251: 
                    252:     for (;;)
                    253:        {
                    254:        adjuststats();  /* truncate any bad values */
                    255: 
                    256:        /* print some important statistics */
                    257:        mvprintw(1, 0, "Gold:   %9.0f  Gems:  %9.0f  Level:   %6.0f  Charms: %6d\n",
                    258:            Player.p_gold, Player.p_gems, Player.p_level, Player.p_charms);
                    259:        printw("Shield: %9.0f  Sword: %9.0f  Quicksilver:%3.0f  Blessed: %s\n",
                    260:            Player.p_shield, Player.p_sword, Player.p_quksilver,
                    261:            (Player.p_blessing ? " True" : "False"));
                    262:        printw("Brains: %9.0f  Mana:  %9.0f", Player.p_brains, Player.p_mana);
                    263: 
                    264:        move(5, 36);
                    265:        ch = getanswer("LPS", FALSE);
                    266:        move(15, 0);
                    267:        clrtobot();
                    268:        switch(ch)
                    269:            {
                    270:            case 'L':           /* leave */
                    271:            case '\n':
                    272:                altercoordinates(0.0, 0.0, A_NEAR);
                    273:                return;
                    274: 
                    275:            case 'P':           /* make purchase */
                    276:                mvaddstr(15, 0, "What what would you like to buy ? ");
                    277:                ch = getanswer(" 1234567", FALSE);
                    278:                move(15, 0);
                    279:                clrtoeol();
                    280: 
                    281:                if (ch - '0' > size)
                    282:                    addstr("Sorry, this merchant doesn't have that.");
                    283:                else
                    284:                    switch (ch)
                    285:                        {
                    286:                        case '1':
                    287:                            printw("Mana is one per %.0f gold piece.  How many do you want (%.0f max) ? ",
                    288:                                Menu[0].cost, floor(Player.p_gold / Menu[0].cost));
                    289:                            cost = (numitems = floor(infloat())) * Menu[0].cost;
                    290: 
                    291:                            if (cost > Player.p_gold || numitems < 0)
                    292:                                ++cheat;
                    293:                            else
                    294:                                {
                    295:                                cheat = 0;
                    296:                                Player.p_gold -= cost;
                    297:                                if (drandom() < 0.02)
                    298:                                    dishonest = TRUE;
                    299:                                else
                    300:                                    Player.p_mana += numitems;
                    301:                                }
                    302:                            break;
                    303: 
                    304:                        case '2':
                    305:                            printw("Shields are %.0f per +1.  How many do you want (%.0f max) ? ",
                    306:                                Menu[1].cost, floor(Player.p_gold / Menu[1].cost));
                    307:                            cost = (numitems = floor(infloat())) * Menu[1].cost;
                    308: 
                    309:                            if (numitems == 0.0)
                    310:                                break;
                    311:                            else if (cost > Player.p_gold || numitems < 0)
                    312:                                ++cheat;
                    313:                            else if (numitems < Player.p_shield)
                    314:                                NOBETTER();
                    315:                            else
                    316:                                {
                    317:                                cheat = 0;
                    318:                                Player.p_gold -= cost;
                    319:                                if (drandom() < 0.02)
                    320:                                    dishonest = TRUE;
                    321:                                else
                    322:                                    Player.p_shield = numitems;
                    323:                                }
                    324:                            break;
                    325: 
                    326:                        case '3':
                    327:                            printw("A book costs %.0f gp.  How many do you want (%.0f max) ? ",
                    328:                                Menu[2].cost, floor(Player.p_gold / Menu[2].cost));
                    329:                            cost = (numitems = floor(infloat())) * Menu[2].cost;
                    330: 
                    331:                            if (cost > Player.p_gold || numitems < 0)
                    332:                                ++cheat;
                    333:                            else
                    334:                                {
                    335:                                cheat = 0;
                    336:                                Player.p_gold -= cost;
                    337:                                if (drandom() < 0.02)
                    338:                                    dishonest = TRUE;
                    339:                                else if (drandom() * numitems > Player.p_level / 10.0
                    340:                                    && numitems != 1)
                    341:                                    {
                    342:                                    printw("\nYou blew your mind!\n");
                    343:                                    Player.p_brains /= 5;
                    344:                                    }
                    345:                                else
                    346:                                    {
                    347:                                    Player.p_brains += floor(numitems) * ROLL(20, 8);
                    348:                                    }
                    349:                                }
                    350:                            break;
                    351: 
                    352:                        case '4':
                    353:                            printw("Swords are %.0f gp per +1.  How many + do you want (%.0f max) ? ",
                    354:                                Menu[3].cost, floor(Player.p_gold / Menu[3].cost));
                    355:                            cost = (numitems = floor(infloat())) * Menu[3].cost;
                    356: 
                    357:                            if (numitems == 0.0)
                    358:                                break;
                    359:                            else if (cost > Player.p_gold || numitems < 0)
                    360:                                ++cheat;
                    361:                            else if (numitems < Player.p_sword)
                    362:                                NOBETTER();
                    363:                            else
                    364:                                {
                    365:                                cheat = 0;
                    366:                                Player.p_gold -= cost;
                    367:                                if (drandom() < 0.02)
                    368:                                    dishonest = TRUE;
                    369:                                else
                    370:                                    Player.p_sword = numitems;
                    371:                                }
                    372:                            break;
                    373: 
                    374:                        case '5':
                    375:                            printw("A charm costs %.0f gp.  How many do you want (%.0f max) ? ",
                    376:                                Menu[4].cost, floor(Player.p_gold / Menu[4].cost));
                    377:                            cost = (numitems = floor(infloat())) * Menu[4].cost;
                    378: 
                    379:                            if (cost > Player.p_gold || numitems < 0)
                    380:                                ++cheat;
                    381:                            else
                    382:                                {
                    383:                                cheat = 0;
                    384:                                Player.p_gold -= cost;
                    385:                                if (drandom() < 0.02)
                    386:                                    dishonest = TRUE;
                    387:                                else
                    388:                                    Player.p_charms += numitems;
                    389:                                }
                    390:                            break;
                    391: 
                    392:                        case '6':
                    393:                            printw("Quicksilver is %.0f gp per +1.  How many + do you want (%.0f max) ? ",
                    394:                                Menu[5].cost, floor(Player.p_gold / Menu[5].cost));
                    395:                            cost = (numitems = floor(infloat())) * Menu[5].cost;
                    396: 
                    397:                            if (numitems == 0.0)
                    398:                                break;
                    399:                            else if (cost > Player.p_gold || numitems < 0)
                    400:                                ++cheat;
                    401:                            else if (numitems < Player.p_quksilver)
                    402:                                NOBETTER();
                    403:                            else
                    404:                                {
                    405:                                cheat = 0;
                    406:                                Player.p_gold -= cost;
                    407:                                if (drandom() < 0.02)
                    408:                                    dishonest = TRUE;
                    409:                                else
                    410:                                    Player.p_quksilver = numitems;
                    411:                                }
                    412:                            break;
                    413: 
                    414:                        case '7':
                    415:                            if (Player.p_blessing)
                    416:                                {
                    417:                                addstr("You already have a blessing.");
                    418:                                break;
                    419:                                }
                    420: 
                    421:                            printw("A blessing requires a %.0f gp donation.  Still want one ? ", blessingcost);
                    422:                            ch = getanswer("NY", FALSE);
                    423: 
                    424:                            if (ch == 'Y')
                    425:                                if (Player.p_gold < blessingcost)
                    426:                                    ++cheat;
                    427:                                else
                    428:                                    {
                    429:                                    cheat = 0;
                    430:                                    Player.p_gold -= blessingcost;
                    431:                                    if (drandom() < 0.02)
                    432:                                        dishonest = TRUE;
                    433:                                    else
                    434:                                        Player.p_blessing = TRUE;
                    435:                                    }
                    436:                            break;
                    437:                        }
                    438:            break;
                    439: 
                    440:            case 'S':           /* sell gems */
                    441:                mvprintw(15, 0, "A gem is worth %.0f gp.  How many do you want to sell (%.0f max) ? ",
                    442:                    (double) N_GEMVALUE, Player.p_gems);
                    443:                numitems = floor(infloat());
                    444: 
                    445:                if (numitems > Player.p_gems || numitems < 0)
                    446:                    ++cheat;
                    447:                else
                    448:                    {
                    449:                    cheat = 0;
                    450:                    Player.p_gems -= numitems;
                    451:                    Player.p_gold += numitems * N_GEMVALUE;
                    452:                    }
                    453:            }
                    454: 
                    455:        if (cheat == 1)
                    456:            mvaddstr(17, 0, "Come on, merchants aren't stupid.  Stop cheating.\n");
                    457:        else if (cheat == 2)
                    458:            {
                    459:            mvaddstr(17, 0, "You had your chance.  This merchant happens to be\n");
                    460:            printw("a %.0f level magic user, and you made %s mad!\n",
                    461:                ROLL(Circle * 20.0, 40.0), (drandom() < 0.5) ? "him" : "her");
                    462:            altercoordinates(0.0, 0.0, A_FAR);
                    463:            Player.p_energy /= 2.0;
                    464:            ++Player.p_sin;
                    465:            more(23);
                    466:            return;
                    467:            }
                    468:        else if (dishonest)
                    469:            {
                    470:            mvaddstr(17, 0, "The merchant stole your money!");
                    471:            refresh();
                    472:            altercoordinates(Player.p_x - Player.p_x / 10.0,
                    473:                Player.p_y - Player.p_y / 10.0, A_SPECIFIC);
                    474:            sleep(2);
                    475:            return;
                    476:            }
                    477:        }
                    478: }
                    479: /**/
                    480: /************************************************************************
                    481: /
                    482: / FUNCTION NAME: displaystats()
                    483: /
                    484: / FUNCTION: print out important player statistics
                    485: /
                    486: / AUTHOR: E. A. Estes, 12/4/85
                    487: /
                    488: / ARGUMENTS: none
                    489: /
                    490: / RETURN VALUE: none
                    491: /
                    492: / MODULES CALLED: descrstatus(), descrlocation(), mvprintw()
                    493: /
                    494: / GLOBAL INPUTS: Users, Player
                    495: /
                    496: / GLOBAL OUTPUTS: none
                    497: /
                    498: / DESCRIPTION:
                    499: /      Important player statistics are printed on the screen.
                    500: /
                    501: /************************************************************************/
                    502: 
                    503: displaystats()
                    504: {
                    505:     mvprintw(0, 0, "%s%s\n", Player.p_name, descrlocation(&Player, FALSE));
                    506:     mvprintw(1, 0, "Level :%7.0f   Energy  :%9.0f(%9.0f)  Mana :%9.0f  Users:%3d\n",
                    507:        Player.p_level, Player.p_energy, Player.p_maxenergy + Player.p_shield,
                    508:        Player.p_mana, Users);
                    509:     mvprintw(2, 0, "Quick :%3.0f(%3.0f)  Strength:%9.0f(%9.0f)  Gold :%9.0f  %s\n",
                    510:        Player.p_speed, Player.p_quickness + Player.p_quksilver, Player.p_might,
                    511:        Player.p_strength + Player.p_sword, Player.p_gold, descrstatus(&Player));
                    512: }
                    513: /**/
                    514: /************************************************************************
                    515: /
                    516: / FUNCTION NAME: allstatslist()
                    517: /
                    518: / FUNCTION: show player items
                    519: /
                    520: / AUTHOR: E. A. Estes, 12/4/85
                    521: /
                    522: / ARGUMENTS: none
                    523: /
                    524: / RETURN VALUE: none
                    525: /
                    526: / MODULES CALLED: mvprintw(), descrtype()
                    527: /
                    528: / GLOBAL INPUTS: Player
                    529: /
                    530: / GLOBAL OUTPUTS: none
                    531: /
                    532: / DESCRIPTION:
                    533: /      Print out some player statistics of lesser importance.
                    534: /
                    535: /************************************************************************/
                    536: 
                    537: allstatslist()
                    538: {
                    539: static char    *flags[] =      /* to print value of some bools */
                    540:            {
                    541:            "False", 
                    542:            " True"
                    543:            };
                    544: 
                    545:     mvprintw( 8,  0, "Type: %s\n",  descrtype(&Player,  FALSE));
                    546: 
                    547:     mvprintw(10,  0, "Experience: %9.0f", Player.p_experience);
                    548:     mvprintw(11,  0, "Brains    : %9.0f", Player.p_brains);
                    549:     mvprintw(12,  0, "Magic Lvl : %9.0f", Player.p_magiclvl);
                    550:     mvprintw(13,  0, "Sin       : %9.5f", Player.p_sin);
                    551:     mvprintw(14,  0, "Poison    : %9.5f", Player.p_poison);
                    552:     mvprintw(15,  0, "Gems      : %9.0f", Player.p_gems);
                    553:     mvprintw(16,  0, "Age       : %9d", Player.p_age);
                    554:     mvprintw(10, 40, "Holy Water: %9d", Player.p_holywater);
                    555:     mvprintw(11, 40, "Amulets   : %9d", Player.p_amulets);
                    556:     mvprintw(12, 40, "Charms    : %9d", Player.p_charms);
                    557:     mvprintw(13, 40, "Crowns    : %9d", Player.p_crowns);
                    558:     mvprintw(14, 40, "Shield    : %9.0f", Player.p_shield);
                    559:     mvprintw(15, 40, "Sword     : %9.0f", Player.p_sword);
                    560:     mvprintw(16, 40, "Quickslver: %9.0f", Player.p_quksilver);
                    561: 
                    562:     mvprintw(18,  0, "Blessing: %s   Ring: %s   Virgin: %s   Palantir: %s", 
                    563:        flags[Player.p_blessing], flags[Player.p_ring.ring_type != R_NONE], 
                    564:        flags[Player.p_virgin], flags[Player.p_palantir]);
                    565: }
                    566: /**/
                    567: /************************************************************************
                    568: /
                    569: / FUNCTION NAME: descrtype()
                    570: /
                    571: / FUNCTION: return a string specifying player type
                    572: /
                    573: / AUTHOR: E. A. Estes, 12/4/85
                    574: /
                    575: / ARGUMENTS:
                    576: /      struct player playerp - pointer to structure for player
                    577: /      bool shortflag - set if short form is desired
                    578: /
                    579: / RETURN VALUE: pointer to string describing player type
                    580: /
                    581: / MODULES CALLED: strcpy()
                    582: /
                    583: / GLOBAL INPUTS: Databuf[]
                    584: /
                    585: / GLOBAL OUTPUTS: Databuf[]
                    586: /
                    587: / DESCRIPTION:
                    588: /      Return a string describing the player type.
                    589: /      King, council, valar, supercedes other types.
                    590: /      The first character of the string is '*' if the player
                    591: /      has a crown.
                    592: /      If 'shortflag' is TRUE, return a 3 character string.
                    593: /
                    594: /************************************************************************/
                    595: 
                    596: char   *
                    597: descrtype(playerp, shortflag)
                    598: struct player *playerp;
                    599: bool   shortflag;
                    600: {
                    601: register int type;     /* for caluculating result subscript */
                    602: static char    *results[] =    /* description table */
                    603:                        {
                    604:                        " Magic User", " MU",
                    605:                        " Fighter", " F ",
                    606:                        " Elf", " E ",
                    607:                        " Dwarf", " D ",
                    608:                        " Halfling", " H ",
                    609:                        " Experimento", " EX",
                    610:                        " Super", " S ",
                    611:                        " King", " K ",
                    612:                        " Council of Wise", " CW",
                    613:                        " Ex-Valar", " EV",
                    614:                        " Valar", " V ",
                    615:                        " ? ", " ? "
                    616:                        };
                    617: 
                    618:     type = playerp->p_type;
                    619: 
                    620:     switch (playerp->p_specialtype)
                    621:        {
                    622:        case SC_NONE:
                    623:            type = playerp->p_type;
                    624:            break;
                    625: 
                    626:        case SC_KING:
                    627:            type = 7;
                    628:            break;
                    629: 
                    630:        case SC_COUNCIL:
                    631:            type = 8;
                    632:            break;
                    633: 
                    634:        case SC_EXVALAR:
                    635:            type = 9;
                    636:            break;
                    637: 
                    638:        case SC_VALAR:
                    639:            type = 10;
                    640:            break;
                    641:        }
                    642: 
                    643:     type *= 2;         /* calculate offset */
                    644: 
                    645:     if (type > 20)
                    646:        /* error */
                    647:        type = 22;
                    648: 
                    649:     if (shortflag)
                    650:        /* use short descriptions */
                    651:        ++type;
                    652: 
                    653:     if (playerp->p_crowns > 0)
                    654:        {
                    655:        strcpy(Databuf, results[type]);
                    656:        Databuf[0] = '*';
                    657:        return(Databuf);
                    658:        }
                    659:     else
                    660:        return(results[type]);
                    661: }
                    662: /**/
                    663: /************************************************************************
                    664: /
                    665: / FUNCTION NAME: findname()
                    666: /
                    667: / FUNCTION: find location in player file of given name
                    668: /
                    669: / AUTHOR: E. A. Estes, 12/4/85
                    670: /
                    671: / ARGUMENTS:
                    672: /      char *name - name of character to look for
                    673: /      struct player *playerp - pointer of structure to fill
                    674: /
                    675: / RETURN VALUE: location of player if found, -1 otherwise
                    676: /
                    677: / MODULES CALLED: fread(), fseek(), strcmp()
                    678: /
                    679: / GLOBAL INPUTS: Wizard, *Playersfp
                    680: /
                    681: / GLOBAL OUTPUTS: none
                    682: /
                    683: / DESCRIPTION:
                    684: /      Search the player file for the player of the given name.
                    685: /      If player is found, fill structure with player data.
                    686: /
                    687: /************************************************************************/
                    688: 
                    689: long
                    690: findname(name, playerp)
                    691: register char  *name;
                    692: register struct player *playerp;
                    693: {
                    694: long   loc = 0;                        /* location in the file */
                    695: 
                    696:     fseek(Playersfp, 0L, 0);
                    697:     while (fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    698:        {
                    699:        if (strcmp(playerp->p_name, name) == 0)
                    700:            {
                    701:            if (playerp->p_status != S_NOTUSED || Wizard)
                    702:                /* found it */
                    703:                return(loc);
                    704:            }
                    705:        loc += SZ_PLAYERSTRUCT;
                    706:        }
                    707: 
                    708:     return(-1);
                    709: }
                    710: /**/
                    711: /************************************************************************
                    712: /
                    713: / FUNCTION NAME: allocrecord()
                    714: /
                    715: / FUNCTION: find space in the player file for a new character
                    716: /
                    717: / AUTHOR: E. A. Estes, 12/4/85
                    718: /
                    719: / ARGUMENTS: none
                    720: /
                    721: / RETURN VALUE: location of free space in file
                    722: /
                    723: / MODULES CALLED: initplayer(), writerecord(), fread(), fseek()
                    724: /
                    725: / GLOBAL INPUTS: Other, *Playersfp
                    726: /
                    727: / GLOBAL OUTPUTS: Player
                    728: /
                    729: / DESCRIPTION:
                    730: /      Search the player file for an unused entry.  If none are found,
                    731: /      make one at the end of the file.
                    732: /
                    733: /************************************************************************/
                    734: 
                    735: long
                    736: allocrecord()
                    737: {
                    738: long   loc = 0L;               /* location in file */
                    739: 
                    740:     fseek(Playersfp, 0L, 0);
                    741:     while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1)
                    742:        {
                    743:        if (Other.p_status == S_NOTUSED)
                    744:            /* found an empty record */
                    745:            return(loc);
                    746:        else
                    747:            loc += SZ_PLAYERSTRUCT;
                    748:        }
                    749: 
                    750:     /* make a new record */
                    751:     initplayer(&Other);
                    752:     Player.p_status = S_OFF;
                    753:     writerecord(&Other, loc);
                    754: 
                    755:     return(loc);
                    756: }
                    757: /**/
                    758: /************************************************************************
                    759: /
                    760: / FUNCTION NAME: freerecord()
                    761: /
                    762: / FUNCTION: free up a record on the player file
                    763: /
                    764: / AUTHOR: E. A. Estes, 2/7/86
                    765: /
                    766: / ARGUMENTS:
                    767: /      struct player playerp - pointer to structure to free
                    768: /      long loc - location in file to free
                    769: /
                    770: / RETURN VALUE: none
                    771: /
                    772: / MODULES CALLED: writerecord()
                    773: /
                    774: / GLOBAL INPUTS: none
                    775: /
                    776: / GLOBAL OUTPUTS: none
                    777: /
                    778: / DESCRIPTION:
                    779: /      Mark structure as not used, and update player file.
                    780: /
                    781: /************************************************************************/
                    782: 
                    783: freerecord(playerp, loc)
                    784: struct player  *playerp;
                    785: long   loc;
                    786: {
                    787:     playerp->p_name[0] = CH_MARKDELETE;
                    788:     playerp->p_status = S_NOTUSED;
                    789:     writerecord(playerp, loc);
                    790: }
                    791: /**/
                    792: /************************************************************************
                    793: /
                    794: / FUNCTION NAME: leavegame()
                    795: /
                    796: / FUNCTION: leave game
                    797: /
                    798: / AUTHOR: E. A. Estes, 12/4/85
                    799: /
                    800: / ARGUMENTS: none
                    801: /
                    802: / RETURN VALUE: none
                    803: /
                    804: / MODULES CALLED: freerecord(), writerecord(), cleanup()
                    805: /
                    806: / GLOBAL INPUTS: Player, Fileloc
                    807: /
                    808: / GLOBAL OUTPUTS: Player
                    809: /
                    810: / DESCRIPTION:
                    811: /      Mark player as inactive, and cleanup.
                    812: /      Do not save players below level 1.
                    813: /
                    814: /************************************************************************/
                    815: 
                    816: leavegame()
                    817: {
                    818: 
                    819:     if (Player.p_level < 1.0)
                    820:        /* delete character */
                    821:        freerecord(&Player, Fileloc);
                    822:     else
                    823:        {
                    824:        Player.p_status = S_OFF;
                    825:        writerecord(&Player, Fileloc);
                    826:        }
                    827: 
                    828:     cleanup(TRUE);
                    829:     /*NOTREACHED*/
                    830: }
                    831: /**/
                    832: /************************************************************************
                    833: /
                    834: / FUNCTION NAME: death()
                    835: /
                    836: / FUNCTION: death routine
                    837: /
                    838: / AUTHOR: E. A. Estes, 12/4/85
                    839: /
                    840: / ARGUMENTS:
                    841: /      char *how - pointer to string describing cause of death
                    842: /
                    843: / RETURN VALUE: none
                    844: /
                    845: / MODULES CALLED: freerecord(), enterscore(), more(), exit(), fread(), 
                    846: /      fseek(), execl(), fopen(), floor(), wmove(), drandom(), wclear(), strcmp(), 
                    847: /      fwrite(), fflush(), printw(), strcpy(), fclose(), waddstr(), cleanup(), 
                    848: /      fprintf(), wrefresh(), getanswer(), descrtype()
                    849: /
                    850: / GLOBAL INPUTS: Curmonster, Wizard, Player, *stdscr, Fileloc, *Monstfp
                    851: /
                    852: / GLOBAL OUTPUTS: Player
                    853: /
                    854: / DESCRIPTION:
                    855: /      Kill off current player.
                    856: /      Handle rings, and multiple lives.
                    857: /      Print an appropriate message.
                    858: /      Update scoreboard, lastdead, and let other players know about
                    859: /      the demise of their comrade.
                    860: /
                    861: /************************************************************************/
                    862: 
                    863: death(how)
                    864: char   *how;
                    865: {
                    866: FILE   *fp;            /* for updating various files */
                    867: int    ch;             /* input */
                    868: static char    *deathmesg[] =
                    869:        /* add more messages here, if desired */
                    870:        {
                    871:        "You have been wounded beyond repair.  ",
                    872:        "You have been disemboweled.  ",
                    873:        "You've been mashed, mauled, and spit upon.  (You're dead.)\n",
                    874:        "You died!  ",
                    875:        "You're a complete failure -- you've died!!\n",
                    876:        "You have been dealt a fatal blow!  "
                    877:        };
                    878: 
                    879:     clear();
                    880: 
                    881:     if (strcmp(how, "Stupidity") != 0)
                    882:        {
                    883:        if (Player.p_level > 9999.0)
                    884:            /* old age */
                    885:            addstr("Characters must be retired upon reaching level 10000.  Sorry.");
                    886:        else if (Player.p_lives > 0)
                    887:            /* extra lives */
                    888:            {
                    889:            addstr("You should be more cautious.  You've been killed.\n");
                    890:            printw("You only have %d more chance(s).\n", --Player.p_lives);
                    891:            more(3);
                    892:            Player.p_energy = Player.p_maxenergy;
                    893:            return;
                    894:            }
                    895:        else if (Player.p_specialtype == SC_VALAR)
                    896:            {
                    897:            addstr("You had your chances, but Valar aren't totally\n");
                    898:            addstr("immortal.  You are now left to wither and die . . .\n");
                    899:            more(3);
                    900:            Player.p_brains = Player.p_level / 25.0;
                    901:            Player.p_energy = Player.p_maxenergy /= 5.0;
                    902:            Player.p_quksilver = Player.p_sword = 0.0;
                    903:            Player.p_specialtype = SC_COUNCIL;
                    904:            return;
                    905:            }
                    906:        else if (Player.p_ring.ring_inuse &&
                    907:            (Player.p_ring.ring_type == R_DLREG || Player.p_ring.ring_type == R_NAZREG))
                    908:            /* good ring in use - saved from death */
                    909:            {
                    910:            mvaddstr(4, 0, "Your ring saved you from death!\n");
                    911:            refresh();
                    912:            Player.p_ring.ring_type = R_NONE;
                    913:            Player.p_energy = Player.p_maxenergy / 12.0 + 1.0;
                    914:            if (Player.p_crowns > 0)
                    915:                --Player.p_crowns;
                    916:            return;
                    917:            }
                    918:        else if (Player.p_ring.ring_type == R_BAD
                    919:            || Player.p_ring.ring_type == R_SPOILED)
                    920:            /* bad ring in possession; name idiot after player */
                    921:            {
                    922:            mvaddstr(4, 0,
                    923:                "Your ring has taken control of you and turned you into a monster!\n");
                    924:            fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0);
                    925:            fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
                    926:            strcpy(Curmonster.m_name, Player.p_name);
                    927:            fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0);
                    928:            fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp);
                    929:            fflush(Monstfp);
                    930:            }
                    931:        }
                    932: 
                    933:     enterscore();              /* update score board */
                    934: 
                    935:     /* put info in last dead file */
                    936:     fp = fopen(_PATH_LASTDEAD, "w");
                    937:     fprintf(fp,"%s (%s, run by %s, level %.0f, killed by %s)",
                    938:        Player.p_name, descrtype(&Player, TRUE),
                    939:        Player.p_login, Player.p_level, how);
                    940:     fclose(fp);
                    941: 
                    942:     /* let other players know */
                    943:     fp = fopen(_PATH_MESS, "w");
                    944:     fprintf(fp, "%s was killed by %s.", Player.p_name, how);
                    945:     fclose(fp);
                    946: 
                    947:     freerecord(&Player, Fileloc);
                    948: 
                    949:     clear();
                    950:     move(10, 0);
                    951:     addstr(deathmesg[(int) ROLL(0.0, (double) sizeof(deathmesg) / sizeof(char *))]);
                    952:     addstr("Care to give it another try ? ");
                    953:     ch = getanswer("NY", FALSE);
                    954: 
                    955:     if (ch == 'Y')
                    956:        {
                    957:        cleanup(FALSE);
                    958:        execl(_PATH_GAMEPROG, "phantasia", "-s",
                    959:            (Wizard ? "-S": (char *) NULL), 0);
                    960:        exit(0);
                    961:        /*NOTREACHED*/
                    962:        }
                    963: 
                    964:     cleanup(TRUE);
                    965:     /*NOTREACHED*/
                    966: }
                    967: /**/
                    968: /************************************************************************
                    969: /
                    970: / FUNCTION NAME: writerecord()
                    971: /
                    972: / FUNCTION: update structure in player file
                    973: /
                    974: / AUTHOR: E. A. Estes, 12/4/85
                    975: /
                    976: / ARGUMENTS:
                    977: /      struct player *playerp - pointer to structure to write out
                    978: /      long place - location in file to updata
                    979: /
                    980: / RETURN VALUE: none
                    981: /
                    982: / MODULES CALLED: fseek(), fwrite(), fflush()
                    983: /
                    984: / GLOBAL INPUTS: *Playersfp
                    985: /
                    986: / GLOBAL OUTPUTS: none
                    987: /
                    988: / DESCRIPTION:
                    989: /      Update location in player file with given structure.
                    990: /
                    991: /************************************************************************/
                    992: 
                    993: writerecord(playerp, place)
                    994: register struct player *playerp;
                    995: long   place;
                    996: {
                    997:     fseek(Playersfp, place, 0);
                    998:     fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
                    999:     fflush(Playersfp);
                   1000: }
                   1001: /**/
                   1002: /************************************************************************
                   1003: /
                   1004: / FUNCTION NAME: explevel()
                   1005: /
                   1006: / FUNCTION: calculate level based upon experience
                   1007: /
                   1008: / AUTHOR: E. A. Estes, 12/4/85
                   1009: /
                   1010: / ARGUMENTS:
                   1011: /      double experience - experience to calculate experience level from
                   1012: /
                   1013: / RETURN VALUE: experience level
                   1014: /
                   1015: / MODULES CALLED: pow(), floor()
                   1016: /
                   1017: / GLOBAL INPUTS: none
                   1018: /
                   1019: / GLOBAL OUTPUTS: none
                   1020: /
                   1021: / DESCRIPTION: 
                   1022: /      Experience level is a geometric progression.  This has been finely
                   1023: /      tuned over the years, and probably should not be changed.
                   1024: /
                   1025: /************************************************************************/
                   1026: 
                   1027: double
                   1028: explevel(experience)
                   1029: double experience;
                   1030: {
                   1031:     if (experience < 1.1e7)
                   1032:        return(floor(pow((experience / 1000.0), 0.4875)));
                   1033:     else
                   1034:        return(floor(pow((experience / 1250.0), 0.4865)));
                   1035: }
                   1036: /**/
                   1037: /************************************************************************
                   1038: /
                   1039: / FUNCTION NAME: truncstring()
                   1040: /
                   1041: / FUNCTION: truncate trailing blanks off a string
                   1042: /
                   1043: / AUTHOR: E. A. Estes, 12/4/85
                   1044: /
                   1045: / ARGUMENTS: 
                   1046: /      char *string - pointer to null terminated string
                   1047: /
                   1048: / RETURN VALUE: none
                   1049: /
                   1050: / MODULES CALLED: strlen()
                   1051: /
                   1052: / GLOBAL INPUTS: none
                   1053: /
                   1054: / GLOBAL OUTPUTS: none
                   1055: /
                   1056: / DESCRIPTION: 
                   1057: /      Put nul characters in place of spaces at the end of the string.
                   1058: /
                   1059: /************************************************************************/
                   1060: 
                   1061: truncstring(string)
                   1062: register char  *string;
                   1063: {
                   1064: register int   length;         /* length of string */
                   1065: 
                   1066:     length = strlen(string);
                   1067:     while (string[--length] == ' ')
                   1068:        string[length] = '\0';
                   1069: }
                   1070: /**/
                   1071: /************************************************************************
                   1072: /
                   1073: / FUNCTION NAME: altercoordinates()
                   1074: /
                   1075: / FUNCTION: Alter x, y coordinates and set/check location flags
                   1076: /
                   1077: / AUTHOR: E. A. Estes, 12/16/85
                   1078: /
                   1079: / ARGUMENTS: 
                   1080: /      double xnew, ynew - new x, y coordinates
                   1081: /      int operation - operation to perform with coordinates
                   1082: /
                   1083: / RETURN VALUE: none
                   1084: /
                   1085: / MODULES CALLED: fabs(), floor(), drandom(), distance()
                   1086: /
                   1087: / GLOBAL INPUTS: Circle, Beyond, Player
                   1088: /
                   1089: / GLOBAL OUTPUTS: Marsh, Circle, Beyond, Throne, Player, Changed
                   1090: /
                   1091: / DESCRIPTION: 
                   1092: /      This module is called whenever the player's coordinates are altered.
                   1093: /      If the player is beyond the point of no return, he/she is forced
                   1094: /      to stay there.
                   1095: /
                   1096: /************************************************************************/
                   1097: 
                   1098: altercoordinates(xnew, ynew, operation)
                   1099: double xnew;
                   1100: double ynew;
                   1101: int    operation;
                   1102: {
                   1103:     switch (operation)
                   1104:        {
                   1105:        case A_FORCED:  /* move with no checks */
                   1106:            break;
                   1107: 
                   1108:        case A_NEAR:    /* pick random coordinates near */
                   1109:            xnew = Player.p_x + ROLL(1.0, 5.0);
                   1110:            ynew = Player.p_y - ROLL(1.0, 5.0);
                   1111:            /* fall through for check */
                   1112: 
                   1113:        case A_SPECIFIC:        /* just move player */
                   1114:            if (Beyond && fabs(xnew) < D_BEYOND && fabs(ynew) < D_BEYOND)
                   1115:                /*
                   1116:                 * cannot move back from point of no return
                   1117:                 * pick the largest coordinate to remain unchanged
                   1118:                 */
                   1119:                {
                   1120:                if (fabs(xnew) > fabs(ynew))
                   1121:                    xnew = SGN(Player.p_x) * MAX(fabs(Player.p_x), D_BEYOND);
                   1122:                else
                   1123:                    ynew = SGN(Player.p_y) * MAX(fabs(Player.p_y), D_BEYOND);
                   1124:                }
                   1125:            break;
                   1126: 
                   1127:        case A_FAR:     /* pick random coordinates far */
                   1128:            xnew = Player.p_x + SGN(Player.p_x) * ROLL(50 * Circle, 250 * Circle);
                   1129:            ynew = Player.p_y + SGN(Player.p_y) * ROLL(50 * Circle, 250 * Circle);
                   1130:            break;
                   1131:        }
                   1132:     
                   1133:     /* now set location flags and adjust coordinates */
                   1134:     Circle = CIRCLE(Player.p_x = floor(xnew), Player.p_y = floor(ynew));
                   1135: 
                   1136:     /* set up flags based upon location */
                   1137:     Throne = Marsh = Beyond = FALSE;
                   1138: 
                   1139:     if (Player.p_x == 0.0 && Player.p_y == 0.0)
                   1140:        Throne = TRUE;
                   1141:     else if (Circle < 35 && Circle >= 20)
                   1142:        Marsh = TRUE;
                   1143:     else if (MAX(fabs(Player.p_x), fabs(Player.p_y)) >= D_BEYOND)
                   1144:        Beyond = TRUE;
                   1145: 
                   1146:     Changed = TRUE;
                   1147: }
                   1148: /**/
                   1149: /************************************************************************
                   1150: /
                   1151: / FUNCTION NAME: readrecord()
                   1152: /
                   1153: / FUNCTION: read a player structure from file
                   1154: /
                   1155: / AUTHOR: E. A. Estes, 12/4/85
                   1156: /
                   1157: / ARGUMENTS:
                   1158: /      struct player *playerp - pointer to structure to fill
                   1159: /      int loc - location of record to read
                   1160: /
                   1161: / RETURN VALUE: none
                   1162: /
                   1163: / MODULES CALLED: fread(), fseek()
                   1164: /
                   1165: / GLOBAL INPUTS: *Playersfp
                   1166: /
                   1167: / GLOBAL OUTPUTS: none
                   1168: /
                   1169: / DESCRIPTION:
                   1170: /      Read structure information from player file.
                   1171: /
                   1172: /************************************************************************/
                   1173: 
                   1174: readrecord(playerp, loc)
                   1175: register struct player *playerp;
                   1176: long   loc;
                   1177: {
                   1178:     fseek(Playersfp, loc, 0);
                   1179:     fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp);
                   1180: }
                   1181: /**/
                   1182: /************************************************************************
                   1183: /
                   1184: / FUNCTION NAME: adjuststats()
                   1185: /
                   1186: / FUNCTION: adjust player statistics
                   1187: /
                   1188: / AUTHOR: E. A. Estes, 12/4/85
                   1189: /
                   1190: / ARGUMENTS: none
                   1191: /
                   1192: / RETURN VALUE: none
                   1193: /
                   1194: / MODULES CALLED: death(), floor(), drandom(), explevel(), movelevel()
                   1195: /
                   1196: / GLOBAL INPUTS: Player, *Statptr
                   1197: /
                   1198: / GLOBAL OUTPUTS: Circle, Player, Timeout
                   1199: /
                   1200: / DESCRIPTION:
                   1201: /      Handle adjustment and maximums on various player characteristics.
                   1202: /
                   1203: /************************************************************************/
                   1204: 
                   1205: adjuststats()
                   1206: {
                   1207: double dtemp;                          /* for temporary calculations */
                   1208: 
                   1209:     if (explevel(Player.p_experience) > Player.p_level)
                   1210:        /* move one or more levels */
                   1211:        {
                   1212:        movelevel();
                   1213:        if (Player.p_level > 5.0)
                   1214:            Timeout = TRUE;
                   1215:        }
                   1216: 
                   1217:     if (Player.p_specialtype == SC_VALAR)
                   1218:        /* valar */
                   1219:        Circle = Player.p_level / 5.0;
                   1220: 
                   1221:     /* calculate effective quickness */
                   1222:     dtemp = ((Player.p_gold + Player.p_gems / 2.0) - 1000.0) / Statptr->c_goldtote
                   1223:        - Player.p_level;;
                   1224:     dtemp = MAX(0.0, dtemp);           /* gold slows player down */
                   1225:     Player.p_speed = Player.p_quickness + Player.p_quksilver - dtemp;
                   1226: 
                   1227:     /* calculate effective strength */
                   1228:     if (Player.p_poison > 0.0)
                   1229:        /* poison makes player weaker */
                   1230:        {
                   1231:        dtemp = 1.0 - Player.p_poison * Statptr->c_weakness / 800.0;
                   1232:        dtemp = MAX(0.1, dtemp);
                   1233:        }
                   1234:     else
                   1235:        dtemp = 1.0;
                   1236:     Player.p_might = dtemp *  Player.p_strength + Player.p_sword;
                   1237: 
                   1238:     /* insure that important things are within limits */
                   1239:     Player.p_quksilver = MIN(99.0, Player.p_quksilver);
                   1240:     Player.p_mana = MIN(Player.p_mana,
                   1241:        Player.p_level * Statptr->c_maxmana + 1000.0);
                   1242:     Player.p_brains = MIN(Player.p_brains,
                   1243:        Player.p_level * Statptr->c_maxbrains + 200.0);
                   1244:     Player.p_charms = MIN(Player.p_charms, Player.p_level + 10.0);
                   1245: 
                   1246:     /*
                   1247:      * some implementations have problems with floating point compare
                   1248:      * we work around it with this stuff
                   1249:      */
                   1250:     Player.p_gold = floor(Player.p_gold) + 0.1;
                   1251:     Player.p_gems = floor(Player.p_gems) + 0.1;
                   1252:     Player.p_mana = floor(Player.p_mana) + 0.1;
                   1253: 
                   1254:     if (Player.p_ring.ring_type != R_NONE)
                   1255:        /* do ring things */
                   1256:        {
                   1257:        /* rest to max */
                   1258:        Player.p_energy = Player.p_maxenergy + Player.p_shield;
                   1259: 
                   1260:         if (Player.p_ring.ring_duration <= 0)
                   1261:            /* clean up expired rings */
                   1262:            switch (Player.p_ring.ring_type)
                   1263:                {
                   1264:                case R_BAD:     /* ring drives player crazy */
                   1265:                    Player.p_ring.ring_type = R_SPOILED;
                   1266:                    Player.p_ring.ring_duration = (short) ROLL(10.0, 25.0);
                   1267:                    break;
                   1268: 
                   1269:                case R_NAZREG:  /* ring disappears */
                   1270:                    Player.p_ring.ring_type = R_NONE;
                   1271:                    break;
                   1272: 
                   1273:                case R_SPOILED: /* ring kills player */
                   1274:                    death("A cursed ring");
                   1275:                    break;
                   1276: 
                   1277:                case R_DLREG:   /* this ring doesn't expire */
                   1278:                    Player.p_ring.ring_duration = 0;
                   1279:                    break;
                   1280:                }
                   1281:        }
                   1282: 
                   1283:     if (Player.p_age / N_AGE > Player.p_degenerated)
                   1284:        /* age player slightly */
                   1285:        {
                   1286:        ++Player.p_degenerated;
                   1287:        if (Player.p_quickness > 23.0)
                   1288:            Player.p_quickness *= 0.99;
                   1289:        Player.p_strength *= 0.97;
                   1290:        Player.p_brains *= 0.95;
                   1291:        Player.p_magiclvl *= 0.97;
                   1292:        Player.p_maxenergy *= 0.95;
                   1293:        Player.p_quksilver *= 0.95;
                   1294:        Player.p_sword *= 0.93;
                   1295:        Player.p_shield *= 0.93;
                   1296:        }
                   1297: }
                   1298: /**/
                   1299: /************************************************************************
                   1300: /
                   1301: / FUNCTION NAME: initplayer()
                   1302: /
                   1303: / FUNCTION: initialize a character
                   1304: /
                   1305: / AUTHOR: E. A. Estes, 12/4/85
                   1306: /
                   1307: / ARGUMENTS:
                   1308: /      struct player *playerp - pointer to structure to init
                   1309: /
                   1310: / RETURN VALUE: none
                   1311: /
                   1312: / MODULES CALLED: floor(), drandom()
                   1313: /
                   1314: / GLOBAL INPUTS: none
                   1315: /
                   1316: / GLOBAL OUTPUTS: none
                   1317: /
                   1318: / DESCRIPTION:
                   1319: /      Put a bunch of default values in the given structure.
                   1320: /
                   1321: /************************************************************************/
                   1322: 
                   1323: initplayer(playerp)
                   1324: register struct  player   *playerp;
                   1325: {
                   1326:     playerp->p_experience =
                   1327:     playerp->p_level =
                   1328:     playerp->p_strength =
                   1329:     playerp->p_sword =
                   1330:     playerp->p_might =
                   1331:     playerp->p_energy =
                   1332:     playerp->p_maxenergy =
                   1333:     playerp->p_shield =
                   1334:     playerp->p_quickness =
                   1335:     playerp->p_quksilver =
                   1336:     playerp->p_speed =
                   1337:     playerp->p_magiclvl =
                   1338:     playerp->p_mana =
                   1339:     playerp->p_brains =
                   1340:     playerp->p_poison =
                   1341:     playerp->p_gems =
                   1342:     playerp->p_sin =
                   1343:     playerp->p_1scratch =
                   1344:     playerp->p_2scratch = 0.0;
                   1345: 
                   1346:     playerp->p_gold = ROLL(50.0, 75.0) + 0.1;  /* give some gold */
                   1347: 
                   1348:     playerp->p_x = ROLL(-125.0, 251.0);
                   1349:     playerp->p_y = ROLL(-125.0, 251.0);                /* give random x, y */
                   1350: 
                   1351:     /* clear ring */
                   1352:     playerp->p_ring.ring_type = R_NONE;
                   1353:     playerp->p_ring.ring_duration = 0;
                   1354:     playerp->p_ring.ring_inuse = FALSE;
                   1355: 
                   1356:     playerp->p_age = 0L;
                   1357: 
                   1358:     playerp->p_degenerated = 1;                        /* don't degenerate initially */
                   1359: 
                   1360:     playerp->p_type = C_FIGHTER;               /* default */
                   1361:     playerp->p_specialtype = SC_NONE;
                   1362:     playerp->p_lives =
                   1363:     playerp->p_crowns = 
                   1364:     playerp->p_charms =
                   1365:     playerp->p_amulets =
                   1366:     playerp->p_holywater =
                   1367:     playerp->p_lastused = 0;
                   1368:     playerp->p_status = S_NOTUSED;
                   1369:     playerp->p_tampered = T_OFF;
                   1370:     playerp->p_istat = I_OFF;
                   1371: 
                   1372:     playerp->p_palantir =
                   1373:     playerp->p_blessing =
                   1374:     playerp->p_virgin =
                   1375:     playerp->p_blindness = FALSE;
                   1376: 
                   1377:     playerp->p_name[0] =
                   1378:     playerp->p_password[0] =
                   1379:     playerp->p_login[0] = '\0';
                   1380: }
                   1381: /**/
                   1382: /************************************************************************
                   1383: /
                   1384: / FUNCTION NAME: readmessage()
                   1385: /
                   1386: / FUNCTION: read message from other players
                   1387: /
                   1388: / AUTHOR: E. A. Estes, 12/4/85
                   1389: /
                   1390: / ARGUMENTS: none
                   1391: /
                   1392: / RETURN VALUE: none
                   1393: /
                   1394: / MODULES CALLED: fseek(), fgets(), wmove(), waddstr(), wclrtoeol()
                   1395: /
                   1396: / GLOBAL INPUTS: *stdscr, Databuf[], *Messagefp
                   1397: /
                   1398: / GLOBAL OUTPUTS: none
                   1399: /
                   1400: / DESCRIPTION:
                   1401: /      If there is a message from other players, print it.
                   1402: /
                   1403: /************************************************************************/
                   1404: 
                   1405: readmessage()
                   1406: {
                   1407:     move(3, 0);
                   1408:     clrtoeol();
                   1409:     fseek(Messagefp, 0L, 0);
                   1410:     if (fgets(Databuf, SZ_DATABUF, Messagefp) != NULL)
                   1411:        addstr(Databuf);
                   1412: }
                   1413: /**/
                   1414: /************************************************************************
                   1415: /
                   1416: / FUNCTION NAME: error()
                   1417: /
                   1418: / FUNCTION: process evironment error
                   1419: /
                   1420: / AUTHOR: E. A. Estes, 12/4/85
                   1421: /
                   1422: / ARGUMENTS:
                   1423: /      char *whichfile - pointer to name of file which caused error
                   1424: /
                   1425: / RETURN VALUE: none
                   1426: /
                   1427: / MODULES CALLED: wclear(), cleanup()
                   1428: /
                   1429: / GLOBAL INPUTS: errno, *stdscr, printw(), printf(), Windows
                   1430: /
                   1431: / GLOBAL OUTPUTS: none
                   1432: /
                   1433: / DESCRIPTION:
                   1434: /      Print message about offending file, and exit.
                   1435: /
                   1436: /************************************************************************/
                   1437: 
                   1438: error(whichfile)
                   1439: char   *whichfile;
                   1440: {
                   1441: extern int errno;
                   1442: extern printw(), printf();
                   1443: int    (*funcp)();
                   1444: 
                   1445:     if (Windows)
                   1446:        {
                   1447:        funcp = printw;
                   1448:        clear();
                   1449:        }
                   1450:     else
                   1451:        funcp = printf;
                   1452: 
                   1453:     (*funcp)("An unrecoverable error has occurred reading %s.  (errno = %d)\n", whichfile, errno);
                   1454:     (*funcp)("Please run 'setup' to determine the problem.\n");
                   1455:     cleanup(TRUE);
                   1456:     /*NOTREACHED*/
                   1457: }
                   1458: /**/
                   1459: /************************************************************************
                   1460: /
                   1461: / FUNCTION NAME: distance()
                   1462: /
                   1463: / FUNCTION: calculate distance between two points
                   1464: /
                   1465: / AUTHOR: E. A. Estes, 12/4/85
                   1466: /
                   1467: / ARGUMENTS: 
                   1468: /      double x1, y1 - x, y coordinates of first point
                   1469: /      double x2, y2 - x, y coordinates of second point
                   1470: /
                   1471: / RETURN VALUE: distance between the two points
                   1472: /
                   1473: / MODULES CALLED: sqrt()
                   1474: /
                   1475: / GLOBAL INPUTS: none
                   1476: /
                   1477: / GLOBAL OUTPUTS: none
                   1478: /
                   1479: / DESCRIPTION:
                   1480: /      This function is provided because someone's hypot() library function
                   1481: /      fails if x1 == x2 && y1 == y2.
                   1482: /
                   1483: /************************************************************************/
                   1484: 
                   1485: double
                   1486: distance(x1, x2, y1, y2)
                   1487: double x1, x2, y1, y2;
                   1488: {
                   1489: double deltax, deltay;
                   1490: 
                   1491:     deltax = x1 - x2;
                   1492:     deltay = y1 - y2;
                   1493:     return(sqrt(deltax * deltax + deltay * deltay));
                   1494: }
                   1495: 
                   1496: /**/
                   1497: /************************************************************************
                   1498: /
                   1499: / FUNCTION NAME: ill_sig()
                   1500: /
                   1501: / FUNCTION: exit upon trapping an illegal signal
                   1502: /
                   1503: / AUTHOR: E. A. Estes, 12/4/85
                   1504: /
                   1505: / ARGUMENTS:
                   1506: /      int whichsig - signal which occured to cause jump to here
                   1507: /
                   1508: / RETURN VALUE: none
                   1509: /
                   1510: / MODULES CALLED: wclear(), printw(), cleanup()
                   1511: /
                   1512: / GLOBAL INPUTS: *stdscr
                   1513: /
                   1514: / GLOBAL OUTPUTS: none
                   1515: /
                   1516: / DESCRIPTION:
                   1517: /      When an illegal signal is caught, print a message, and cleanup.
                   1518: /
                   1519: /************************************************************************/
                   1520: 
                   1521: ill_sig(whichsig)
                   1522: int whichsig;
                   1523: {
                   1524:     clear();
                   1525:     if (!(whichsig == SIGINT || whichsig == SIGQUIT))
                   1526:        printw("Error: caught signal # %d.\n", whichsig);
                   1527:     cleanup(TRUE);
                   1528:     /*NOTREACHED*/
                   1529: }
                   1530: /**/
                   1531: /************************************************************************
                   1532: /
                   1533: / FUNCTION NAME: descrstatus()
                   1534: /
                   1535: / FUNCTION: return a string describing the player status
                   1536: /
                   1537: / AUTHOR: E. A. Estes, 3/3/86
                   1538: /
                   1539: / ARGUMENTS:
                   1540: /      struct player playerp - pointer to player structure to describe
                   1541: /
                   1542: / RETURN VALUE: string describing player's status
                   1543: /
                   1544: / MODULES CALLED: none
                   1545: /
                   1546: / GLOBAL INPUTS: none
                   1547: /
                   1548: / GLOBAL OUTPUTS: none
                   1549: /
                   1550: / DESCRIPTION:
                   1551: /      Return verbal description of player status.
                   1552: /      If player status is S_PLAYING, check for low energy and blindness.
                   1553: /
                   1554: /************************************************************************/
                   1555: 
                   1556: char   *
                   1557: descrstatus(playerp)
                   1558: register struct player *playerp;
                   1559: {
                   1560:     switch (playerp->p_status)
                   1561:        {
                   1562:        case S_PLAYING:
                   1563:            if (playerp->p_energy < 0.2 * (playerp->p_maxenergy + playerp->p_shield))
                   1564:                return("Low Energy");
                   1565:            else if (playerp->p_blindness)
                   1566:                return("Blind");
                   1567:            else
                   1568:                return("In game");
                   1569: 
                   1570:        case S_CLOAKED:
                   1571:            return("Cloaked");
                   1572: 
                   1573:        case S_INBATTLE:
                   1574:            return("In Battle");
                   1575: 
                   1576:        case S_MONSTER:
                   1577:            return("Encounter");
                   1578: 
                   1579:        case S_TRADING:
                   1580:            return("Trading");
                   1581: 
                   1582:        case S_OFF:
                   1583:            return("Off");
                   1584: 
                   1585:        case S_HUNGUP:
                   1586:            return("Hung up");
                   1587: 
                   1588:        default:
                   1589:            return("");
                   1590:        }
                   1591: }
                   1592: /**/
                   1593: /************************************************************************
                   1594: /
                   1595: / FUNCTION NAME: drandom()
                   1596: /
                   1597: / FUNCTION: return a random floating point number from 0.0 < 1.0
                   1598: /
                   1599: / AUTHOR: E. A. Estes, 2/7/86
                   1600: /
                   1601: / ARGUMENTS: none
                   1602: /
                   1603: / RETURN VALUE: none
                   1604: /
                   1605: / MODULES CALLED: random()
                   1606: /
                   1607: / GLOBAL INPUTS: none
                   1608: /
                   1609: / GLOBAL OUTPUTS: none
                   1610: /
                   1611: / DESCRIPTION:
                   1612: /      Convert random integer from library routine into a floating
                   1613: /      point number, and divide by the largest possible random number.
                   1614: /      We mask large integers with 32767 to handle sites that return
                   1615: /      31 bit random integers.
                   1616: /
                   1617: /************************************************************************/
                   1618: 
                   1619: double
                   1620: drandom()
                   1621: {
                   1622:     if (sizeof(int) != 2)
                   1623:        /* use only low bits */
                   1624:        return((double) (random() & 0x7fff) / 32768.0);
                   1625:     else
                   1626:        return((double) random() / 32768.0);
                   1627: }
                   1628: /**/
                   1629: /************************************************************************
                   1630: /
                   1631: / FUNCTION NAME: collecttaxes()
                   1632: /
                   1633: / FUNCTION: collect taxes from current player
                   1634: /
                   1635: / AUTHOR: E. A. Estes, 2/7/86
                   1636: /
                   1637: / ARGUMENTS:
                   1638: /      double gold - amount of gold to tax
                   1639: /      double gems - amount of gems to tax
                   1640: /
                   1641: / RETURN VALUE: none
                   1642: /
                   1643: / MODULES CALLED: fread(), fseek(), fopen(), floor(), fwrite(), fclose()
                   1644: /
                   1645: / GLOBAL INPUTS: Player
                   1646: /
                   1647: / GLOBAL OUTPUTS: Player
                   1648: /
                   1649: / DESCRIPTION:
                   1650: /      Pay taxes on gold and gems.  If the player does not have enough
                   1651: /      gold to pay taxes on the added gems, convert some gems to gold.
                   1652: /      Add taxes to tax data base; add remaining gold and gems to
                   1653: /      player's cache.
                   1654: /
                   1655: /************************************************************************/
                   1656: 
                   1657: collecttaxes(gold, gems)
                   1658: double gold;
                   1659: double gems;
                   1660: {
                   1661: FILE   *fp;            /* to update Goldfile */
                   1662: double dtemp;          /* for temporary calculations */
                   1663: double taxes;          /* tax liability */
                   1664: 
                   1665:     /* add to cache */
                   1666:     Player.p_gold += gold;
                   1667:     Player.p_gems += gems;
                   1668: 
                   1669:     /* calculate tax liability */
                   1670:     taxes = N_TAXAMOUNT / 100.0 * (N_GEMVALUE * gems + gold);
                   1671: 
                   1672:     if (Player.p_gold < taxes)
                   1673:        /* not enough gold to pay taxes, must convert some gems to gold */
                   1674:        {
                   1675:        dtemp = floor(taxes / N_GEMVALUE + 1.0); /* number of gems to convert */
                   1676: 
                   1677:        if (Player.p_gems >= dtemp)
                   1678:            /* player has enough to convert */
                   1679:            {
                   1680:            Player.p_gems -= dtemp;
                   1681:            Player.p_gold += dtemp * N_GEMVALUE;
                   1682:            }
                   1683:        else
                   1684:            /* take everything; this should never happen */
                   1685:            {
                   1686:            Player.p_gold += Player.p_gems * N_GEMVALUE;
                   1687:            Player.p_gems = 0.0;
                   1688:            taxes = Player.p_gold;
                   1689:            }
                   1690:        }
                   1691: 
                   1692:     Player.p_gold -= taxes;
                   1693: 
                   1694:     if ((fp = fopen(_PATH_GOLD, "r+")) != NULL)
                   1695:        /* update taxes */
                   1696:        {
                   1697:        dtemp = 0.0;
                   1698:        fread((char *) &dtemp, sizeof(double), 1, fp);
                   1699:        dtemp += floor(taxes);
                   1700:        fseek(fp, 0L, 0);
                   1701:        fwrite((char *) &dtemp, sizeof(double), 1, fp);
                   1702:        fclose(fp);
                   1703:        }
                   1704: }

unix.superglobalmegacorp.com

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