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