134606Sbostic /* 234606Sbostic * misc.c Phantasia miscellaneous support routines 334606Sbostic */ 434606Sbostic 534606Sbostic #include "include.h" 634606Sbostic 734606Sbostic /************************************************************************ 834606Sbostic / 934606Sbostic / FUNCTION NAME: movelevel() 1034606Sbostic / 1134606Sbostic / FUNCTION: move player to new level 1234606Sbostic / 1334606Sbostic / AUTHOR: E. A. Estes, 12/4/85 1434606Sbostic / 1534606Sbostic / ARGUMENTS: none 1634606Sbostic / 1734606Sbostic / RETURN VALUE: none 1834606Sbostic / 1934606Sbostic / MODULES CALLED: death(), floor(), wmove(), drandom(), waddstr(), explevel() 2034606Sbostic / 2134606Sbostic / GLOBAL INPUTS: Player, *stdscr, *Statptr, Stattable[] 2234606Sbostic / 2334606Sbostic / GLOBAL OUTPUTS: Player, Changed 2434606Sbostic / 2534606Sbostic / DESCRIPTION: 2634606Sbostic / Use lookup table to increment important statistics when 2734606Sbostic / progressing to new experience level. 2834606Sbostic / Players are rested to maximum as a bonus for making a new 2934606Sbostic / level. 3034606Sbostic / Check for council of wise, and being too big to be king. 3134606Sbostic / 3234606Sbostic /************************************************************************/ 3334606Sbostic 3434606Sbostic movelevel() 3534606Sbostic { 3634606Sbostic register struct charstats *statptr; /* for pointing into Stattable */ 3734606Sbostic double new; /* new level */ 3834606Sbostic double inc; /* increment between new and old levels */ 3934606Sbostic 4034606Sbostic Changed = TRUE; 4134606Sbostic 4234606Sbostic if (Player.p_type == C_EXPER) 4334606Sbostic /* roll a type to use for increment */ 4434606Sbostic statptr = &Stattable[(int) ROLL(C_MAGIC, C_HALFLING - C_MAGIC + 1)]; 4534606Sbostic else 4634606Sbostic statptr = Statptr; 4734606Sbostic 4834606Sbostic new = explevel(Player.p_experience); 4934606Sbostic inc = new - Player.p_level; 5034606Sbostic Player.p_level = new; 5134606Sbostic 5234606Sbostic /* add increments to statistics */ 5334606Sbostic Player.p_strength += statptr->c_strength.increase * inc; 5434606Sbostic Player.p_mana += statptr->c_mana.increase * inc; 5534606Sbostic Player.p_brains += statptr->c_brains.increase * inc; 5634606Sbostic Player.p_magiclvl += statptr->c_magiclvl.increase * inc; 5734606Sbostic Player.p_maxenergy += statptr->c_energy.increase * inc; 5834606Sbostic 5934606Sbostic /* rest to maximum upon reaching new level */ 6034606Sbostic Player.p_energy = Player.p_maxenergy + Player.p_shield; 6134606Sbostic 6234606Sbostic if (Player.p_crowns > 0 && Player.p_level >= 1000.0) 6334606Sbostic /* no longer able to be king -- turn crowns into cash */ 6434606Sbostic { 6534606Sbostic Player.p_gold += ((double) Player.p_crowns) * 5000.0; 6634606Sbostic Player.p_crowns = 0; 6734606Sbostic } 6834606Sbostic 6934606Sbostic if (Player.p_level >= 3000.0 && Player.p_specialtype < SC_COUNCIL) 7034606Sbostic /* make a member of the council */ 7134606Sbostic { 7234606Sbostic mvaddstr(6, 0, "You have made it to the Council of the Wise.\n"); 7334606Sbostic addstr("Good Luck on your search for the Holy Grail.\n"); 7434606Sbostic 7534606Sbostic Player.p_specialtype = SC_COUNCIL; 7634606Sbostic 7734606Sbostic /* no rings for council and above */ 7834606Sbostic Player.p_ring.ring_type = R_NONE; 7934606Sbostic Player.p_ring.ring_duration = 0; 8034606Sbostic 8134606Sbostic Player.p_lives = 3; /* three extra lives */ 8234606Sbostic } 8334606Sbostic 8434606Sbostic if (Player.p_level > 9999.0 && Player.p_specialtype != SC_VALAR) 8534606Sbostic death("Old age"); 8634606Sbostic } 8734606Sbostic /**/ 8834606Sbostic /************************************************************************ 8934606Sbostic / 9034606Sbostic / FUNCTION NAME: descrlocation() 9134606Sbostic / 9234606Sbostic / FUNCTION: return a formatted description of location 9334606Sbostic / 9434606Sbostic / AUTHOR: E. A. Estes, 12/4/85 9534606Sbostic / 9634606Sbostic / ARGUMENTS: 9734606Sbostic / struct player playerp - pointer to player structure 9834606Sbostic / bool shortflag - set if short form is desired 9934606Sbostic / 10034606Sbostic / RETURN VALUE: pointer to string containing result 10134606Sbostic / 10234606Sbostic / MODULES CALLED: fabs(), floor(), sprintf(), distance() 10334606Sbostic / 10434606Sbostic / GLOBAL INPUTS: Databuf[] 10534606Sbostic / 10634606Sbostic / GLOBAL OUTPUTS: none 10734606Sbostic / 10834606Sbostic / DESCRIPTION: 10934606Sbostic / Look at coordinates and return an appropriately formatted 11034606Sbostic / string. 11134606Sbostic / 11234606Sbostic /************************************************************************/ 11334606Sbostic 11434606Sbostic char * 11534606Sbostic descrlocation(playerp, shortflag) 11634606Sbostic struct player *playerp; 11734606Sbostic bool shortflag; 11834606Sbostic { 11934606Sbostic double circle; /* corresponding circle for coordinates */ 12034606Sbostic register int quadrant; /* quandrant of grid */ 12134606Sbostic register char *label; /* pointer to place name */ 12234606Sbostic static char *nametable[4][4] = /* names of places */ 12334606Sbostic { 12434606Sbostic "Anorien", "Ithilien", "Rohan", "Lorien", 12534606Sbostic "Gondor", "Mordor", "Dunland", "Rovanion", 12634606Sbostic "South Gondor", "Khand", "Eriador", "The Iron Hills", 12734606Sbostic "Far Harad", "Near Harad", "The Northern Waste", "Rhun" 12834606Sbostic }; 12934606Sbostic 13034606Sbostic if (playerp->p_specialtype == SC_VALAR) 13134606Sbostic return(" is in Valhala"); 13234606Sbostic else if ((circle = CIRCLE(playerp->p_x, playerp->p_y)) >= 1000.0) 13334606Sbostic { 13434606Sbostic if (MAX(fabs(playerp->p_x), fabs(playerp->p_y)) > D_BEYOND) 13534606Sbostic label = "The Point of No Return"; 13634606Sbostic else 13734606Sbostic label = "The Ashen Mountains"; 13834606Sbostic } 13934606Sbostic else if (circle >= 55) 14034606Sbostic label = "Morannon"; 14134606Sbostic else if (circle >= 35) 14234606Sbostic label = "Kennaquahair"; 14334606Sbostic else if (circle >= 20) 14434606Sbostic label = "The Dead Marshes"; 14534606Sbostic else if (circle >= 9) 14634606Sbostic label = "The Outer Waste"; 14734606Sbostic else if (circle >= 5) 14834606Sbostic label = "The Moors Adventurous"; 14934606Sbostic else 15034606Sbostic { 15134606Sbostic if (playerp->p_x == 0.0 && playerp->p_y == 0.0) 15234606Sbostic label = "The Lord's Chamber"; 15334606Sbostic else 15434606Sbostic { 15534606Sbostic /* this expression is split to prevent compiler loop with some compilers */ 15634606Sbostic quadrant = ((playerp->p_x > 0.0) ? 1 : 0); 15734606Sbostic quadrant += ((playerp->p_y >= 0.0) ? 2 : 0); 15834606Sbostic label = nametable[((int) circle) - 1][quadrant]; 15934606Sbostic } 16034606Sbostic } 16134606Sbostic 16234606Sbostic if (shortflag) 16334606Sbostic sprintf(Databuf, "%.29s", label); 16434606Sbostic else 16534606Sbostic sprintf(Databuf, " is in %s (%.0f,%.0f)", label, playerp->p_x, playerp->p_y); 16634606Sbostic 16734606Sbostic return(Databuf); 16834606Sbostic } 16934606Sbostic /**/ 17034606Sbostic /************************************************************************ 17134606Sbostic / 17234606Sbostic / FUNCTION NAME: tradingpost() 17334606Sbostic / 17434606Sbostic / FUNCTION: do trading post stuff 17534606Sbostic / 17634606Sbostic / AUTHOR: E. A. Estes, 12/4/85 17734606Sbostic / 17834606Sbostic / ARGUMENTS: none 17934606Sbostic / 18034606Sbostic / RETURN VALUE: none 18134606Sbostic / 18234606Sbostic / MODULES CALLED: writerecord(), adjuststats(), fabs(), more(), sqrt(), 18334606Sbostic / sleep(), floor(), wmove(), drandom(), wclear(), printw(), 18434606Sbostic / altercoordinates(), infloat(), waddstr(), wrefresh(), mvprintw(), getanswer(), 18534606Sbostic / wclrtoeol(), wclrtobot() 18634606Sbostic / 18734606Sbostic / GLOBAL INPUTS: Menu[], Circle, Player, *stdscr, Fileloc, Nobetter[] 18834606Sbostic / 18934606Sbostic / GLOBAL OUTPUTS: Player 19034606Sbostic / 19134606Sbostic / DESCRIPTION: 19234606Sbostic / Different trading posts have different items. 19334606Sbostic / Merchants cannot be cheated, but they can be dishonest 19434606Sbostic / themselves. 19534606Sbostic / 19634606Sbostic / Shields, swords, and quicksilver are not cumulative. This is 19734606Sbostic / one major area of complaint, but there are two reasons for this: 19834606Sbostic / 1) It becomes MUCH too easy to make very large versions 19934606Sbostic / of these items. 20034606Sbostic / 2) In the real world, one cannot simply weld two swords 20134606Sbostic / together to make a bigger one. 20234606Sbostic / 20334606Sbostic / At one time, it was possible to sell old weapons at half the purchase 20434606Sbostic / price. This resulted in huge amounts of gold floating around, 20534606Sbostic / and the game lost much of its challenge. 20634606Sbostic / 20734606Sbostic / Also, purchasing gems defeats the whole purpose of gold. Gold 20834606Sbostic / is small change for lower level players. They really shouldn't 20934606Sbostic / be able to accumulate more than enough gold for a small sword or 21034606Sbostic / a few books. Higher level players shouldn't even bother to pick 21134606Sbostic / up gold, except maybe to buy mana once in a while. 21234606Sbostic / 21334606Sbostic /************************************************************************/ 21434606Sbostic 21534606Sbostic tradingpost() 21634606Sbostic { 21734606Sbostic double numitems; /* number of items to purchase */ 21834606Sbostic double cost; /* cost of purchase */ 21934606Sbostic double blessingcost; /* cost of blessing */ 22034606Sbostic int ch; /* input */ 22134606Sbostic register int size; /* size of the trading post */ 22234606Sbostic register int loop; /* loop counter */ 22334606Sbostic int cheat = 0; /* number of times player has tried to cheat */ 22434606Sbostic bool dishonest = FALSE;/* set when merchant is dishonest */ 22534606Sbostic 22634606Sbostic Player.p_status = S_TRADING; 22734606Sbostic writerecord(&Player, Fileloc); 22834606Sbostic 22934606Sbostic clear(); 23034606Sbostic addstr("You are at a trading post. All purchases must be made with gold."); 23134606Sbostic 23234606Sbostic size = sqrt(fabs(Player.p_x / 100)) + 1; 23334606Sbostic size = MIN(7, size); 23434606Sbostic 23534606Sbostic /* set up cost of blessing */ 23634606Sbostic blessingcost = 1000.0 * (Player.p_level + 5.0); 23734606Sbostic 23834606Sbostic /* print Menu */ 23934606Sbostic move(7, 0); 24034606Sbostic for (loop = 0; loop < size; ++loop) 24134606Sbostic /* print Menu */ 24234606Sbostic { 24334606Sbostic if (loop == 6) 24434606Sbostic cost = blessingcost; 24534606Sbostic else 24634606Sbostic cost = Menu[loop].cost; 24734606Sbostic printw("(%d) %-12s: %6.0f\n", loop + 1, Menu[loop].item, cost); 24834606Sbostic } 24934606Sbostic 25034606Sbostic mvprintw(5, 0, "L:Leave P:Purchase S:Sell Gems ? "); 25134606Sbostic 25234606Sbostic for (;;) 25334606Sbostic { 25434606Sbostic adjuststats(); /* truncate any bad values */ 25534606Sbostic 25634606Sbostic /* print some important statistics */ 25734606Sbostic mvprintw(1, 0, "Gold: %9.0f Gems: %9.0f Level: %6.0f Charms: %6d\n", 25834606Sbostic Player.p_gold, Player.p_gems, Player.p_level, Player.p_charms); 25934606Sbostic printw("Shield: %9.0f Sword: %9.0f Quicksilver:%3.0f Blessed: %s\n", 26034606Sbostic Player.p_shield, Player.p_sword, Player.p_quksilver, 26134606Sbostic (Player.p_blessing ? " True" : "False")); 26234606Sbostic printw("Brains: %9.0f Mana: %9.0f", Player.p_brains, Player.p_mana); 26334606Sbostic 26434606Sbostic move(5, 36); 26534606Sbostic ch = getanswer("LPS", FALSE); 26634606Sbostic move(15, 0); 26734606Sbostic clrtobot(); 26834606Sbostic switch(ch) 26934606Sbostic { 27034606Sbostic case 'L': /* leave */ 27134606Sbostic case '\n': 27234606Sbostic altercoordinates(0.0, 0.0, A_NEAR); 27334606Sbostic return; 27434606Sbostic 27534606Sbostic case 'P': /* make purchase */ 27634606Sbostic mvaddstr(15, 0, "What what would you like to buy ? "); 27734606Sbostic ch = getanswer(" 1234567", FALSE); 27834606Sbostic move(15, 0); 27934606Sbostic clrtoeol(); 28034606Sbostic 28134606Sbostic if (ch - '0' > size) 28234606Sbostic addstr("Sorry, this merchant doesn't have that."); 28334606Sbostic else 28434606Sbostic switch (ch) 28534606Sbostic { 28634606Sbostic case '1': 28734606Sbostic printw("Mana is one per %.0f gold piece. How many do you want (%.0f max) ? ", 28834606Sbostic Menu[0].cost, floor(Player.p_gold / Menu[0].cost)); 28934606Sbostic cost = (numitems = floor(infloat())) * Menu[0].cost; 29034606Sbostic 29134606Sbostic if (cost > Player.p_gold || numitems < 0) 29234606Sbostic ++cheat; 29334606Sbostic else 29434606Sbostic { 29534606Sbostic cheat = 0; 29634606Sbostic Player.p_gold -= cost; 29734606Sbostic if (drandom() < 0.02) 29834606Sbostic dishonest = TRUE; 29934606Sbostic else 30034606Sbostic Player.p_mana += numitems; 30134606Sbostic } 30234606Sbostic break; 30334606Sbostic 30434606Sbostic case '2': 30534606Sbostic printw("Shields are %.0f per +1. How many do you want (%.0f max) ? ", 30634606Sbostic Menu[1].cost, floor(Player.p_gold / Menu[1].cost)); 30734606Sbostic cost = (numitems = floor(infloat())) * Menu[1].cost; 30834606Sbostic 30934606Sbostic if (numitems == 0.0) 31034606Sbostic break; 31134606Sbostic else if (cost > Player.p_gold || numitems < 0) 31234606Sbostic ++cheat; 31334606Sbostic else if (numitems < Player.p_shield) 31434606Sbostic NOBETTER(); 31534606Sbostic else 31634606Sbostic { 31734606Sbostic cheat = 0; 31834606Sbostic Player.p_gold -= cost; 31934606Sbostic if (drandom() < 0.02) 32034606Sbostic dishonest = TRUE; 32134606Sbostic else 32234606Sbostic Player.p_shield = numitems; 32334606Sbostic } 32434606Sbostic break; 32534606Sbostic 32634606Sbostic case '3': 32734606Sbostic printw("A book costs %.0f gp. How many do you want (%.0f max) ? ", 32834606Sbostic Menu[2].cost, floor(Player.p_gold / Menu[2].cost)); 32934606Sbostic cost = (numitems = floor(infloat())) * Menu[2].cost; 33034606Sbostic 33134606Sbostic if (cost > Player.p_gold || numitems < 0) 33234606Sbostic ++cheat; 33334606Sbostic else 33434606Sbostic { 33534606Sbostic cheat = 0; 33634606Sbostic Player.p_gold -= cost; 33734606Sbostic if (drandom() < 0.02) 33834606Sbostic dishonest = TRUE; 33934606Sbostic else if (drandom() * numitems > Player.p_level / 10.0 34034606Sbostic && numitems != 1) 34134606Sbostic { 34234606Sbostic printw("\nYou blew your mind!\n"); 34334606Sbostic Player.p_brains /= 5; 34434606Sbostic } 34534606Sbostic else 34634606Sbostic { 34734606Sbostic Player.p_brains += floor(numitems) * ROLL(20, 8); 34834606Sbostic } 34934606Sbostic } 35034606Sbostic break; 35134606Sbostic 35234606Sbostic case '4': 35334606Sbostic printw("Swords are %.0f gp per +1. How many + do you want (%.0f max) ? ", 35434606Sbostic Menu[3].cost, floor(Player.p_gold / Menu[3].cost)); 35534606Sbostic cost = (numitems = floor(infloat())) * Menu[3].cost; 35634606Sbostic 35734606Sbostic if (numitems == 0.0) 35834606Sbostic break; 35934606Sbostic else if (cost > Player.p_gold || numitems < 0) 36034606Sbostic ++cheat; 36134606Sbostic else if (numitems < Player.p_sword) 36234606Sbostic NOBETTER(); 36334606Sbostic else 36434606Sbostic { 36534606Sbostic cheat = 0; 36634606Sbostic Player.p_gold -= cost; 36734606Sbostic if (drandom() < 0.02) 36834606Sbostic dishonest = TRUE; 36934606Sbostic else 37034606Sbostic Player.p_sword = numitems; 37134606Sbostic } 37234606Sbostic break; 37334606Sbostic 37434606Sbostic case '5': 37534606Sbostic printw("A charm costs %.0f gp. How many do you want (%.0f max) ? ", 37634606Sbostic Menu[4].cost, floor(Player.p_gold / Menu[4].cost)); 37734606Sbostic cost = (numitems = floor(infloat())) * Menu[4].cost; 37834606Sbostic 37934606Sbostic if (cost > Player.p_gold || numitems < 0) 38034606Sbostic ++cheat; 38134606Sbostic else 38234606Sbostic { 38334606Sbostic cheat = 0; 38434606Sbostic Player.p_gold -= cost; 38534606Sbostic if (drandom() < 0.02) 38634606Sbostic dishonest = TRUE; 38734606Sbostic else 38834606Sbostic Player.p_charms += numitems; 38934606Sbostic } 39034606Sbostic break; 39134606Sbostic 39234606Sbostic case '6': 39334606Sbostic printw("Quicksilver is %.0f gp per +1. How many + do you want (%.0f max) ? ", 39434606Sbostic Menu[5].cost, floor(Player.p_gold / Menu[5].cost)); 39534606Sbostic cost = (numitems = floor(infloat())) * Menu[5].cost; 39634606Sbostic 39734606Sbostic if (numitems == 0.0) 39834606Sbostic break; 39934606Sbostic else if (cost > Player.p_gold || numitems < 0) 40034606Sbostic ++cheat; 40134606Sbostic else if (numitems < Player.p_quksilver) 40234606Sbostic NOBETTER(); 40334606Sbostic else 40434606Sbostic { 40534606Sbostic cheat = 0; 40634606Sbostic Player.p_gold -= cost; 40734606Sbostic if (drandom() < 0.02) 40834606Sbostic dishonest = TRUE; 40934606Sbostic else 41034606Sbostic Player.p_quksilver = numitems; 41134606Sbostic } 41234606Sbostic break; 41334606Sbostic 41434606Sbostic case '7': 41534606Sbostic if (Player.p_blessing) 41634606Sbostic { 41734606Sbostic addstr("You already have a blessing."); 41834606Sbostic break; 41934606Sbostic } 42034606Sbostic 42134606Sbostic printw("A blessing requires a %.0f gp donation. Still want one ? ", blessingcost); 42234606Sbostic ch = getanswer("NY", FALSE); 42334606Sbostic 42434606Sbostic if (ch == 'Y') 42534606Sbostic if (Player.p_gold < blessingcost) 42634606Sbostic ++cheat; 42734606Sbostic else 42834606Sbostic { 42934606Sbostic cheat = 0; 43034606Sbostic Player.p_gold -= blessingcost; 43134606Sbostic if (drandom() < 0.02) 43234606Sbostic dishonest = TRUE; 43334606Sbostic else 43434606Sbostic Player.p_blessing = TRUE; 43534606Sbostic } 43634606Sbostic break; 43734606Sbostic } 43834606Sbostic break; 43934606Sbostic 44034606Sbostic case 'S': /* sell gems */ 44134606Sbostic mvprintw(15, 0, "A gem is worth %.0f gp. How many do you want to sell (%.0f max) ? ", 44234606Sbostic (double) N_GEMVALUE, Player.p_gems); 44334606Sbostic numitems = floor(infloat()); 44434606Sbostic 44534606Sbostic if (numitems > Player.p_gems || numitems < 0) 44634606Sbostic ++cheat; 44734606Sbostic else 44834606Sbostic { 44934606Sbostic cheat = 0; 45034606Sbostic Player.p_gems -= numitems; 45134606Sbostic Player.p_gold += numitems * N_GEMVALUE; 45234606Sbostic } 45334606Sbostic } 45434606Sbostic 45534606Sbostic if (cheat == 1) 45634606Sbostic mvaddstr(17, 0, "Come on, merchants aren't stupid. Stop cheating.\n"); 45734606Sbostic else if (cheat == 2) 45834606Sbostic { 45934606Sbostic mvaddstr(17, 0, "You had your chance. This merchant happens to be\n"); 46034606Sbostic printw("a %.0f level magic user, and you made %s mad!\n", 46134606Sbostic ROLL(Circle * 20.0, 40.0), (drandom() < 0.5) ? "him" : "her"); 46234606Sbostic altercoordinates(0.0, 0.0, A_FAR); 46334606Sbostic Player.p_energy /= 2.0; 46434606Sbostic ++Player.p_sin; 46534606Sbostic more(23); 46634606Sbostic return; 46734606Sbostic } 46834606Sbostic else if (dishonest) 46934606Sbostic { 47034606Sbostic mvaddstr(17, 0, "The merchant stole your money!"); 47134606Sbostic refresh(); 47234606Sbostic altercoordinates(Player.p_x - Player.p_x / 10.0, 47334606Sbostic Player.p_y - Player.p_y / 10.0, A_SPECIFIC); 47434606Sbostic sleep(2); 47534606Sbostic return; 47634606Sbostic } 47734606Sbostic } 47834606Sbostic } 47934606Sbostic /**/ 48034606Sbostic /************************************************************************ 48134606Sbostic / 48234606Sbostic / FUNCTION NAME: displaystats() 48334606Sbostic / 48434606Sbostic / FUNCTION: print out important player statistics 48534606Sbostic / 48634606Sbostic / AUTHOR: E. A. Estes, 12/4/85 48734606Sbostic / 48834606Sbostic / ARGUMENTS: none 48934606Sbostic / 49034606Sbostic / RETURN VALUE: none 49134606Sbostic / 49234606Sbostic / MODULES CALLED: descrstatus(), descrlocation(), mvprintw() 49334606Sbostic / 49434606Sbostic / GLOBAL INPUTS: Users, Player 49534606Sbostic / 49634606Sbostic / GLOBAL OUTPUTS: none 49734606Sbostic / 49834606Sbostic / DESCRIPTION: 49934606Sbostic / Important player statistics are printed on the screen. 50034606Sbostic / 50134606Sbostic /************************************************************************/ 50234606Sbostic 50334606Sbostic displaystats() 50434606Sbostic { 50534606Sbostic mvprintw(0, 0, "%s%s\n", Player.p_name, descrlocation(&Player, FALSE)); 50634606Sbostic mvprintw(1, 0, "Level :%7.0f Energy :%9.0f(%9.0f) Mana :%9.0f Users:%3d\n", 50734606Sbostic Player.p_level, Player.p_energy, Player.p_maxenergy + Player.p_shield, 50834606Sbostic Player.p_mana, Users); 50934606Sbostic mvprintw(2, 0, "Quick :%3.0f(%3.0f) Strength:%9.0f(%9.0f) Gold :%9.0f %s\n", 51034606Sbostic Player.p_speed, Player.p_quickness + Player.p_quksilver, Player.p_might, 51134606Sbostic Player.p_strength + Player.p_sword, Player.p_gold, descrstatus(&Player)); 51234606Sbostic } 51334606Sbostic /**/ 51434606Sbostic /************************************************************************ 51534606Sbostic / 51634606Sbostic / FUNCTION NAME: allstatslist() 51734606Sbostic / 51834606Sbostic / FUNCTION: show player items 51934606Sbostic / 52034606Sbostic / AUTHOR: E. A. Estes, 12/4/85 52134606Sbostic / 52234606Sbostic / ARGUMENTS: none 52334606Sbostic / 52434606Sbostic / RETURN VALUE: none 52534606Sbostic / 52634606Sbostic / MODULES CALLED: mvprintw(), descrtype() 52734606Sbostic / 52834606Sbostic / GLOBAL INPUTS: Player 52934606Sbostic / 53034606Sbostic / GLOBAL OUTPUTS: none 53134606Sbostic / 53234606Sbostic / DESCRIPTION: 53334606Sbostic / Print out some player statistics of lesser importance. 53434606Sbostic / 53534606Sbostic /************************************************************************/ 53634606Sbostic 53734606Sbostic allstatslist() 53834606Sbostic { 53934606Sbostic static char *flags[] = /* to print value of some bools */ 54034606Sbostic { 54134606Sbostic "False", 54234606Sbostic " True" 54334606Sbostic }; 54434606Sbostic 54534606Sbostic mvprintw( 8, 0, "Type: %s\n", descrtype(&Player, FALSE)); 54634606Sbostic 54734606Sbostic mvprintw(10, 0, "Experience: %9.0f", Player.p_experience); 54834606Sbostic mvprintw(11, 0, "Brains : %9.0f", Player.p_brains); 54934606Sbostic mvprintw(12, 0, "Magic Lvl : %9.0f", Player.p_magiclvl); 55034606Sbostic mvprintw(13, 0, "Sin : %9.5f", Player.p_sin); 55134606Sbostic mvprintw(14, 0, "Poison : %9.5f", Player.p_poison); 55234606Sbostic mvprintw(15, 0, "Gems : %9.0f", Player.p_gems); 55334606Sbostic mvprintw(16, 0, "Age : %9d", Player.p_age); 55434606Sbostic mvprintw(10, 40, "Holy Water: %9d", Player.p_holywater); 55534606Sbostic mvprintw(11, 40, "Amulets : %9d", Player.p_amulets); 55634606Sbostic mvprintw(12, 40, "Charms : %9d", Player.p_charms); 55734606Sbostic mvprintw(13, 40, "Crowns : %9d", Player.p_crowns); 55834606Sbostic mvprintw(14, 40, "Shield : %9.0f", Player.p_shield); 55934606Sbostic mvprintw(15, 40, "Sword : %9.0f", Player.p_sword); 56034606Sbostic mvprintw(16, 40, "Quickslver: %9.0f", Player.p_quksilver); 56134606Sbostic 56234606Sbostic mvprintw(18, 0, "Blessing: %s Ring: %s Virgin: %s Palantir: %s", 56334606Sbostic flags[Player.p_blessing], flags[Player.p_ring.ring_type != R_NONE], 56434606Sbostic flags[Player.p_virgin], flags[Player.p_palantir]); 56534606Sbostic } 56634606Sbostic /**/ 56734606Sbostic /************************************************************************ 56834606Sbostic / 56934606Sbostic / FUNCTION NAME: descrtype() 57034606Sbostic / 57134606Sbostic / FUNCTION: return a string specifying player type 57234606Sbostic / 57334606Sbostic / AUTHOR: E. A. Estes, 12/4/85 57434606Sbostic / 57534606Sbostic / ARGUMENTS: 57634606Sbostic / struct player playerp - pointer to structure for player 57734606Sbostic / bool shortflag - set if short form is desired 57834606Sbostic / 57934606Sbostic / RETURN VALUE: pointer to string describing player type 58034606Sbostic / 58134606Sbostic / MODULES CALLED: strcpy() 58234606Sbostic / 58334606Sbostic / GLOBAL INPUTS: Databuf[] 58434606Sbostic / 58534606Sbostic / GLOBAL OUTPUTS: Databuf[] 58634606Sbostic / 58734606Sbostic / DESCRIPTION: 58834606Sbostic / Return a string describing the player type. 58934606Sbostic / King, council, valar, supercedes other types. 59034606Sbostic / The first character of the string is '*' if the player 59134606Sbostic / has a crown. 59234606Sbostic / If 'shortflag' is TRUE, return a 3 character string. 59334606Sbostic / 59434606Sbostic /************************************************************************/ 59534606Sbostic 59634606Sbostic char * 59734606Sbostic descrtype(playerp, shortflag) 59834606Sbostic struct player *playerp; 59934606Sbostic bool shortflag; 60034606Sbostic { 60134606Sbostic register int type; /* for caluculating result subscript */ 60234606Sbostic static char *results[] = /* description table */ 60334606Sbostic { 60434606Sbostic " Magic User", " MU", 60534606Sbostic " Fighter", " F ", 60634606Sbostic " Elf", " E ", 60734606Sbostic " Dwarf", " D ", 60834606Sbostic " Halfling", " H ", 60934606Sbostic " Experimento", " EX", 61034606Sbostic " Super", " S ", 61134606Sbostic " King", " K ", 61234606Sbostic " Council of Wise", " CW", 61334606Sbostic " Ex-Valar", " EV", 61434606Sbostic " Valar", " V ", 61534606Sbostic " ? ", " ? " 61634606Sbostic }; 61734606Sbostic 61834606Sbostic type = playerp->p_type; 61934606Sbostic 62034606Sbostic switch (playerp->p_specialtype) 62134606Sbostic { 62234606Sbostic case SC_NONE: 62334606Sbostic type = playerp->p_type; 62434606Sbostic break; 62534606Sbostic 62634606Sbostic case SC_KING: 62734606Sbostic type = 7; 62834606Sbostic break; 62934606Sbostic 63034606Sbostic case SC_COUNCIL: 63134606Sbostic type = 8; 63234606Sbostic break; 63334606Sbostic 63434606Sbostic case SC_EXVALAR: 63534606Sbostic type = 9; 63634606Sbostic break; 63734606Sbostic 63834606Sbostic case SC_VALAR: 63934606Sbostic type = 10; 64034606Sbostic break; 64134606Sbostic } 64234606Sbostic 64334606Sbostic type *= 2; /* calculate offset */ 64434606Sbostic 64534606Sbostic if (type > 20) 64634606Sbostic /* error */ 64734606Sbostic type = 22; 64834606Sbostic 64934606Sbostic if (shortflag) 65034606Sbostic /* use short descriptions */ 65134606Sbostic ++type; 65234606Sbostic 65334606Sbostic if (playerp->p_crowns > 0) 65434606Sbostic { 65534606Sbostic strcpy(Databuf, results[type]); 65634606Sbostic Databuf[0] = '*'; 65734606Sbostic return(Databuf); 65834606Sbostic } 65934606Sbostic else 66034606Sbostic return(results[type]); 66134606Sbostic } 66234606Sbostic /**/ 66334606Sbostic /************************************************************************ 66434606Sbostic / 66534606Sbostic / FUNCTION NAME: findname() 66634606Sbostic / 66734606Sbostic / FUNCTION: find location in player file of given name 66834606Sbostic / 66934606Sbostic / AUTHOR: E. A. Estes, 12/4/85 67034606Sbostic / 67134606Sbostic / ARGUMENTS: 67234606Sbostic / char *name - name of character to look for 67334606Sbostic / struct player *playerp - pointer of structure to fill 67434606Sbostic / 67534606Sbostic / RETURN VALUE: location of player if found, -1 otherwise 67634606Sbostic / 67734606Sbostic / MODULES CALLED: fread(), fseek(), strcmp() 67834606Sbostic / 67934606Sbostic / GLOBAL INPUTS: Wizard, *Playersfp 68034606Sbostic / 68134606Sbostic / GLOBAL OUTPUTS: none 68234606Sbostic / 68334606Sbostic / DESCRIPTION: 68434606Sbostic / Search the player file for the player of the given name. 68534606Sbostic / If player is found, fill structure with player data. 68634606Sbostic / 68734606Sbostic /************************************************************************/ 68834606Sbostic 68934606Sbostic long 69034606Sbostic findname(name, playerp) 69134606Sbostic register char *name; 69234606Sbostic register struct player *playerp; 69334606Sbostic { 69434606Sbostic long loc = 0; /* location in the file */ 69534606Sbostic 69634606Sbostic fseek(Playersfp, 0L, 0); 69734606Sbostic while (fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) 69834606Sbostic { 69934606Sbostic if (strcmp(playerp->p_name, name) == 0) 70034606Sbostic { 70134606Sbostic if (playerp->p_status != S_NOTUSED || Wizard) 70234606Sbostic /* found it */ 70334606Sbostic return(loc); 70434606Sbostic } 70534606Sbostic loc += SZ_PLAYERSTRUCT; 70634606Sbostic } 70734606Sbostic 70834606Sbostic return(-1); 70934606Sbostic } 71034606Sbostic /**/ 71134606Sbostic /************************************************************************ 71234606Sbostic / 71334606Sbostic / FUNCTION NAME: allocrecord() 71434606Sbostic / 71534606Sbostic / FUNCTION: find space in the player file for a new character 71634606Sbostic / 71734606Sbostic / AUTHOR: E. A. Estes, 12/4/85 71834606Sbostic / 71934606Sbostic / ARGUMENTS: none 72034606Sbostic / 72134606Sbostic / RETURN VALUE: location of free space in file 72234606Sbostic / 72334606Sbostic / MODULES CALLED: initplayer(), writerecord(), fread(), fseek() 72434606Sbostic / 72534606Sbostic / GLOBAL INPUTS: Other, *Playersfp 72634606Sbostic / 72734606Sbostic / GLOBAL OUTPUTS: Player 72834606Sbostic / 72934606Sbostic / DESCRIPTION: 73034606Sbostic / Search the player file for an unused entry. If none are found, 73134606Sbostic / make one at the end of the file. 73234606Sbostic / 73334606Sbostic /************************************************************************/ 73434606Sbostic 73534606Sbostic long 73634606Sbostic allocrecord() 73734606Sbostic { 73834606Sbostic long loc = 0L; /* location in file */ 73934606Sbostic 74034606Sbostic fseek(Playersfp, 0L, 0); 74134606Sbostic while (fread((char *) &Other, SZ_PLAYERSTRUCT, 1, Playersfp) == 1) 74234606Sbostic { 74334606Sbostic if (Other.p_status == S_NOTUSED) 74434606Sbostic /* found an empty record */ 74534606Sbostic return(loc); 74634606Sbostic else 74734606Sbostic loc += SZ_PLAYERSTRUCT; 74834606Sbostic } 74934606Sbostic 75034606Sbostic /* make a new record */ 75134606Sbostic initplayer(&Other); 75234606Sbostic Player.p_status = S_OFF; 75334606Sbostic writerecord(&Other, loc); 75434606Sbostic 75534606Sbostic return(loc); 75634606Sbostic } 75734606Sbostic /**/ 75834606Sbostic /************************************************************************ 75934606Sbostic / 76034606Sbostic / FUNCTION NAME: freerecord() 76134606Sbostic / 76234606Sbostic / FUNCTION: free up a record on the player file 76334606Sbostic / 76434606Sbostic / AUTHOR: E. A. Estes, 2/7/86 76534606Sbostic / 76634606Sbostic / ARGUMENTS: 76734606Sbostic / struct player playerp - pointer to structure to free 76834606Sbostic / long loc - location in file to free 76934606Sbostic / 77034606Sbostic / RETURN VALUE: none 77134606Sbostic / 77234606Sbostic / MODULES CALLED: writerecord() 77334606Sbostic / 77434606Sbostic / GLOBAL INPUTS: none 77534606Sbostic / 77634606Sbostic / GLOBAL OUTPUTS: none 77734606Sbostic / 77834606Sbostic / DESCRIPTION: 77934606Sbostic / Mark structure as not used, and update player file. 78034606Sbostic / 78134606Sbostic /************************************************************************/ 78234606Sbostic 78334606Sbostic freerecord(playerp, loc) 78434606Sbostic struct player *playerp; 78534606Sbostic long loc; 78634606Sbostic { 78734606Sbostic playerp->p_name[0] = CH_MARKDELETE; 78834606Sbostic playerp->p_status = S_NOTUSED; 78934606Sbostic writerecord(playerp, loc); 79034606Sbostic } 79134606Sbostic /**/ 79234606Sbostic /************************************************************************ 79334606Sbostic / 79434606Sbostic / FUNCTION NAME: leavegame() 79534606Sbostic / 79634606Sbostic / FUNCTION: leave game 79734606Sbostic / 79834606Sbostic / AUTHOR: E. A. Estes, 12/4/85 79934606Sbostic / 80034606Sbostic / ARGUMENTS: none 80134606Sbostic / 80234606Sbostic / RETURN VALUE: none 80334606Sbostic / 80434606Sbostic / MODULES CALLED: freerecord(), writerecord(), cleanup() 80534606Sbostic / 80634606Sbostic / GLOBAL INPUTS: Player, Fileloc 80734606Sbostic / 80834606Sbostic / GLOBAL OUTPUTS: Player 80934606Sbostic / 81034606Sbostic / DESCRIPTION: 81134606Sbostic / Mark player as inactive, and cleanup. 81234606Sbostic / Do not save players below level 1. 81334606Sbostic / 81434606Sbostic /************************************************************************/ 81534606Sbostic 81634606Sbostic leavegame() 81734606Sbostic { 81834606Sbostic 81934606Sbostic if (Player.p_level < 1.0) 82034606Sbostic /* delete character */ 82134606Sbostic freerecord(&Player, Fileloc); 82234606Sbostic else 82334606Sbostic { 82434606Sbostic Player.p_status = S_OFF; 82534606Sbostic writerecord(&Player, Fileloc); 82634606Sbostic } 82734606Sbostic 82834606Sbostic cleanup(TRUE); 82934606Sbostic /*NOTREACHED*/ 83034606Sbostic } 83134606Sbostic /**/ 83234606Sbostic /************************************************************************ 83334606Sbostic / 83434606Sbostic / FUNCTION NAME: death() 83534606Sbostic / 83634606Sbostic / FUNCTION: death routine 83734606Sbostic / 83834606Sbostic / AUTHOR: E. A. Estes, 12/4/85 83934606Sbostic / 84034606Sbostic / ARGUMENTS: 84134606Sbostic / char *how - pointer to string describing cause of death 84234606Sbostic / 84334606Sbostic / RETURN VALUE: none 84434606Sbostic / 84534606Sbostic / MODULES CALLED: freerecord(), enterscore(), more(), exit(), fread(), 84634606Sbostic / fseek(), execl(), fopen(), floor(), wmove(), drandom(), wclear(), strcmp(), 84734606Sbostic / fwrite(), fflush(), printw(), strcpy(), fclose(), waddstr(), cleanup(), 84834606Sbostic / fprintf(), wrefresh(), getanswer(), descrtype() 84934606Sbostic / 850*40279Sbostic / GLOBAL INPUTS: Curmonster, Wizard, Player, *stdscr, Fileloc, *Monstfp 85134606Sbostic / 85234606Sbostic / GLOBAL OUTPUTS: Player 85334606Sbostic / 85434606Sbostic / DESCRIPTION: 85534606Sbostic / Kill off current player. 85634606Sbostic / Handle rings, and multiple lives. 85734606Sbostic / Print an appropriate message. 85834606Sbostic / Update scoreboard, lastdead, and let other players know about 85934606Sbostic / the demise of their comrade. 86034606Sbostic / 86134606Sbostic /************************************************************************/ 86234606Sbostic 86334606Sbostic death(how) 86434606Sbostic char *how; 86534606Sbostic { 86634606Sbostic FILE *fp; /* for updating various files */ 86734606Sbostic int ch; /* input */ 86834606Sbostic static char *deathmesg[] = 86934606Sbostic /* add more messages here, if desired */ 87034606Sbostic { 87134606Sbostic "You have been wounded beyond repair. ", 87234606Sbostic "You have been disemboweled. ", 87334606Sbostic "You've been mashed, mauled, and spit upon. (You're dead.)\n", 87434606Sbostic "You died! ", 87534606Sbostic "You're a complete failure -- you've died!!\n", 87634606Sbostic "You have been dealt a fatal blow! " 87734606Sbostic }; 87834606Sbostic 87934606Sbostic clear(); 88034606Sbostic 88134606Sbostic if (strcmp(how, "Stupidity") != 0) 88234606Sbostic { 88334606Sbostic if (Player.p_level > 9999.0) 88434606Sbostic /* old age */ 88534606Sbostic addstr("Characters must be retired upon reaching level 10000. Sorry."); 88634606Sbostic else if (Player.p_lives > 0) 88734606Sbostic /* extra lives */ 88834606Sbostic { 88934606Sbostic addstr("You should be more cautious. You've been killed.\n"); 89034606Sbostic printw("You only have %d more chance(s).\n", --Player.p_lives); 89134606Sbostic more(3); 89234606Sbostic Player.p_energy = Player.p_maxenergy; 89334606Sbostic return; 89434606Sbostic } 89534606Sbostic else if (Player.p_specialtype == SC_VALAR) 89634606Sbostic { 89734606Sbostic addstr("You had your chances, but Valar aren't totally\n"); 89834606Sbostic addstr("immortal. You are now left to wither and die . . .\n"); 89934606Sbostic more(3); 90034606Sbostic Player.p_brains = Player.p_level / 25.0; 90134606Sbostic Player.p_energy = Player.p_maxenergy /= 5.0; 90234606Sbostic Player.p_quksilver = Player.p_sword = 0.0; 90334606Sbostic Player.p_specialtype = SC_COUNCIL; 90434606Sbostic return; 90534606Sbostic } 90634606Sbostic else if (Player.p_ring.ring_inuse && 90734606Sbostic (Player.p_ring.ring_type == R_DLREG || Player.p_ring.ring_type == R_NAZREG)) 90834606Sbostic /* good ring in use - saved from death */ 90934606Sbostic { 91034606Sbostic mvaddstr(4, 0, "Your ring saved you from death!\n"); 91134606Sbostic refresh(); 91234606Sbostic Player.p_ring.ring_type = R_NONE; 91334606Sbostic Player.p_energy = Player.p_maxenergy / 12.0 + 1.0; 91434606Sbostic if (Player.p_crowns > 0) 91534606Sbostic --Player.p_crowns; 91634606Sbostic return; 91734606Sbostic } 91834606Sbostic else if (Player.p_ring.ring_type == R_BAD 91934606Sbostic || Player.p_ring.ring_type == R_SPOILED) 92034606Sbostic /* bad ring in possession; name idiot after player */ 92134606Sbostic { 92234606Sbostic mvaddstr(4, 0, 92334606Sbostic "Your ring has taken control of you and turned you into a monster!\n"); 92434606Sbostic fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0); 92534606Sbostic fread((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp); 92634606Sbostic strcpy(Curmonster.m_name, Player.p_name); 92734606Sbostic fseek(Monstfp, 13L * SZ_MONSTERSTRUCT, 0); 92834606Sbostic fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, Monstfp); 92934606Sbostic fflush(Monstfp); 93034606Sbostic } 93134606Sbostic } 93234606Sbostic 93334606Sbostic enterscore(); /* update score board */ 93434606Sbostic 93534606Sbostic /* put info in last dead file */ 936*40279Sbostic fp = fopen(_PATH_LASTDEAD, "w"); 93734606Sbostic fprintf(fp,"%s (%s, run by %s, level %.0f, killed by %s)", 93834606Sbostic Player.p_name, descrtype(&Player, TRUE), 93934606Sbostic Player.p_login, Player.p_level, how); 94034606Sbostic fclose(fp); 94134606Sbostic 94234606Sbostic /* let other players know */ 943*40279Sbostic fp = fopen(_PATH_MESS, "w"); 94434606Sbostic fprintf(fp, "%s was killed by %s.", Player.p_name, how); 94534606Sbostic fclose(fp); 94634606Sbostic 94734606Sbostic freerecord(&Player, Fileloc); 94834606Sbostic 94934606Sbostic clear(); 95034606Sbostic move(10, 0); 95134606Sbostic addstr(deathmesg[(int) ROLL(0.0, (double) sizeof(deathmesg) / sizeof(char *))]); 95234606Sbostic addstr("Care to give it another try ? "); 95334606Sbostic ch = getanswer("NY", FALSE); 95434606Sbostic 95534606Sbostic if (ch == 'Y') 95634606Sbostic { 95734606Sbostic cleanup(FALSE); 958*40279Sbostic execl(_PATH_GAMEPROG, "phantasia", "-s", 959*40279Sbostic (Wizard ? "-S": (char *) NULL), 0); 96034606Sbostic exit(0); 96134606Sbostic /*NOTREACHED*/ 96234606Sbostic } 96334606Sbostic 96434606Sbostic cleanup(TRUE); 96534606Sbostic /*NOTREACHED*/ 96634606Sbostic } 96734606Sbostic /**/ 96834606Sbostic /************************************************************************ 96934606Sbostic / 97034606Sbostic / FUNCTION NAME: writerecord() 97134606Sbostic / 97234606Sbostic / FUNCTION: update structure in player file 97334606Sbostic / 97434606Sbostic / AUTHOR: E. A. Estes, 12/4/85 97534606Sbostic / 97634606Sbostic / ARGUMENTS: 97734606Sbostic / struct player *playerp - pointer to structure to write out 97834606Sbostic / long place - location in file to updata 97934606Sbostic / 98034606Sbostic / RETURN VALUE: none 98134606Sbostic / 98234606Sbostic / MODULES CALLED: fseek(), fwrite(), fflush() 98334606Sbostic / 98434606Sbostic / GLOBAL INPUTS: *Playersfp 98534606Sbostic / 98634606Sbostic / GLOBAL OUTPUTS: none 98734606Sbostic / 98834606Sbostic / DESCRIPTION: 98934606Sbostic / Update location in player file with given structure. 99034606Sbostic / 99134606Sbostic /************************************************************************/ 99234606Sbostic 99334606Sbostic writerecord(playerp, place) 99434606Sbostic register struct player *playerp; 99534606Sbostic long place; 99634606Sbostic { 99734606Sbostic fseek(Playersfp, place, 0); 99834606Sbostic fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp); 99934606Sbostic fflush(Playersfp); 100034606Sbostic } 100134606Sbostic /**/ 100234606Sbostic /************************************************************************ 100334606Sbostic / 100434606Sbostic / FUNCTION NAME: explevel() 100534606Sbostic / 100634606Sbostic / FUNCTION: calculate level based upon experience 100734606Sbostic / 100834606Sbostic / AUTHOR: E. A. Estes, 12/4/85 100934606Sbostic / 101034606Sbostic / ARGUMENTS: 101134606Sbostic / double experience - experience to calculate experience level from 101234606Sbostic / 101334606Sbostic / RETURN VALUE: experience level 101434606Sbostic / 101534606Sbostic / MODULES CALLED: pow(), floor() 101634606Sbostic / 101734606Sbostic / GLOBAL INPUTS: none 101834606Sbostic / 101934606Sbostic / GLOBAL OUTPUTS: none 102034606Sbostic / 102134606Sbostic / DESCRIPTION: 102234606Sbostic / Experience level is a geometric progression. This has been finely 102334606Sbostic / tuned over the years, and probably should not be changed. 102434606Sbostic / 102534606Sbostic /************************************************************************/ 102634606Sbostic 102734606Sbostic double 102834606Sbostic explevel(experience) 102934606Sbostic double experience; 103034606Sbostic { 103134606Sbostic if (experience < 1.1e7) 103234606Sbostic return(floor(pow((experience / 1000.0), 0.4875))); 103334606Sbostic else 103434606Sbostic return(floor(pow((experience / 1250.0), 0.4865))); 103534606Sbostic } 103634606Sbostic /**/ 103734606Sbostic /************************************************************************ 103834606Sbostic / 103934606Sbostic / FUNCTION NAME: truncstring() 104034606Sbostic / 104134606Sbostic / FUNCTION: truncate trailing blanks off a string 104234606Sbostic / 104334606Sbostic / AUTHOR: E. A. Estes, 12/4/85 104434606Sbostic / 104534606Sbostic / ARGUMENTS: 104634606Sbostic / char *string - pointer to null terminated string 104734606Sbostic / 104834606Sbostic / RETURN VALUE: none 104934606Sbostic / 105034606Sbostic / MODULES CALLED: strlen() 105134606Sbostic / 105234606Sbostic / GLOBAL INPUTS: none 105334606Sbostic / 105434606Sbostic / GLOBAL OUTPUTS: none 105534606Sbostic / 105634606Sbostic / DESCRIPTION: 105734606Sbostic / Put nul characters in place of spaces at the end of the string. 105834606Sbostic / 105934606Sbostic /************************************************************************/ 106034606Sbostic 106134606Sbostic truncstring(string) 106234606Sbostic register char *string; 106334606Sbostic { 106434606Sbostic register int length; /* length of string */ 106534606Sbostic 106634606Sbostic length = strlen(string); 106734606Sbostic while (string[--length] == ' ') 106834606Sbostic string[length] = '\0'; 106934606Sbostic } 107034606Sbostic /**/ 107134606Sbostic /************************************************************************ 107234606Sbostic / 107334606Sbostic / FUNCTION NAME: altercoordinates() 107434606Sbostic / 107534606Sbostic / FUNCTION: Alter x, y coordinates and set/check location flags 107634606Sbostic / 107734606Sbostic / AUTHOR: E. A. Estes, 12/16/85 107834606Sbostic / 107934606Sbostic / ARGUMENTS: 108034606Sbostic / double xnew, ynew - new x, y coordinates 108134606Sbostic / int operation - operation to perform with coordinates 108234606Sbostic / 108334606Sbostic / RETURN VALUE: none 108434606Sbostic / 108534606Sbostic / MODULES CALLED: fabs(), floor(), drandom(), distance() 108634606Sbostic / 108734606Sbostic / GLOBAL INPUTS: Circle, Beyond, Player 108834606Sbostic / 108934606Sbostic / GLOBAL OUTPUTS: Marsh, Circle, Beyond, Throne, Player, Changed 109034606Sbostic / 109134606Sbostic / DESCRIPTION: 109234606Sbostic / This module is called whenever the player's coordinates are altered. 109334606Sbostic / If the player is beyond the point of no return, he/she is forced 109434606Sbostic / to stay there. 109534606Sbostic / 109634606Sbostic /************************************************************************/ 109734606Sbostic 109834606Sbostic altercoordinates(xnew, ynew, operation) 109934606Sbostic double xnew; 110034606Sbostic double ynew; 110134606Sbostic int operation; 110234606Sbostic { 110334606Sbostic switch (operation) 110434606Sbostic { 110534606Sbostic case A_FORCED: /* move with no checks */ 110634606Sbostic break; 110734606Sbostic 110834606Sbostic case A_NEAR: /* pick random coordinates near */ 110934606Sbostic xnew = Player.p_x + ROLL(1.0, 5.0); 111034606Sbostic ynew = Player.p_y - ROLL(1.0, 5.0); 111134606Sbostic /* fall through for check */ 111234606Sbostic 111334606Sbostic case A_SPECIFIC: /* just move player */ 111434606Sbostic if (Beyond && fabs(xnew) < D_BEYOND && fabs(ynew) < D_BEYOND) 111534606Sbostic /* 111634606Sbostic * cannot move back from point of no return 111734606Sbostic * pick the largest coordinate to remain unchanged 111834606Sbostic */ 111934606Sbostic { 112034606Sbostic if (fabs(xnew) > fabs(ynew)) 112134606Sbostic xnew = SGN(Player.p_x) * MAX(fabs(Player.p_x), D_BEYOND); 112234606Sbostic else 112334606Sbostic ynew = SGN(Player.p_y) * MAX(fabs(Player.p_y), D_BEYOND); 112434606Sbostic } 112534606Sbostic break; 112634606Sbostic 112734606Sbostic case A_FAR: /* pick random coordinates far */ 112834606Sbostic xnew = Player.p_x + SGN(Player.p_x) * ROLL(50 * Circle, 250 * Circle); 112934606Sbostic ynew = Player.p_y + SGN(Player.p_y) * ROLL(50 * Circle, 250 * Circle); 113034606Sbostic break; 113134606Sbostic } 113234606Sbostic 113334606Sbostic /* now set location flags and adjust coordinates */ 113434606Sbostic Circle = CIRCLE(Player.p_x = floor(xnew), Player.p_y = floor(ynew)); 113534606Sbostic 113634606Sbostic /* set up flags based upon location */ 113734606Sbostic Throne = Marsh = Beyond = FALSE; 113834606Sbostic 113934606Sbostic if (Player.p_x == 0.0 && Player.p_y == 0.0) 114034606Sbostic Throne = TRUE; 114134606Sbostic else if (Circle < 35 && Circle >= 20) 114234606Sbostic Marsh = TRUE; 114334606Sbostic else if (MAX(fabs(Player.p_x), fabs(Player.p_y)) >= D_BEYOND) 114434606Sbostic Beyond = TRUE; 114534606Sbostic 114634606Sbostic Changed = TRUE; 114734606Sbostic } 114834606Sbostic /**/ 114934606Sbostic /************************************************************************ 115034606Sbostic / 115134606Sbostic / FUNCTION NAME: readrecord() 115234606Sbostic / 115334606Sbostic / FUNCTION: read a player structure from file 115434606Sbostic / 115534606Sbostic / AUTHOR: E. A. Estes, 12/4/85 115634606Sbostic / 115734606Sbostic / ARGUMENTS: 115834606Sbostic / struct player *playerp - pointer to structure to fill 115934606Sbostic / int loc - location of record to read 116034606Sbostic / 116134606Sbostic / RETURN VALUE: none 116234606Sbostic / 116334606Sbostic / MODULES CALLED: fread(), fseek() 116434606Sbostic / 116534606Sbostic / GLOBAL INPUTS: *Playersfp 116634606Sbostic / 116734606Sbostic / GLOBAL OUTPUTS: none 116834606Sbostic / 116934606Sbostic / DESCRIPTION: 117034606Sbostic / Read structure information from player file. 117134606Sbostic / 117234606Sbostic /************************************************************************/ 117334606Sbostic 117434606Sbostic readrecord(playerp, loc) 117534606Sbostic register struct player *playerp; 117634606Sbostic long loc; 117734606Sbostic { 117834606Sbostic fseek(Playersfp, loc, 0); 117934606Sbostic fread((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp); 118034606Sbostic } 118134606Sbostic /**/ 118234606Sbostic /************************************************************************ 118334606Sbostic / 118434606Sbostic / FUNCTION NAME: adjuststats() 118534606Sbostic / 118634606Sbostic / FUNCTION: adjust player statistics 118734606Sbostic / 118834606Sbostic / AUTHOR: E. A. Estes, 12/4/85 118934606Sbostic / 119034606Sbostic / ARGUMENTS: none 119134606Sbostic / 119234606Sbostic / RETURN VALUE: none 119334606Sbostic / 119434606Sbostic / MODULES CALLED: death(), floor(), drandom(), explevel(), movelevel() 119534606Sbostic / 119634606Sbostic / GLOBAL INPUTS: Player, *Statptr 119734606Sbostic / 119834606Sbostic / GLOBAL OUTPUTS: Circle, Player, Timeout 119934606Sbostic / 120034606Sbostic / DESCRIPTION: 120134606Sbostic / Handle adjustment and maximums on various player characteristics. 120234606Sbostic / 120334606Sbostic /************************************************************************/ 120434606Sbostic 120534606Sbostic adjuststats() 120634606Sbostic { 120734606Sbostic double dtemp; /* for temporary calculations */ 120834606Sbostic 120934606Sbostic if (explevel(Player.p_experience) > Player.p_level) 121034606Sbostic /* move one or more levels */ 121134606Sbostic { 121234606Sbostic movelevel(); 121334606Sbostic if (Player.p_level > 5.0) 121434606Sbostic Timeout = TRUE; 121534606Sbostic } 121634606Sbostic 121734606Sbostic if (Player.p_specialtype == SC_VALAR) 121834606Sbostic /* valar */ 121934606Sbostic Circle = Player.p_level / 5.0; 122034606Sbostic 122134606Sbostic /* calculate effective quickness */ 122234606Sbostic dtemp = ((Player.p_gold + Player.p_gems / 2.0) - 1000.0) / Statptr->c_goldtote 122334606Sbostic - Player.p_level;; 122434606Sbostic dtemp = MAX(0.0, dtemp); /* gold slows player down */ 122534606Sbostic Player.p_speed = Player.p_quickness + Player.p_quksilver - dtemp; 122634606Sbostic 122734606Sbostic /* calculate effective strength */ 122834606Sbostic if (Player.p_poison > 0.0) 122934606Sbostic /* poison makes player weaker */ 123034606Sbostic { 123134606Sbostic dtemp = 1.0 - Player.p_poison * Statptr->c_weakness / 800.0; 123234606Sbostic dtemp = MAX(0.1, dtemp); 123334606Sbostic } 123434606Sbostic else 123534606Sbostic dtemp = 1.0; 123634606Sbostic Player.p_might = dtemp * Player.p_strength + Player.p_sword; 123734606Sbostic 123834606Sbostic /* insure that important things are within limits */ 123934606Sbostic Player.p_quksilver = MIN(99.0, Player.p_quksilver); 124034606Sbostic Player.p_mana = MIN(Player.p_mana, 124134606Sbostic Player.p_level * Statptr->c_maxmana + 1000.0); 124234606Sbostic Player.p_brains = MIN(Player.p_brains, 124334606Sbostic Player.p_level * Statptr->c_maxbrains + 200.0); 124434606Sbostic Player.p_charms = MIN(Player.p_charms, Player.p_level + 10.0); 124534606Sbostic 124634606Sbostic /* 124734606Sbostic * some implementations have problems with floating point compare 124834606Sbostic * we work around it with this stuff 124934606Sbostic */ 125034606Sbostic Player.p_gold = floor(Player.p_gold) + 0.1; 125134606Sbostic Player.p_gems = floor(Player.p_gems) + 0.1; 125234606Sbostic Player.p_mana = floor(Player.p_mana) + 0.1; 125334606Sbostic 125434606Sbostic if (Player.p_ring.ring_type != R_NONE) 125534606Sbostic /* do ring things */ 125634606Sbostic { 125734606Sbostic /* rest to max */ 125834606Sbostic Player.p_energy = Player.p_maxenergy + Player.p_shield; 125934606Sbostic 126034606Sbostic if (Player.p_ring.ring_duration <= 0) 126134606Sbostic /* clean up expired rings */ 126234606Sbostic switch (Player.p_ring.ring_type) 126334606Sbostic { 126434606Sbostic case R_BAD: /* ring drives player crazy */ 126534606Sbostic Player.p_ring.ring_type = R_SPOILED; 126634606Sbostic Player.p_ring.ring_duration = (short) ROLL(10.0, 25.0); 126734606Sbostic break; 126834606Sbostic 126934606Sbostic case R_NAZREG: /* ring disappears */ 127034606Sbostic Player.p_ring.ring_type = R_NONE; 127134606Sbostic break; 127234606Sbostic 127334606Sbostic case R_SPOILED: /* ring kills player */ 127434606Sbostic death("A cursed ring"); 127534606Sbostic break; 127634606Sbostic 127734606Sbostic case R_DLREG: /* this ring doesn't expire */ 127834606Sbostic Player.p_ring.ring_duration = 0; 127934606Sbostic break; 128034606Sbostic } 128134606Sbostic } 128234606Sbostic 128334606Sbostic if (Player.p_age / N_AGE > Player.p_degenerated) 128434606Sbostic /* age player slightly */ 128534606Sbostic { 128634606Sbostic ++Player.p_degenerated; 128734606Sbostic if (Player.p_quickness > 23.0) 128834606Sbostic Player.p_quickness *= 0.99; 128934606Sbostic Player.p_strength *= 0.97; 129034606Sbostic Player.p_brains *= 0.95; 129134606Sbostic Player.p_magiclvl *= 0.97; 129234606Sbostic Player.p_maxenergy *= 0.95; 129334606Sbostic Player.p_quksilver *= 0.95; 129434606Sbostic Player.p_sword *= 0.93; 129534606Sbostic Player.p_shield *= 0.93; 129634606Sbostic } 129734606Sbostic } 129834606Sbostic /**/ 129934606Sbostic /************************************************************************ 130034606Sbostic / 130134606Sbostic / FUNCTION NAME: initplayer() 130234606Sbostic / 130334606Sbostic / FUNCTION: initialize a character 130434606Sbostic / 130534606Sbostic / AUTHOR: E. A. Estes, 12/4/85 130634606Sbostic / 130734606Sbostic / ARGUMENTS: 130834606Sbostic / struct player *playerp - pointer to structure to init 130934606Sbostic / 131034606Sbostic / RETURN VALUE: none 131134606Sbostic / 131234606Sbostic / MODULES CALLED: floor(), drandom() 131334606Sbostic / 131434606Sbostic / GLOBAL INPUTS: none 131534606Sbostic / 131634606Sbostic / GLOBAL OUTPUTS: none 131734606Sbostic / 131834606Sbostic / DESCRIPTION: 131934606Sbostic / Put a bunch of default values in the given structure. 132034606Sbostic / 132134606Sbostic /************************************************************************/ 132234606Sbostic 132334606Sbostic initplayer(playerp) 132434606Sbostic register struct player *playerp; 132534606Sbostic { 132634606Sbostic playerp->p_experience = 132734606Sbostic playerp->p_level = 132834606Sbostic playerp->p_strength = 132934606Sbostic playerp->p_sword = 133034606Sbostic playerp->p_might = 133134606Sbostic playerp->p_energy = 133234606Sbostic playerp->p_maxenergy = 133334606Sbostic playerp->p_shield = 133434606Sbostic playerp->p_quickness = 133534606Sbostic playerp->p_quksilver = 133634606Sbostic playerp->p_speed = 133734606Sbostic playerp->p_magiclvl = 133834606Sbostic playerp->p_mana = 133934606Sbostic playerp->p_brains = 134034606Sbostic playerp->p_poison = 134134606Sbostic playerp->p_gems = 134234606Sbostic playerp->p_sin = 134334606Sbostic playerp->p_1scratch = 134434606Sbostic playerp->p_2scratch = 0.0; 134534606Sbostic 134634606Sbostic playerp->p_gold = ROLL(50.0, 75.0) + 0.1; /* give some gold */ 134734606Sbostic 134834606Sbostic playerp->p_x = ROLL(-125.0, 251.0); 134934606Sbostic playerp->p_y = ROLL(-125.0, 251.0); /* give random x, y */ 135034606Sbostic 135134606Sbostic /* clear ring */ 135234606Sbostic playerp->p_ring.ring_type = R_NONE; 135334606Sbostic playerp->p_ring.ring_duration = 0; 135434606Sbostic playerp->p_ring.ring_inuse = FALSE; 135534606Sbostic 135634606Sbostic playerp->p_age = 0L; 135734606Sbostic 135834606Sbostic playerp->p_degenerated = 1; /* don't degenerate initially */ 135934606Sbostic 136034606Sbostic playerp->p_type = C_FIGHTER; /* default */ 136134606Sbostic playerp->p_specialtype = SC_NONE; 136234606Sbostic playerp->p_lives = 136334606Sbostic playerp->p_crowns = 136434606Sbostic playerp->p_charms = 136534606Sbostic playerp->p_amulets = 136634606Sbostic playerp->p_holywater = 136734606Sbostic playerp->p_lastused = 0; 136834606Sbostic playerp->p_status = S_NOTUSED; 136934606Sbostic playerp->p_tampered = T_OFF; 137034606Sbostic playerp->p_istat = I_OFF; 137134606Sbostic 137234606Sbostic playerp->p_palantir = 137334606Sbostic playerp->p_blessing = 137434606Sbostic playerp->p_virgin = 137534606Sbostic playerp->p_blindness = FALSE; 137634606Sbostic 137734606Sbostic playerp->p_name[0] = 137834606Sbostic playerp->p_password[0] = 137934606Sbostic playerp->p_login[0] = '\0'; 138034606Sbostic } 138134606Sbostic /**/ 138234606Sbostic /************************************************************************ 138334606Sbostic / 138434606Sbostic / FUNCTION NAME: readmessage() 138534606Sbostic / 138634606Sbostic / FUNCTION: read message from other players 138734606Sbostic / 138834606Sbostic / AUTHOR: E. A. Estes, 12/4/85 138934606Sbostic / 139034606Sbostic / ARGUMENTS: none 139134606Sbostic / 139234606Sbostic / RETURN VALUE: none 139334606Sbostic / 139434606Sbostic / MODULES CALLED: fseek(), fgets(), wmove(), waddstr(), wclrtoeol() 139534606Sbostic / 139634606Sbostic / GLOBAL INPUTS: *stdscr, Databuf[], *Messagefp 139734606Sbostic / 139834606Sbostic / GLOBAL OUTPUTS: none 139934606Sbostic / 140034606Sbostic / DESCRIPTION: 140134606Sbostic / If there is a message from other players, print it. 140234606Sbostic / 140334606Sbostic /************************************************************************/ 140434606Sbostic 140534606Sbostic readmessage() 140634606Sbostic { 140734606Sbostic move(3, 0); 140834606Sbostic clrtoeol(); 140934606Sbostic fseek(Messagefp, 0L, 0); 141034606Sbostic if (fgets(Databuf, SZ_DATABUF, Messagefp) != NULL) 141134606Sbostic addstr(Databuf); 141234606Sbostic } 141334606Sbostic /**/ 141434606Sbostic /************************************************************************ 141534606Sbostic / 141634606Sbostic / FUNCTION NAME: error() 141734606Sbostic / 141834606Sbostic / FUNCTION: process evironment error 141934606Sbostic / 142034606Sbostic / AUTHOR: E. A. Estes, 12/4/85 142134606Sbostic / 142234606Sbostic / ARGUMENTS: 142334606Sbostic / char *whichfile - pointer to name of file which caused error 142434606Sbostic / 142534606Sbostic / RETURN VALUE: none 142634606Sbostic / 142734606Sbostic / MODULES CALLED: wclear(), cleanup() 142834606Sbostic / 142934606Sbostic / GLOBAL INPUTS: errno, *stdscr, printw(), printf(), Windows 143034606Sbostic / 143134606Sbostic / GLOBAL OUTPUTS: none 143234606Sbostic / 143334606Sbostic / DESCRIPTION: 143434606Sbostic / Print message about offending file, and exit. 143534606Sbostic / 143634606Sbostic /************************************************************************/ 143734606Sbostic 143834606Sbostic error(whichfile) 143934606Sbostic char *whichfile; 144034606Sbostic { 144134606Sbostic extern int errno; 144234606Sbostic extern printw(), printf(); 144334606Sbostic int (*funcp)(); 144434606Sbostic 144534606Sbostic if (Windows) 144634606Sbostic { 144734606Sbostic funcp = printw; 144834606Sbostic clear(); 144934606Sbostic } 145034606Sbostic else 145134606Sbostic funcp = printf; 145234606Sbostic 145334606Sbostic (*funcp)("An unrecoverable error has occurred reading %s. (errno = %d)\n", whichfile, errno); 145434606Sbostic (*funcp)("Please run 'setup' to determine the problem.\n"); 145534606Sbostic cleanup(TRUE); 145634606Sbostic /*NOTREACHED*/ 145734606Sbostic } 145834606Sbostic /**/ 145934606Sbostic /************************************************************************ 146034606Sbostic / 146134606Sbostic / FUNCTION NAME: distance() 146234606Sbostic / 146334606Sbostic / FUNCTION: calculate distance between two points 146434606Sbostic / 146534606Sbostic / AUTHOR: E. A. Estes, 12/4/85 146634606Sbostic / 146734606Sbostic / ARGUMENTS: 146834606Sbostic / double x1, y1 - x, y coordinates of first point 146934606Sbostic / double x2, y2 - x, y coordinates of second point 147034606Sbostic / 147134606Sbostic / RETURN VALUE: distance between the two points 147234606Sbostic / 147334606Sbostic / MODULES CALLED: sqrt() 147434606Sbostic / 147534606Sbostic / GLOBAL INPUTS: none 147634606Sbostic / 147734606Sbostic / GLOBAL OUTPUTS: none 147834606Sbostic / 147934606Sbostic / DESCRIPTION: 148034606Sbostic / This function is provided because someone's hypot() library function 148134606Sbostic / fails if x1 == x2 && y1 == y2. 148234606Sbostic / 148334606Sbostic /************************************************************************/ 148434606Sbostic 148534606Sbostic double 148634606Sbostic distance(x1, x2, y1, y2) 148734606Sbostic double x1, x2, y1, y2; 148834606Sbostic { 148934606Sbostic double deltax, deltay; 149034606Sbostic 149134606Sbostic deltax = x1 - x2; 149234606Sbostic deltay = y1 - y2; 149334606Sbostic return(sqrt(deltax * deltax + deltay * deltay)); 149434606Sbostic } 149534606Sbostic 149634606Sbostic /**/ 149734606Sbostic /************************************************************************ 149834606Sbostic / 149934606Sbostic / FUNCTION NAME: ill_sig() 150034606Sbostic / 150134606Sbostic / FUNCTION: exit upon trapping an illegal signal 150234606Sbostic / 150334606Sbostic / AUTHOR: E. A. Estes, 12/4/85 150434606Sbostic / 150534606Sbostic / ARGUMENTS: 150634606Sbostic / int whichsig - signal which occured to cause jump to here 150734606Sbostic / 150834606Sbostic / RETURN VALUE: none 150934606Sbostic / 151034606Sbostic / MODULES CALLED: wclear(), printw(), cleanup() 151134606Sbostic / 151234606Sbostic / GLOBAL INPUTS: *stdscr 151334606Sbostic / 151434606Sbostic / GLOBAL OUTPUTS: none 151534606Sbostic / 151634606Sbostic / DESCRIPTION: 151734606Sbostic / When an illegal signal is caught, print a message, and cleanup. 151834606Sbostic / 151934606Sbostic /************************************************************************/ 152034606Sbostic 152134606Sbostic ill_sig(whichsig) 152234606Sbostic int whichsig; 152334606Sbostic { 152434606Sbostic clear(); 152534606Sbostic if (!(whichsig == SIGINT || whichsig == SIGQUIT)) 152634606Sbostic printw("Error: caught signal # %d.\n", whichsig); 152734606Sbostic cleanup(TRUE); 152834606Sbostic /*NOTREACHED*/ 152934606Sbostic } 153034606Sbostic /**/ 153134606Sbostic /************************************************************************ 153234606Sbostic / 153334606Sbostic / FUNCTION NAME: descrstatus() 153434606Sbostic / 153534606Sbostic / FUNCTION: return a string describing the player status 153634606Sbostic / 153734606Sbostic / AUTHOR: E. A. Estes, 3/3/86 153834606Sbostic / 153934606Sbostic / ARGUMENTS: 154034606Sbostic / struct player playerp - pointer to player structure to describe 154134606Sbostic / 154234606Sbostic / RETURN VALUE: string describing player's status 154334606Sbostic / 154434606Sbostic / MODULES CALLED: none 154534606Sbostic / 154634606Sbostic / GLOBAL INPUTS: none 154734606Sbostic / 154834606Sbostic / GLOBAL OUTPUTS: none 154934606Sbostic / 155034606Sbostic / DESCRIPTION: 155134606Sbostic / Return verbal description of player status. 155234606Sbostic / If player status is S_PLAYING, check for low energy and blindness. 155334606Sbostic / 155434606Sbostic /************************************************************************/ 155534606Sbostic 155634606Sbostic char * 155734606Sbostic descrstatus(playerp) 155834606Sbostic register struct player *playerp; 155934606Sbostic { 156034606Sbostic switch (playerp->p_status) 156134606Sbostic { 156234606Sbostic case S_PLAYING: 156334606Sbostic if (playerp->p_energy < 0.2 * (playerp->p_maxenergy + playerp->p_shield)) 156434606Sbostic return("Low Energy"); 156534606Sbostic else if (playerp->p_blindness) 156634606Sbostic return("Blind"); 156734606Sbostic else 156834606Sbostic return("In game"); 156934606Sbostic 157034606Sbostic case S_CLOAKED: 157134606Sbostic return("Cloaked"); 157234606Sbostic 157334606Sbostic case S_INBATTLE: 157434606Sbostic return("In Battle"); 157534606Sbostic 157634606Sbostic case S_MONSTER: 157734606Sbostic return("Encounter"); 157834606Sbostic 157934606Sbostic case S_TRADING: 158034606Sbostic return("Trading"); 158134606Sbostic 158234606Sbostic case S_OFF: 158334606Sbostic return("Off"); 158434606Sbostic 158534606Sbostic case S_HUNGUP: 158634606Sbostic return("Hung up"); 158734606Sbostic 158834606Sbostic default: 158934606Sbostic return(""); 159034606Sbostic } 159134606Sbostic } 159234606Sbostic /**/ 159334606Sbostic /************************************************************************ 159434606Sbostic / 159534606Sbostic / FUNCTION NAME: drandom() 159634606Sbostic / 159734606Sbostic / FUNCTION: return a random floating point number from 0.0 < 1.0 159834606Sbostic / 159934606Sbostic / AUTHOR: E. A. Estes, 2/7/86 160034606Sbostic / 160134606Sbostic / ARGUMENTS: none 160234606Sbostic / 160334606Sbostic / RETURN VALUE: none 160434606Sbostic / 160534606Sbostic / MODULES CALLED: random() 160634606Sbostic / 160734606Sbostic / GLOBAL INPUTS: none 160834606Sbostic / 160934606Sbostic / GLOBAL OUTPUTS: none 161034606Sbostic / 161134606Sbostic / DESCRIPTION: 161234606Sbostic / Convert random integer from library routine into a floating 161334606Sbostic / point number, and divide by the largest possible random number. 161434606Sbostic / We mask large integers with 32767 to handle sites that return 161534606Sbostic / 31 bit random integers. 161634606Sbostic / 161734606Sbostic /************************************************************************/ 161834606Sbostic 161934606Sbostic double 162034606Sbostic drandom() 162134606Sbostic { 162234606Sbostic if (sizeof(int) != 2) 162334606Sbostic /* use only low bits */ 162434606Sbostic return((double) (random() & 0x7fff) / 32768.0); 162534606Sbostic else 162634606Sbostic return((double) random() / 32768.0); 162734606Sbostic } 162834606Sbostic /**/ 162934606Sbostic /************************************************************************ 163034606Sbostic / 163134606Sbostic / FUNCTION NAME: collecttaxes() 163234606Sbostic / 163334606Sbostic / FUNCTION: collect taxes from current player 163434606Sbostic / 163534606Sbostic / AUTHOR: E. A. Estes, 2/7/86 163634606Sbostic / 163734606Sbostic / ARGUMENTS: 163834606Sbostic / double gold - amount of gold to tax 163934606Sbostic / double gems - amount of gems to tax 164034606Sbostic / 164134606Sbostic / RETURN VALUE: none 164234606Sbostic / 164334606Sbostic / MODULES CALLED: fread(), fseek(), fopen(), floor(), fwrite(), fclose() 164434606Sbostic / 1645*40279Sbostic / GLOBAL INPUTS: Player 164634606Sbostic / 164734606Sbostic / GLOBAL OUTPUTS: Player 164834606Sbostic / 164934606Sbostic / DESCRIPTION: 165034606Sbostic / Pay taxes on gold and gems. If the player does not have enough 165134606Sbostic / gold to pay taxes on the added gems, convert some gems to gold. 165234606Sbostic / Add taxes to tax data base; add remaining gold and gems to 165334606Sbostic / player's cache. 165434606Sbostic / 165534606Sbostic /************************************************************************/ 165634606Sbostic 165734606Sbostic collecttaxes(gold, gems) 165834606Sbostic double gold; 165934606Sbostic double gems; 166034606Sbostic { 166134606Sbostic FILE *fp; /* to update Goldfile */ 166234606Sbostic double dtemp; /* for temporary calculations */ 166334606Sbostic double taxes; /* tax liability */ 166434606Sbostic 166534606Sbostic /* add to cache */ 166634606Sbostic Player.p_gold += gold; 166734606Sbostic Player.p_gems += gems; 166834606Sbostic 166934606Sbostic /* calculate tax liability */ 167034606Sbostic taxes = N_TAXAMOUNT / 100.0 * (N_GEMVALUE * gems + gold); 167134606Sbostic 167234606Sbostic if (Player.p_gold < taxes) 167334606Sbostic /* not enough gold to pay taxes, must convert some gems to gold */ 167434606Sbostic { 167534606Sbostic dtemp = floor(taxes / N_GEMVALUE + 1.0); /* number of gems to convert */ 167634606Sbostic 167734606Sbostic if (Player.p_gems >= dtemp) 167834606Sbostic /* player has enough to convert */ 167934606Sbostic { 168034606Sbostic Player.p_gems -= dtemp; 168134606Sbostic Player.p_gold += dtemp * N_GEMVALUE; 168234606Sbostic } 168334606Sbostic else 168434606Sbostic /* take everything; this should never happen */ 168534606Sbostic { 168634606Sbostic Player.p_gold += Player.p_gems * N_GEMVALUE; 168734606Sbostic Player.p_gems = 0.0; 168834606Sbostic taxes = Player.p_gold; 168934606Sbostic } 169034606Sbostic } 169134606Sbostic 169234606Sbostic Player.p_gold -= taxes; 169334606Sbostic 1694*40279Sbostic if ((fp = fopen(_PATH_GOLD, "r+")) != NULL) 169534606Sbostic /* update taxes */ 169634606Sbostic { 169734606Sbostic dtemp = 0.0; 169834606Sbostic fread((char *) &dtemp, sizeof(double), 1, fp); 169934606Sbostic dtemp += floor(taxes); 170034606Sbostic fseek(fp, 0L, 0); 170134606Sbostic fwrite((char *) &dtemp, sizeof(double), 1, fp); 170234606Sbostic fclose(fp); 170334606Sbostic } 170434606Sbostic } 1705