From decwrl!wyse!mips!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!uunet!zephyr.ens.tek.com!tekred!saab!billr Sat May 19 10:38:40 PDT 1990 Article 878 of comp.sources.games: Path: decwrl!wyse!mips!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!uunet!zephyr.ens.tek.com!tekred!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v09i059: umoria3 - single player dungeon simulation (ver. 5.2), Part05/31 Message-ID: <5590@tekred.CNA.TEK.COM> Date: 16 May 90 19:11:51 GMT Sender: news@tekred.CNA.TEK.COM Lines: 2515 Approved: billr@saab.CNA.TEK.COM Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson) Posting-number: Volume 9, Issue 59 Archive-name: umoria3/Part05 Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'misc2.c' <<'END_OF_FILE' X/* misc2.c: misc code for maintaining the dungeon, printing player info X X Copyright (c) 1989 James E. Wilson, Robert A. Koeneke X X This software may be copied and distributed for educational, research, and X not for profit purposes provided that this copyright and statement are X included in all such copies. */ X X#include "config.h" X X/* include before constant.h because param.h defines NULL incorrectly */ X#ifndef USG X#include X#include X#endif X X#include "constant.h" X#include "types.h" X#include "externs.h" X X#include X X#ifdef USG X#ifndef ATARIST_MWC X#include X#else Xchar *index(); X#endif X#else X#include X#endif X X#if defined(LINT_ARGS) Xstatic void prt_lnum(char *, int32, int, int); Xstatic void prt_num(char *, int, int, int); Xstatic void prt_long(int32, int, int); Xstatic void prt_int(int, int, int); Xstatic void gain_level(void); X#endif X Xstatic char *stat_names[] = { "STR : ", "INT : ", "WIS : ", X "DEX : ", "CON : ", "CHR : " }; X#define BLANK_LENGTH 24 Xstatic char blank_string[] = " "; X Xchar *malloc(); X X/* Places a particular trap at location y, x -RAK- */ Xvoid place_trap(y, x, subval) Xint y, x, subval; X{ X register int cur_pos; X X cur_pos = popt(); X cave[y][x].tptr = cur_pos; X invcopy(&t_list[cur_pos], OBJ_TRAP_LIST + subval); X} X X X/* Places rubble at location y, x -RAK- */ Xvoid place_rubble(y, x) Xint y, x; X{ X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave[y][x]; X cave_ptr->tptr = cur_pos; X cave_ptr->fval = BLOCKED_FLOOR; X invcopy(&t_list[cur_pos], OBJ_RUBBLE); X} X X X/* Places a treasure (Gold or Gems) at given row, column -RAK- */ Xvoid place_gold(y, x) Xint y, x; X{ X register int i, cur_pos; X register inven_type *t_ptr; X X cur_pos = popt(); X i = ((randint(dun_level+2)+2) / 2) - 1; X if (randint(OBJ_GREAT) == 1) X i += randint(dun_level+1); X if (i >= MAX_GOLD) X i = MAX_GOLD - 1; X cave[y][x].tptr = cur_pos; X invcopy(&t_list[cur_pos], OBJ_GOLD_LIST+i); X t_ptr = &t_list[cur_pos]; X t_ptr->cost += (8L * (long)randint((int)t_ptr->cost)) + randint(8); X if (cave[y][x].cptr == 1) X msg_print ("You feel something roll beneath your feet."); X} X X X/* Returns the array number of a random object -RAK- */ Xint get_obj_num(level) Xint level; X{ X register int i, j; X X if (level == 0) X i = randint(t_level[0]) - 1; X else X { X if (level >= MAX_OBJ_LEVEL) X level = MAX_OBJ_LEVEL; X else if (randint(OBJ_GREAT) == 1) X { X level = level * MAX_OBJ_LEVEL / randint (MAX_OBJ_LEVEL) + 1; X if (level > MAX_OBJ_LEVEL) X level = MAX_OBJ_LEVEL; X } X X /* This code has been added to make it slightly more likely to get the X higher level objects. Originally a uniform distribution over all X objects less than or equal to the dungeon level. This distribution X makes a level n objects occur approx 2/n% of the time on level n, X and 1/2n are 0th level. */ X X if (randint(2) == 1) X i = randint(t_level[level]) - 1; X else /* Choose three objects, pick the highest level. */ X { X i = randint(t_level[level]) - 1; X j = randint(t_level[level]) - 1; X if (i < j) X i = j; X j = randint(t_level[level]) - 1; X if (i < j) X i = j; X j = object_list[sorted_objects[i]].level; X if (j == 0) X i = randint(t_level[0]) - 1; X else X i = randint(t_level[j]-t_level[j-1]) - 1 + t_level[j-1]; X } X } X return(i); X} X X X/* Places an object at given row, column co-ordinate -RAK- */ Xvoid place_object(y, x) Xint y, x; X{ X register int cur_pos, tmp; X X cur_pos = popt(); X cave[y][x].tptr = cur_pos; X /* split this line up to avoid a reported compiler bug */ X tmp = get_obj_num(dun_level); X invcopy(&t_list[cur_pos], sorted_objects[tmp]); X magic_treasure(cur_pos, dun_level); X if (cave[y][x].cptr == 1) X msg_print ("You feel something roll beneath your feet."); /* -CJS- */ X} X X X/* Allocates an object for tunnels and rooms -RAK- */ Xvoid alloc_object(alloc_set, typ, num) Xint (*alloc_set)(); Xint typ, num; X{ X register int i, j, k; X X for (k = 0; k < num; k++) X { X do X { X i = randint(cur_height) - 1; X j = randint(cur_width) - 1; X } X /* don't put an object beneath the player, this could cause problems X if player is standing under rubble, or on a trap */ X while ((!(*alloc_set)(cave[i][j].fval)) || X (cave[i][j].tptr != 0) || (i == char_row && j == char_col)); X if (typ < 4) { /* typ == 2 not used, used to be visible traps */ X if (typ == 1) place_trap(i, j, randint(MAX_TRAP)-1); /* typ == 1 */ X else place_rubble(i, j); /* typ == 3 */ X } else { X if (typ == 4) place_gold(i, j); /* typ == 4 */ X else place_object(i, j); /* typ == 5 */ X } X } X} X X X/* Creates objects nearby the coordinates given -RAK- */ Xvoid random_object(y, x, num) Xint y, x, num; X{ X register int i, j, k; X register cave_type *cave_ptr; X X do X { X i = 0; X do X { X j = y - 3 + randint(5); X k = x - 4 + randint(7); X cave_ptr = &cave[j][k]; X if ((cave_ptr->fval <= MAX_CAVE_FLOOR) && (cave_ptr->tptr == 0)) X { X if (randint(100) < 75) X place_object(j, k); X else X place_gold(j, k); X i = 9; X } X i++; X } X while(i <= 10); X num--; X } X while (num != 0); X} X X X/* Converts stat num into string -RAK- */ Xvoid cnv_stat(stat, out_val) Xint8u stat; Xchar *out_val; X{ X register int part1, part2; X X if (stat > 18) X { X part1 = 18; X part2 = stat - 18; X if (part2 == 100) X (void) strcpy(out_val, "18/100"); X else X (void) sprintf(out_val, " %2d/%02d", part1, part2); X } X else X (void) sprintf(out_val, "%6d", stat); X} X X X/* Print character stat in given row, column -RAK- */ Xvoid prt_stat(stat) Xint stat; X{ X stat_type out_val1; X X cnv_stat(py.stats.use_stat[stat], out_val1); X put_buffer(stat_names[stat], 6+stat, STAT_COLUMN); X put_buffer (out_val1, 6+stat, STAT_COLUMN+6); X} X X X/* Print character info in given row, column -RAK- */ X/* the longest title is 13 characters, so only pad to 13 */ Xvoid prt_field(info, row, column) Xchar *info; Xint row, column; X{ X put_buffer (&blank_string[BLANK_LENGTH-13], row, column); X put_buffer (info, row, column); X} X X/* Print long number with header at given row, column */ Xstatic void prt_lnum(header, num, row, column) Xchar *header; Xint32 num; Xint row, column; X{ X vtype out_val; X X (void) sprintf(out_val, "%s: %6ld", header, num); X put_buffer(out_val, row, column); X} X X/* Print number with header at given row, column -RAK- */ Xstatic void prt_num(header, num, row, column) Xchar *header; Xint num, row, column; X{ X vtype out_val; X X (void) sprintf(out_val, "%s: %6d", header, num); X put_buffer(out_val, row, column); X} X X/* Print long number at given row, column */ Xstatic void prt_long(num, row, column) Xint32 num; Xint row, column; X{ X vtype out_val; X X (void) sprintf(out_val, "%6ld", num); X put_buffer(out_val, row, column); X} X X/* Print number at given row, column -RAK- */ Xstatic void prt_int(num, row, column) Xint num, row, column; X{ X vtype out_val; X X (void) sprintf(out_val, "%6d", num); X put_buffer(out_val, row, column); X} X X X/* Adjustment for wisdom/intelligence -JWT- */ Xint stat_adj(stat) Xint stat; X{ X register int value; X X value = py.stats.use_stat[stat]; X if (value > 117) X return(7); X else if (value > 107) X return(6); X else if (value > 87) X return(5); X else if (value > 67) X return(4); X else if (value > 17) X return(3); X else if (value > 14) X return(2); X else if (value > 7) X return(1); X else X return(0); X} X X X/* Adjustment for charisma -RAK- */ X/* Percent decrease or increase in price of goods */ Xint chr_adj() X{ X register int charisma; X X charisma = py.stats.use_stat[A_CHR]; X if (charisma > 117) X return(90); X else if (charisma > 107) X return(92); X else if (charisma > 87) X return(94); X else if (charisma > 67) X return(96); X else if (charisma > 18) X return(98); X else X switch(charisma) X { X case 18: return(100); X case 17: return(101); X case 16: return(102); X case 15: return(103); X case 14: return(104); X case 13: return(106); X case 12: return(108); X case 11: return(110); X case 10: return(112); X case 9: return(114); X case 8: return(116); X case 7: return(118); X case 6: return(120); X case 5: return(122); X case 4: return(125); X case 3: return(130); X default: return(100); X } X} X X X/* Returns a character's adjustment to hit points -JWT- */ Xint con_adj() X{ X register int con; X X con = py.stats.use_stat[A_CON]; X if (con < 7) X return(con - 7); X else if (con < 17) X return(0); X else if (con == 17) X return(1); X else if (con < 94) X return(2); X else if (con < 117) X return(3); X else X return(4); X} X X Xchar *title_string() X{ X register char *p; X X if (py.misc.lev < 1) X p = "Babe in arms"; X else if (py.misc.lev <= MAX_PLAYER_LEVEL) X p = player_title[py.misc.pclass][py.misc.lev-1]; X else if (py.misc.male) X p = "**KING**"; X else X p = "**QUEEN**"; X return p; X} X X X/* Prints title of character -RAK- */ Xvoid prt_title() X{ X prt_field(title_string(), 4, STAT_COLUMN); X} X X X/* Prints level -RAK- */ Xvoid prt_level() X{ X prt_int((int)py.misc.lev, 13, STAT_COLUMN+6); X} X X X/* Prints players current mana points. -RAK- */ Xvoid prt_cmana() X{ X prt_int(py.misc.cmana, 15, STAT_COLUMN+6); X} X X X/* Prints Max hit points -RAK- */ Xvoid prt_mhp() X{ X prt_int(py.misc.mhp, 16, STAT_COLUMN+6); X} X X X/* Prints players current hit points -RAK- */ Xvoid prt_chp() X{ X prt_int(py.misc.chp, 17, STAT_COLUMN+6); X} X X X/* prints current AC -RAK- */ Xvoid prt_pac() X{ X prt_int(py.misc.dis_ac, 19, STAT_COLUMN+6); X} X X X/* Prints current gold -RAK- */ Xvoid prt_gold() X{ X prt_long(py.misc.au, 20, STAT_COLUMN+6); X} X X X/* Prints depth in stat area -RAK- */ Xvoid prt_depth() X{ X vtype depths; X register int depth; X X depth = dun_level*50; X if (depth == 0) X (void) strcpy(depths, "Town level"); X else X (void) sprintf(depths, "%d feet", depth); X prt(depths, 23, 65); X} X X X/* Prints status of hunger -RAK- */ Xvoid prt_hunger() X{ X if (PY_WEAK & py.flags.status) X put_buffer("Weak ", 23, 0); X else if (PY_HUNGRY & py.flags.status) X put_buffer("Hungry", 23, 0); X else X put_buffer(&blank_string[BLANK_LENGTH-6], 23, 0); X} X X X/* Prints Blind status -RAK- */ Xvoid prt_blind() X{ X if (PY_BLIND & py.flags.status) X put_buffer("Blind", 23, 7); X else X put_buffer(&blank_string[BLANK_LENGTH-5], 23, 7); X} X X X/* Prints Confusion status -RAK- */ Xvoid prt_confused() X{ X if (PY_CONFUSED & py.flags.status) X put_buffer("Confused", 23, 13); X else X put_buffer(&blank_string[BLANK_LENGTH-8], 23, 13); X} X X X/* Prints Fear status -RAK- */ Xvoid prt_afraid() X{ X if (PY_FEAR & py.flags.status) X put_buffer("Afraid", 23, 22); X else X put_buffer(&blank_string[BLANK_LENGTH-6], 23, 22); X} X X X/* Prints Poisoned status -RAK- */ Xvoid prt_poisoned() X{ X if (PY_POISONED & py.flags.status) X put_buffer("Poisoned", 23, 29); X else X put_buffer(&blank_string[BLANK_LENGTH-8], 23, 29); X} X X X/* Prints Searching, Resting, Paralysis, or 'count' status -RAK- */ Xvoid prt_state() X{ X char tmp[16]; X X py.flags.status &= ~PY_REPEAT; X if (py.flags.paralysis > 1) X put_buffer ("Paralysed", 23, 38); X else if (PY_REST & py.flags.status) X { X (void) sprintf (tmp, "Rest %-5d", py.flags.rest); X put_buffer (tmp, 23, 38); X } X else if (command_count > 0) X { X (void) sprintf (tmp, "Repeat %-3d", command_count); X py.flags.status |= PY_REPEAT; X put_buffer (tmp, 23, 38); X if (PY_SEARCH & py.flags.status) X put_buffer ("Search", 23, 38); X } X else if (PY_SEARCH & py.flags.status) X put_buffer("Searching", 23, 38); X else /* "repeat 999" is 10 characters */ X put_buffer(&blank_string[BLANK_LENGTH-10], 23, 38); X} X X X/* Prints the speed of a character. -CJS- */ Xvoid prt_speed () X{ X register int i; X X i = py.flags.speed; X if (PY_SEARCH & py.flags.status) /* Search mode. */ X i--; X if (i > 1) X put_buffer ("Very Slow", 23, 49); X else if (i == 1) X put_buffer ("Slow ", 23, 49); X else if (i == 0) X put_buffer (&blank_string[BLANK_LENGTH-9], 23, 49); X else if (i == -1) X put_buffer ("Fast ", 23, 49); X else X put_buffer ("Very Fast", 23, 49); X} X X Xvoid prt_study() X{ X py.flags.status &= ~PY_STUDY; X if (py.flags.new_spells == 0) X put_buffer (&blank_string[BLANK_LENGTH-5], 23, 59); X else X put_buffer ("Study", 23, 59); X} X X X/* Prints winner status on display -RAK- */ Xvoid prt_winner() X{ X if (noscore & 0x2) X { X if (wizard) X put_buffer("Is wizard ", 22, 0); X else X put_buffer("Was wizard ", 22, 0); X } X else if (noscore & 0x1) X put_buffer("Resurrected", 22, 0); X else if (total_winner) X put_buffer("*Winner* ", 22, 0); X} X X Xint8u modify_stat (stat, amount) Xint stat; Xint16 amount; X{ X register int loop, i; X register int8u tmp_stat; X X tmp_stat = py.stats.cur_stat[stat]; X loop = (amount < 0 ? -amount : amount); X for (i = 0; i < loop; i++) X { X if (amount > 0) X { X if (tmp_stat < 18) X tmp_stat++; X else if (tmp_stat < 108) X tmp_stat += 10; X else X tmp_stat = 118; X } X else X { X if (tmp_stat > 27) X tmp_stat -= 10; X else if (tmp_stat > 18) X tmp_stat = 18; X else if (tmp_stat > 3) X tmp_stat--; X } X } X return tmp_stat; X} X X X/* Set the value of the stat which is actually used. -CJS- */ Xvoid set_use_stat(stat) Xint stat; X{ X py.stats.use_stat[stat] = modify_stat (stat, py.stats.mod_stat[stat]); X X if (stat == A_STR) X { X py.flags.status |= PY_STR_WGT; X calc_bonuses(); X } X else if (stat == A_DEX) X calc_bonuses(); X else if (stat == A_INT && class[py.misc.pclass].spell == MAGE) X { X calc_spells(A_INT); X calc_mana(A_INT); X } X else if (stat == A_WIS && class[py.misc.pclass].spell == PRIEST) X { X calc_spells(A_WIS); X calc_mana(A_WIS); X } X else if (stat == A_CON) X calc_hitpoints(); X} X X X/* Increases a stat by one randomized level -RAK- */ Xint inc_stat(stat) Xregister int stat; X{ X register int tmp_stat, gain; X X tmp_stat = py.stats.cur_stat[stat]; X if (tmp_stat < 118) X { X if (tmp_stat < 18) X tmp_stat++; X else if (tmp_stat < 116) X { X /* stat increases by 1/6 to 1/3 of difference from max */ X gain = ((118 - tmp_stat)/3 + 1) >> 1; X tmp_stat += randint(gain) + gain; X } X else X tmp_stat++; X X py.stats.cur_stat[stat] = tmp_stat; X if (tmp_stat > py.stats.max_stat[stat]) X py.stats.max_stat[stat] = tmp_stat; X set_use_stat (stat); X prt_stat (stat); X return TRUE; X } X else X return FALSE; X} X X X/* Decreases a stat by one randomized level -RAK- */ Xint dec_stat(stat) Xregister int stat; X{ X register int tmp_stat, loss; X X tmp_stat = py.stats.cur_stat[stat]; X if (tmp_stat > 3) X { X if (tmp_stat < 19) X tmp_stat--; X else if (tmp_stat < 117) X { X loss = (((118 - tmp_stat) >> 1) + 1) >> 1; X tmp_stat += -randint(loss) - loss; X if (tmp_stat < 18) X tmp_stat = 18; X } X else X tmp_stat--; X X py.stats.cur_stat[stat] = tmp_stat; X set_use_stat (stat); X prt_stat (stat); X return TRUE; X } X else X return FALSE; X} X X X/* Restore a stat. Return TRUE only if this actually makes a difference. */ Xint res_stat (stat) Xint stat; X{ X register int i; X X i = py.stats.max_stat[stat] - py.stats.cur_stat[stat]; X if (i) X { X py.stats.cur_stat[stat] += i; X set_use_stat (stat); X prt_stat (stat); X return TRUE; X } X return FALSE; X} X X/* Boost a stat artificially (by wearing something). If the display argument X is TRUE, then increase is shown on the screen. */ Xvoid bst_stat (stat, amount) Xint stat, amount; X{ X py.stats.mod_stat[stat] += amount; X X set_use_stat (stat); X /* can not call prt_stat() here, may be in store, may be in inven_command */ X py.flags.status |= (PY_STR << stat); X} X X X/* Returns a character's adjustment to hit. -JWT- */ Xint tohit_adj() X{ X register int total, stat; X X stat = py.stats.use_stat[A_DEX]; X if (stat < 4) total = -3; X else if (stat < 6) total = -2; X else if (stat < 8) total = -1; X else if (stat < 16) total = 0; X else if (stat < 17) total = 1; X else if (stat < 18) total = 2; X else if (stat < 69) total = 3; X else if (stat < 118) total = 4; X else total = 5; X stat = py.stats.use_stat[A_STR]; X if (stat < 4) total -= 3; X else if (stat < 5) total -= 2; X else if (stat < 7) total -= 1; X else if (stat < 18) total -= 0; X else if (stat < 94) total += 1; X else if (stat < 109) total += 2; X else if (stat < 117) total += 3; X else total += 4; X return(total); X} X X X/* Returns a character's adjustment to armor class -JWT- */ Xint toac_adj() X{ X register int stat; X X stat = py.stats.use_stat[A_DEX]; X if (stat < 4) return(-4); X else if (stat == 4) return(-3); X else if (stat == 5) return(-2); X else if (stat == 6) return(-1); X else if (stat < 15) return( 0); X else if (stat < 18) return( 1); X else if (stat < 59) return( 2); X else if (stat < 94) return( 3); X else if (stat < 117) return( 4); X else return( 5); X} X X X/* Returns a character's adjustment to disarm -RAK- */ Xint todis_adj() X{ X register int stat; X X stat = py.stats.use_stat[A_DEX]; X if (stat < 3) return(-8); X else if (stat == 4) return(-6); X else if (stat == 5) return(-4); X else if (stat == 6) return(-2); X else if (stat == 7) return(-1); X else if (stat < 13) return( 0); X else if (stat < 16) return( 1); X else if (stat < 18) return( 2); X else if (stat < 59) return( 4); X else if (stat < 94) return( 5); X else if (stat < 117) return( 6); X else return( 8); X} X X X/* Returns a character's adjustment to damage -JWT- */ Xint todam_adj() X{ X register int stat; X X stat = py.stats.use_stat[A_STR]; X if (stat < 4) return(-2); X else if (stat < 5) return(-1); X else if (stat < 16) return( 0); X else if (stat < 17) return( 1); X else if (stat < 18) return( 2); X else if (stat < 94) return( 3); X else if (stat < 109) return( 4); X else if (stat < 117) return( 5); X else return( 6); X} X X X/* Prints character-screen info -RAK- */ Xvoid prt_stat_block() X{ X register int32u status; X register struct misc *m_ptr; X register int i; X X m_ptr = &py.misc; X prt_field(race[py.misc.prace].trace, 2, STAT_COLUMN); X prt_field(class[py.misc.pclass].title, 3, STAT_COLUMN); X prt_field(title_string(), 4, STAT_COLUMN); X for (i = 0; i < 6; i++) X prt_stat (i); X prt_num ("LEV ", (int)m_ptr->lev, 13, STAT_COLUMN); X prt_lnum("EXP ", m_ptr->exp, 14, STAT_COLUMN); X prt_num ("MANA", m_ptr->cmana, 15, STAT_COLUMN); X prt_num ("MHP ", m_ptr->mhp, 16, STAT_COLUMN); X prt_num ("CHP ", m_ptr->chp, 17, STAT_COLUMN); X prt_num ("AC ", m_ptr->dis_ac, 19, STAT_COLUMN); X prt_lnum("GOLD", m_ptr->au, 20, STAT_COLUMN); X prt_winner(); X status = py.flags.status; X if ((PY_HUNGRY|PY_WEAK) & status) X prt_hunger(); X if (PY_BLIND & status) X prt_blind(); X if (PY_CONFUSED & status) X prt_confused(); X if (PY_FEAR & status) X prt_afraid(); X if (PY_POISONED & status) X prt_poisoned(); X if ((PY_SEARCH|PY_REST) & status) X prt_state (); X /* if speed non zero, print it, modify speed if Searching */ X if (py.flags.speed - ((PY_SEARCH & status) >> 8) != 0) X prt_speed (); X} X X X/* Draws entire screen -RAK- */ Xvoid draw_cave() X{ X clear_screen (); X prt_stat_block(); X prt_map(); X prt_depth(); X} X X X/* Prints the following information on the screen. -JWT- */ Xvoid put_character() X{ X register struct misc *m_ptr; X X m_ptr = &py.misc; X clear_screen (); X put_buffer ("Name :", 2, 1); X put_buffer ("Race :", 3, 1); X put_buffer ("Sex :", 4, 1); X put_buffer ("Class :", 5, 1); X if (character_generated) X { X put_buffer (m_ptr->name, 2, 15); X put_buffer (race[m_ptr->prace].trace, 3, 15); X put_buffer ((m_ptr->male ? "Male" : "Female"), 4, 15); X put_buffer (class[m_ptr->pclass].title, 5, 15); X } X} X X X/* Prints the following information on the screen. -JWT- */ Xvoid put_stats() X{ X register struct misc *m_ptr; X register int i; X vtype buf; X X m_ptr = &py.misc; X for (i = 0; i < 6; i++) X { X cnv_stat (py.stats.use_stat[i], buf); X put_buffer (stat_names[i], 2+i, 61); X put_buffer (buf, 2+i, 66); X if (py.stats.max_stat[i] > py.stats.cur_stat[i]) X { X cnv_stat (py.stats.max_stat[i], buf); X put_buffer (buf, 2+i, 73); X } X } X prt_num("+ To Hit ", m_ptr->dis_th, 9, 1); X prt_num("+ To Damage ", m_ptr->dis_td, 10, 1); X prt_num("+ To AC ", m_ptr->dis_tac, 11, 1); X prt_num(" Total AC ", m_ptr->dis_ac, 12, 1); X} X X X/* Returns a rating of x depending on y -JWT- */ Xchar *likert(x, y) Xint x, y; X{ X switch((x/y)) X { X case -3: case -2: case -1: return("Very Bad"); X case 0: case 1: return("Bad"); X case 2: return("Poor"); X case 3: case 4: return("Fair"); X case 5: return("Good"); X case 6: return("Very Good"); X case 7: case 8: return("Excellent"); X default: return("Superb"); X } X} X X X/* Prints age, height, weight, and SC -JWT- */ Xvoid put_misc1() X{ X register struct misc *m_ptr; X X m_ptr = &py.misc; X prt_num("Age ", (int)m_ptr->age, 2, 38); X prt_num("Height ", (int)m_ptr->ht, 3, 38); X prt_num("Weight ", (int)m_ptr->wt, 4, 38); X prt_num("Social Class ", (int)m_ptr->sc, 5, 38); X} X X X/* Prints the following information on the screen. -JWT- */ Xvoid put_misc2() X{ X register struct misc *m_ptr; X X m_ptr = &py.misc; X prt_num("Level ", (int)m_ptr->lev, 9, 29); X prt_lnum("Experience ", m_ptr->exp, 10, 29); X prt_lnum("Max Exp ", m_ptr->max_exp, 11, 29); X prt_lnum("Exp to Adv.", (int32)(player_exp[m_ptr->lev-1] * X m_ptr->expfact/100), 12, 29); X prt_lnum("Gold ", m_ptr->au, 13, 29); X prt_num("Max Hit Points ", m_ptr->mhp, 9, 52); X prt_num("Cur Hit Points ", m_ptr->chp, 10, 52); X prt_num("Max Mana ", m_ptr->mana, 11, 52); X prt_num("Cur Mana ", m_ptr->cmana, 12, 52); X} X X X/* Prints ratings on certain abilities -RAK- */ Xvoid put_misc3() X{ X int xbth, xbthb, xfos, xsrh, xstl, xdis, xsave, xdev; X vtype xinfra; X register struct misc *p_ptr; X X clear_from(13); X p_ptr = &py.misc; X xbth = p_ptr->bth + p_ptr->ptohit*BTH_PLUS_ADJ X + (class_level_adj[p_ptr->pclass][CLA_BTH] * p_ptr->lev); X xbthb = p_ptr->bthb + p_ptr->ptohit*BTH_PLUS_ADJ X + (class_level_adj[p_ptr->pclass][CLA_BTHB] * p_ptr->lev); X /* this results in a range from 0 to 29 */ X xfos = 40 - p_ptr->fos; X if (xfos < 0) xfos = 0; X xsrh = p_ptr->srh; X /* this results in a range from 0 to 9 */ X xstl = p_ptr->stl + 1; X xdis = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT) X + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3); X xsave = p_ptr->save + stat_adj(A_WIS) X + (class_level_adj[p_ptr->pclass][CLA_SAVE] * p_ptr->lev / 3); X xdev = p_ptr->save + stat_adj(A_INT) X + (class_level_adj[p_ptr->pclass][CLA_DEVICE] * p_ptr->lev / 3); X X (void) sprintf(xinfra, "%d feet", py.flags.see_infra*10); X X put_buffer ("(Miscellaneous Abilities)", 15, 25); X put_buffer ("Fighting :", 16, 1); X put_buffer (likert (xbth, 12), 16, 15); X put_buffer ("Bows/Throw :", 17, 1); X put_buffer (likert (xbthb, 12), 17, 15); X put_buffer ("Saving Throw:", 18, 1); X put_buffer (likert (xsave, 6), 18, 15); X X put_buffer ("Stealth :", 16, 28); X put_buffer (likert (xstl, 1), 16, 42); X put_buffer ("Disarming :", 17, 28); X put_buffer (likert (xdis, 8), 17, 42); X put_buffer ("Magic Device:", 18, 28); X put_buffer (likert (xdev, 6), 18, 42); X X put_buffer ("Perception :", 16, 55); X put_buffer (likert (xfos, 3), 16, 69); X put_buffer ("Searching :", 17, 55); X put_buffer (likert (xsrh, 6), 17, 69); X put_buffer ("Infra-Vision:", 18, 55); X put_buffer (xinfra, 18, 69); X} X X X/* Used to display the character on the screen. -RAK- */ Xvoid display_char() X{ X put_character(); X put_misc1(); X put_stats(); X put_misc2(); X put_misc3(); X} X X X/* Gets a name for the character -JWT- */ Xvoid get_name() X{ X prt("Enter your player's name [press when finished]", 21, 2); X put_buffer (&blank_string[BLANK_LENGTH-23], 2, 15); X#ifdef MAC X /* Force player to give a name, would be nice to get name from chooser X (STR -16096), but that name might be too long */ X while (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0); X#else X if (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0) X { X user_name (py.misc.name); X put_buffer (py.misc.name, 2, 15); X } X#endif X clear_from (20); X#ifdef MAC X /* Use the new name to set save file default name. */ X initsavedefaults(); X#endif X} X X X/* Changes the name of the character -JWT- */ Xvoid change_name() X{ X register char c; X register int flag; X#ifndef MAC X vtype temp; X#endif X X flag = FALSE; X display_char(); X do X { X prt( "ile character description. hange character name.", 21, 2); X c = inkey(); X switch(c) X { X case 'c': X get_name(); X flag = TRUE; X break; X case 'f': X#ifdef MAC X /* On mac, file_character() gets filename with std file dialog. */ X if (file_character ()) X flag = TRUE; X#else X prt ("File name:", 0, 0); X if (get_string (temp, 0, 10, 60) && temp[0]) X if (file_character (temp)) X flag = TRUE; X#endif X break; X case ESCAPE: case ' ': X case '\n': case '\r': X flag = TRUE; X break; X default: X bell (); X break; X } X } X while (!flag); X} X X X/* Destroy an item in the inventory -RAK- */ Xvoid inven_destroy(item_val) Xint item_val; X{ X register int j; X register inven_type *i_ptr; X X i_ptr = &inventory[item_val]; X if ((i_ptr->number > 1) && (i_ptr->subval <= ITEM_SINGLE_STACK_MAX)) X { X i_ptr->number--; X inven_weight -= i_ptr->weight; X } X else X { X inven_weight -= i_ptr->weight*i_ptr->number; X for (j = item_val; j < inven_ctr-1; j++) X inventory[j] = inventory[j+1]; X invcopy(&inventory[inven_ctr-1], OBJ_NOTHING); X inven_ctr--; X } X py.flags.status |= PY_STR_WGT; X} X X X/* Copies the object in the second argument over the first argument. X However, the second always gets a number of one except for ammo etc. */ Xvoid take_one_item (s_ptr, i_ptr) Xregister inven_type *s_ptr, *i_ptr; X{ X *s_ptr = *i_ptr; X if ((s_ptr->number > 1) && (s_ptr->subval >= ITEM_SINGLE_STACK_MIN) X && (s_ptr->subval <= ITEM_SINGLE_STACK_MAX)) X s_ptr->number = 1; X} X X X/* Drops an item from inventory to given location -RAK- */ Xvoid inven_drop(item_val, drop_all) Xregister int item_val, drop_all; X{ X int i; X register inven_type *i_ptr; X vtype prt2; X bigvtype prt1; X X if (cave[char_row][char_col].tptr != 0) X (void) delete_object(char_row, char_col); X i = popt (); X i_ptr = &inventory[item_val]; X t_list[i] = *i_ptr; X cave[char_row][char_col].tptr = i; X X if (item_val >= INVEN_WIELD) X takeoff (item_val, -1); X else X { X if (drop_all || i_ptr->number == 1) X { X inven_weight -= i_ptr->weight*i_ptr->number; X inven_ctr--; X while (item_val < inven_ctr) X { X inventory[item_val] = inventory[item_val+1]; X item_val++; X } X invcopy(&inventory[inven_ctr], OBJ_NOTHING); X } X else X { X t_list[i].number = 1; X inven_weight -= i_ptr->weight; X i_ptr->number--; X } X objdes (prt1, &t_list[i], TRUE); X (void) sprintf (prt2, "Dropped %s", prt1); X msg_print (prt2); X } X py.flags.status |= PY_STR_WGT; X} X X X/* Destroys a type of item on a given percent chance -RAK- */ Xint inven_damage(typ, perc) Xint (*typ)(); Xregister int perc; X{ X register int i, j; X X j = 0; X for (i = 0; i < inven_ctr; i++) X if ((*typ)(inventory[i].tval) && (randint(100) < perc)) X { X inven_destroy(i); X j++; X } X return(j); X} X X X/* Computes current weight limit -RAK- */ Xint weight_limit() X{ X register int weight_cap; X X weight_cap = py.stats.use_stat[A_STR] * PLAYER_WEIGHT_CAP + py.misc.wt; X if (weight_cap > 3000) weight_cap = 3000; X return(weight_cap); X} X X X/* this code must be identical to the inven_carry() code below */ Xint inven_check_num (t_ptr) Xregister inven_type *t_ptr; X{ X register int i; X X if (inven_ctr < INVEN_WIELD) X return TRUE; X else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN) X for (i = 0; i < inven_ctr; i++) X if (inventory[i].tval == t_ptr->tval && X inventory[i].subval == t_ptr->subval && X /* make sure the number field doesn't overflow */ X ((int)inventory[i].number + (int)t_ptr->number < 256) && X /* they always stack (subval < 192), or else they have same p1 */ X ((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1)) X /* only stack if both or neither are identified */ X && (known1_p(&inventory[i]) == known1_p(t_ptr))) X return TRUE; X return FALSE; X} X X/* return FALSE if picking up an object would change the players speed */ Xint inven_check_weight(i_ptr) Xregister inven_type *i_ptr; X{ X register int i, new_inven_weight; X X i = weight_limit(); X new_inven_weight = i_ptr->number*i_ptr->weight + inven_weight; X if (i < new_inven_weight) X i = new_inven_weight / (i + 1); X else X i = 0; X X if (pack_heavy != i) X return FALSE; X else X return TRUE; X} X X X/* Are we strong enough for the current pack and weapon? -CJS- */ Xvoid check_strength() X{ X register int i; X register inven_type *i_ptr; X X i_ptr = &inventory[INVEN_WIELD]; X if (i_ptr->tval != TV_NOTHING X && (py.stats.use_stat[A_STR]*15 < i_ptr->weight)) X { X if (weapon_heavy == FALSE) X { X msg_print("You have trouble wielding such a heavy weapon."); X weapon_heavy = TRUE; X calc_bonuses(); X } X } X else if (weapon_heavy == TRUE) X { X weapon_heavy = FALSE; X if (i_ptr->tval != TV_NOTHING) X msg_print("You are strong enough to wield your weapon."); X calc_bonuses(); X } X i = weight_limit(); X if (i < inven_weight) X i = inven_weight / (i+1); X else X i = 0; X if (pack_heavy != i) X { X if (pack_heavy < i) X msg_print("Your pack is so heavy that it slows you down."); X else X msg_print("You move more easily under the weight of your pack."); X change_speed(i - pack_heavy); X pack_heavy = i; X } X py.flags.status &= ~PY_STR_WGT; X} X X X/* Add an item to players inventory. Return the */ X/* item position for a description if needed. -RAK- */ X/* this code must be identical to the inven_check_num() code above */ Xint inven_carry(i_ptr) Xregister inven_type *i_ptr; X{ X register int locn, i; X register int typ, subt; X register inven_type *t_ptr; X X typ = i_ptr->tval; X subt = i_ptr->subval; X /* Now, check to see if player can carry object */ X for (locn = 0; ; locn++) X { X t_ptr = &inventory[locn]; X if ((typ == t_ptr->tval) && (subt == t_ptr->subval) X && (subt >= ITEM_SINGLE_STACK_MIN) && X ((int)t_ptr->number + (int)i_ptr->number < 256) && X ((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1)) && X /* only stack if both or neither are identified */ X (known1_p(i_ptr) == known1_p(t_ptr))) X { X t_ptr->number += i_ptr->number; X break; X } X else if (typ > t_ptr->tval) X { X for (i = inven_ctr - 1; i >= locn; i--) X inventory[i+1] = inventory[i]; X inventory[locn] = *i_ptr; X inven_ctr++; X break; X } X } X X inven_weight += i_ptr->number*i_ptr->weight; X py.flags.status |= PY_STR_WGT; X return locn; X} X X X/* Returns spell chance of failure for spell -RAK- */ Xint spell_chance(spell) Xint spell; X{ X register spell_type *s_ptr; X register int chance; X register int stat; X X s_ptr = &magic_spell[py.misc.pclass-1][spell]; X chance = s_ptr->sfail - 3*(py.misc.lev-s_ptr->slevel); X if (class[py.misc.pclass].spell == MAGE) X stat = A_INT; X else X stat = A_WIS; X chance -= 3 * (stat_adj(stat)-1); X if (s_ptr->smana > py.misc.cmana) X chance += 5 * (s_ptr->smana-py.misc.cmana); X if (chance > 95) X chance = 95; X else if (chance < 5) X chance = 5; X return chance; X} X X X/* Print list of spells -RAK- */ X/* if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num X >=0: spells numbered by offset from nonconsec */ Xvoid print_spells(spell, num, comment, nonconsec) Xint *spell; Xregister int num; Xint comment, nonconsec; X{ X register int i, j; X vtype out_val; X register spell_type *s_ptr; X int col, offset; X char *p; X char spell_char; X X if (comment) X col = 22; X else X col = 31; X offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET); X erase_line(1, col); X put_buffer("Name", 1, col+5); X put_buffer("Lv Mana Fail", 1, col+35); X /* only show the first 22 choices */ X if (num > 22) X num = 22; X for (i = 0; i < num; i++) X { X j = spell[i]; X s_ptr = &magic_spell[py.misc.pclass-1][j]; X if (comment == FALSE) X p = ""; X else if ((spell_forgotten & (1L << j)) != 0) X p = " forgotten"; X else if ((spell_learned & (1L << j)) == 0) X p = " unknown"; X else if ((spell_worked & (1L << j)) == 0) X p = " untried"; X else X p = ""; X /* determine whether or not to leave holes in character choices, X nonconsec -1 when learning spells, consec offset>=0 when asking which X spell to cast */ X if (nonconsec == -1) X spell_char = 'a' + i; X else X spell_char = 'a' + j - nonconsec; X (void) sprintf(out_val, " %c) %-30s%2d %4d %3d%%%s", spell_char, X spell_names[j+offset], s_ptr->slevel, s_ptr->smana, X spell_chance (j), p); X prt(out_val, 2+i, col); X } X} X X X/* Returns spell pointer -RAK- */ Xint get_spell(spell, num, sn, sc, prompt, first_spell) Xint *spell; Xregister int num; Xregister int *sn, *sc; Xchar *prompt; Xint first_spell; X{ X register spell_type *s_ptr; X int flag, redraw, offset, i; X char choice; X vtype out_str, tmp_str; X X *sn = -1; X flag = FALSE; X (void) sprintf(out_str, "(Spells %c-%c, *=List, =exit) %s", X spell[0]+'a'-first_spell, spell[num-1]+'a'-first_spell, X prompt); X redraw = FALSE; X offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET); X while (flag == FALSE && get_com (out_str, &choice)) X { X if (isupper((int)choice)) X { X *sn = choice-'A'+first_spell; X /* verify that this is in spell[], at most 22 entries in spell[] */ X for (i = 0; i < num; i++) X if (*sn == spell[i]) X break; X if (i == num) X *sn = -2; X else X { X s_ptr = &magic_spell[py.misc.pclass-1][*sn]; X (void) sprintf (tmp_str, "Cast %s (%d mana, %d%% fail)?", X spell_names[*sn+offset], s_ptr->smana, X spell_chance (*sn)); X if (get_check (tmp_str)) X flag = TRUE; X else X *sn = -1; X } X } X else if (islower((int)choice)) X { X *sn = choice-'a'+first_spell; X /* verify that this is in spell[], at most 22 entries in spell[] */ X for (i = 0; i < num; i++) X if (*sn == spell[i]) X break; X if (i == num) X *sn = -2; X else X flag = TRUE; X } X else if (choice == '*') X { X /* only do this drawing once */ X if (!redraw) X { X save_screen (); X redraw = TRUE; X print_spells (spell, num, FALSE, first_spell); X } X } X else if (isalpha((int)choice)) X *sn = -2; X else X { X *sn = -1; X bell(); X } X if (*sn == -2) X msg_print("You don't know that spell."); X } X if (redraw) X restore_screen (); X X erase_line(MSG_LINE, 0); X if (flag) X *sc = spell_chance (*sn); X X return(flag); X} X X X/* calculate number of spells player should have, and learn forget spells X until that number is met -JEW- */ Xvoid calc_spells(stat) Xint stat; X{ X register int i; X register int32u mask; X int32u spell_flag; X int j, offset; X int num_allowed, new_spells, num_known, levels; X vtype tmp_str; X char *p; X register struct misc *p_ptr; X register spell_type *msp_ptr; X X p_ptr = &py.misc; X msp_ptr = &magic_spell[p_ptr->pclass-1][0]; X if (stat == A_INT) X { X p = "spell"; X offset = SPELL_OFFSET; X } X else X { X p = "prayer"; X offset = PRAYER_OFFSET; X } X X /* check to see if know any spells greater than level, eliminate them */ X for (i = 31, mask = 0x80000000; mask; mask >>= 1, i--) X if (mask & spell_learned) X { X if (msp_ptr[i].slevel > p_ptr->lev) X { X spell_learned &= ~mask; X spell_forgotten |= mask; X (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p, X spell_names[i+offset]); X msg_print(tmp_str); X } X else X break; X } X X /* calc number of spells allowed */ X levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1; X switch(stat_adj(stat)) X { X case 0: num_allowed = 0; break; X case 1: case 2: case 3: num_allowed = 1 * levels; break; X case 4: case 5: num_allowed = 3 * levels / 2; break; X case 6: num_allowed = 2 * levels; break; X case 7: num_allowed = 5 * levels / 2; break; X } X X num_known = 0; X for (mask = 0x1; mask; mask <<= 1) X if (mask & spell_learned) X num_known++; X new_spells = num_allowed - num_known; X X if (new_spells > 0) X { X /* remember forgotten spells while forgotten spells exist of new_spells X positive, remember the spells in the order that they were learned */ X for (i = 0; (spell_forgotten && new_spells X && (i < num_allowed) && (i < 32)); i++) X { X /* j is (i+1)th spell learned */ X j = spell_order[i]; X /* shifting by amounts greater than number of bits in long gives X an undefined result, so don't shift for unknown spells */ X if (j == 99) X mask = 0x0; X else X mask = 1L << j; X if (mask & spell_forgotten) X { X if (msp_ptr[j].slevel <= p_ptr->lev) X { X new_spells--; X spell_forgotten &= ~mask; X spell_learned |= mask; X (void) sprintf(tmp_str, "You have remembered the %s of %s.", X p, spell_names[j+offset]); X msg_print(tmp_str); X } X else X num_allowed++; X } X } X X if (new_spells > 0) X { X /* determine which spells player can learn */ X /* must check all spells here, in gain_spell() we actually check X if the books are present */ X spell_flag = 0x7FFFFFFFL & ~spell_learned; X X mask = 0x1; X i = 0; X for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++) X if (spell_flag & mask) X { X spell_flag &= ~mask; X if (msp_ptr[j].slevel <= p_ptr->lev) X i++; X } X X if (new_spells > i) X new_spells = i; X } X } X else if (new_spells < 0) X { X /* forget spells until new_spells zero or no more spells know, spells X are forgotten in the opposite order that they were learned */ X for (i = 31; new_spells && spell_learned; i--) X { X /* j is the (i+1)th spell learned */ X j = spell_order[i]; X /* shifting by amounts greater than number of bits in long gives X an undefined result, so don't shift for unknown spells */ X if (j == 99) X mask = 0x0; X else X mask = 1L << j; X if (mask & spell_learned) X { X spell_learned &= ~mask; X spell_forgotten |= mask; X new_spells++; X (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p, X spell_names[j+offset]); X msg_print(tmp_str); X } X } X X new_spells = 0; X } X X if (new_spells != py.flags.new_spells) X { X if (new_spells > 0 && py.flags.new_spells == 0) X { X (void) sprintf(tmp_str, "You can learn some new %ss now.", p); X msg_print(tmp_str); X } X X py.flags.new_spells = new_spells; X py.flags.status |= PY_STUDY; X } X} X X X/* gain spells when player wants to - jw */ Xvoid gain_spells() X{ X char query; X int stat, diff_spells, new_spells; X int spells[31], offset, last_known; X register int i, j; X register int32u spell_flag, mask; X vtype tmp_str; X struct misc *p_ptr; X register spell_type *msp_ptr; X X i = 0; X if (py.flags.blind > 0) X msg_print("You can't see to read your spell book!"); X else if (no_light()) X msg_print("You have no light to read by."); X else if (py.flags.confused > 0) X msg_print("You are too confused."); X else X i = 1; X if (i == 0) X return; X X new_spells = py.flags.new_spells; X diff_spells = 0; X p_ptr = &py.misc; X msp_ptr = &magic_spell[p_ptr->pclass-1][0]; X if (class[p_ptr->pclass].spell == MAGE) X { X stat = A_INT; X offset = SPELL_OFFSET; X } X else X { X stat = A_WIS; X offset = PRAYER_OFFSET; X } X X for (last_known = 0; last_known < 32; last_known++) X if (spell_order[last_known] == 99) X break; X X if (!new_spells) X { X (void) sprintf(tmp_str, "You can't learn any new %ss!", X (stat == A_INT ? "spell" : "prayer")); X msg_print(tmp_str); X free_turn_flag = TRUE; X } X else X { X /* determine which spells player can learn */ X /* mages need the book to learn a spell, priests do not need the book */ X if (stat == A_INT) X { X spell_flag = 0; X for (i = 0; i < inven_ctr; i++) X if (((stat == A_INT) && (inventory[i].tval == TV_MAGIC_BOOK)) X || ((stat == A_WIS) && (inventory[i].tval == TV_PRAYER_BOOK))) X spell_flag |= inventory[i].flags; X } X else X spell_flag = 0x7FFFFFFF; X X /* clear bits for spells already learned */ X spell_flag &= ~spell_learned; X X mask = 0x1; X i = 0; X for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++) X if (spell_flag & mask) X { X spell_flag &= ~mask; X if (msp_ptr[j].slevel <= p_ptr->lev) X { X spells[i] = j; X i++; X } X } X X if (new_spells > i) X { X msg_print("You seem to be missing a book."); X diff_spells = new_spells - i; X new_spells = i; X } X if (new_spells == 0) X ; X else if (stat == A_INT) X { X /* get to choose which mage spells will be learned */ X save_screen(); X print_spells (spells, i, FALSE, -1); X while (new_spells && get_com ("Learn which spell?", &query)) X { X j = query - 'a'; X /* test j < 23 in case i is greater than 22, only 22 spells X are actually shown on the screen, so limit choice to those */ X if (j >= 0 && j < i && j < 22) X { X new_spells--; X spell_learned |= 1L << spells[j]; X spell_order[last_known++] = spells[j]; X for (; j <= i-1; j++) X spells[j] = spells[j+1]; X i--; X erase_line (j+1, 31); X print_spells (spells, i, FALSE, -1); X } X else X bell(); X } X restore_screen(); X } X else X { X /* pick a prayer at random */ X while (new_spells) X { X j = randint(i) - 1; X spell_learned |= 1L << spells[j]; X spell_order[last_known++] = spells[j]; X (void) sprintf (tmp_str, X "You have learned the prayer of %s.", X spell_names[spells[j]+offset]); X msg_print(tmp_str); X for (; j <= i-1; j++) X spells[j] = spells[j+1]; X i--; X new_spells--; X } X } X py.flags.new_spells = new_spells + diff_spells; X if (py.flags.new_spells == 0) X py.flags.status |= PY_STUDY; X /* set the mana for first level characters when they learn first spell */ X if (py.misc.mana == 0) X calc_mana(stat); X } X} X X X/* Gain some mana if you know at least one spell -RAK- */ Xvoid calc_mana(stat) Xint stat; X{ X register int new_mana, levels; X register struct misc *p_ptr; X register int32 value; X X p_ptr = &py.misc; X if (spell_learned != 0) X { X levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1; X switch(stat_adj(stat)) X { X case 0: new_mana = 0; break; X case 1: case 2: new_mana = 1 * levels; break; X case 3: new_mana = 3 * levels / 2; break; X case 4: new_mana = 2 * levels; break; X case 5: new_mana = 5 * levels / 2; break; X case 6: new_mana = 3 * levels; break; X case 7: new_mana = 4 * levels; break; X } X /* increment mana by one, so that first level chars have 2 mana */ X if (new_mana > 0) X new_mana++; X X /* mana can be zero when creating character */ X if (p_ptr->mana != new_mana) X { X if (p_ptr->mana != 0) X { X /* change current mana proportionately to change of max mana, X divide first to avoid overflow, little loss of accuracy */ X value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac) X / p_ptr->mana * new_mana; X p_ptr->cmana = value >> 16; X p_ptr->cmana_frac = value & 0xFFFF; X } X else X { X p_ptr->cmana = new_mana; X p_ptr->cmana_frac = 0; X } X p_ptr->mana = new_mana; X /* can't print mana here, may be in store or inventory mode */ X py.flags.status |= PY_MANA; X } X } X else if (p_ptr->mana != 0) X { X p_ptr->mana = 0; X p_ptr->cmana = 0; X /* can't print mana here, may be in store or inventory mode */ X py.flags.status |= PY_MANA; X } X} X X X/* Increases hit points and level -RAK- */ Xstatic void gain_level() X{ X register int32 dif_exp, need_exp; X vtype out_val; X register struct misc *p_ptr; X register class_type *c_ptr; X X p_ptr = &py.misc; X p_ptr->lev++; X (void) sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev); X msg_print(out_val); X calc_hitpoints(); X X need_exp = player_exp[p_ptr->lev-1] * p_ptr->expfact / 100; X if (p_ptr->exp > need_exp) X { X /* lose some of the 'extra' exp when gain a level */ X dif_exp = p_ptr->exp - need_exp; X p_ptr->exp = need_exp + (dif_exp / 2); X } X prt_level(); X prt_title(); X c_ptr = &class[p_ptr->pclass]; X if (c_ptr->spell == MAGE) X { X calc_spells(A_INT); X calc_mana(A_INT); X } X else if (c_ptr->spell == PRIEST) X { X calc_spells(A_WIS); X calc_mana(A_WIS); X } X} X X/* Prints experience -RAK- */ Xvoid prt_experience() X{ X register struct misc *p_ptr; X X p_ptr = &py.misc; X if (p_ptr->exp > MAX_EXP) X p_ptr->exp = MAX_EXP; X if (p_ptr->lev < MAX_PLAYER_LEVEL) X { X while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp) X gain_level(); X if (p_ptr->exp > p_ptr->max_exp) X p_ptr->max_exp = p_ptr->exp; X } X prt_long(p_ptr->exp, 14, STAT_COLUMN+6); X} X X X/* Calculate the players hit points */ Xvoid calc_hitpoints() X{ X register int hitpoints; X register struct misc *p_ptr; X register int32 value; X X p_ptr = &py.misc; X hitpoints = player_hp[p_ptr->lev-1] + (con_adj() * p_ptr->lev); X /* always give at least one point per level + 1 */ X if (hitpoints < (p_ptr->lev + 1)) X hitpoints = p_ptr->lev + 1; X X if (py.flags.status & PY_HERO) X hitpoints += 10; X if (py.flags.status & PY_SHERO) X hitpoints += 20; X X /* mhp can equal zero while character is being created */ X if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0)) X { X /* change current hit points proportionately to change of mhp, X divide first to avoid overflow, little loss of accuracy */ X value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp X * hitpoints; X p_ptr->chp = value >> 16; X p_ptr->chp_frac = value & 0xFFFF; X p_ptr->mhp = hitpoints; X X /* can't print hit points here, may be in store or inventory mode */ X py.flags.status |= PY_HP; X } X} X X X/* Inserts a string into a string */ Xvoid insert_str(object_str, mtc_str, insert) Xchar *object_str, *mtc_str, *insert; X{ X int obj_len; X char *bound, *pc; X register int i, mtc_len; X register char *temp_obj, *temp_mtc; X char out_val[80]; X X mtc_len = strlen(mtc_str); X obj_len = strlen(object_str); X bound = object_str + obj_len - mtc_len; X for (pc = object_str; pc <= bound; pc++) X { X temp_obj = pc; X temp_mtc = mtc_str; X for (i = 0; i < mtc_len; i++) X if (*temp_obj++ != *temp_mtc++) X break; X if (i == mtc_len) X break; X } X X if (pc <= bound) X { X (void) strncpy(out_val, object_str, (pc-object_str)); X out_val[(pc-object_str)] = '\0'; X if (insert) X (void) strcat(out_val, insert); X (void) strcat(out_val, (char *)(pc+mtc_len)); X (void) strcpy(object_str, out_val); X } X} X X X#if 0 X/* this is no longer used anywhere */ X/* Inserts a number into a string */ Xvoid insert_num(object_str, mtc_str, number, show_sign) Xchar *object_str; Xregister char *mtc_str; Xint number; Xint show_sign; X{ X int mlen; X vtype str1, str2; X register char *string, *tmp_str; X int flag; X X flag = 1; X mlen = strlen(mtc_str); X tmp_str = object_str; X do X { X string = index(tmp_str, mtc_str[0]); X if (string == NULL) X flag = 0; X else X { X flag = strncmp(string, mtc_str, mlen); X if (flag) X tmp_str = string+1; X } X } X while (flag); X if (string) X { X (void) strncpy(str1, object_str, string - object_str); X str1[string - object_str] = '\0'; X (void) strcpy(str2, string + mlen); X if ((number >= 0) && (show_sign)) X (void) sprintf(object_str, "%s+%d%s", str1, number, str2); X else X (void) sprintf(object_str, "%s%d%s", str1, number, str2); X } X} X#endif X Xvoid insert_lnum(object_str, mtc_str, number, show_sign) Xchar *object_str; Xregister char *mtc_str; Xint32 number; Xint show_sign; X{ X int mlen; X vtype str1, str2; X register char *string, *tmp_str; X int flag; X X flag = 1; X mlen = strlen(mtc_str); X tmp_str = object_str; X do X { X string = index(tmp_str, mtc_str[0]); X if (string == 0) X flag = 0; X else X { X flag = strncmp(string, mtc_str, mlen); X if (flag) X tmp_str = string+1; X } X } X while (flag); X if (string) X { X (void) strncpy(str1, object_str, string - object_str); X str1[string - object_str] = '\0'; X (void) strcpy(str2, string + mlen); X if ((number >= 0) && (show_sign)) X (void) sprintf(object_str, "%s+%ld%s", str1, number, str2); X else X (void) sprintf(object_str, "%s%ld%s", str1, number, str2); X } X} X X X/* lets anyone enter wizard mode after a disclaimer... - JEW - */ Xint enter_wiz_mode() X{ X register int answer; X X if (!noscore) X { X msg_print("Wizard mode is for debugging and experimenting."); X answer = get_check( X "The game will not be scored if you enter wizard mode. Are you sure?"); X } X if (noscore || answer) X { X noscore |= 0x2; X wizard = TRUE; X return(TRUE); X } X return(FALSE); X} X X X/* Weapon weight VS strength and dexterity -RAK- */ Xint attack_blows(weight, wtohit) Xint weight; Xint *wtohit; X{ X register int adj_weight; X register int str_index, dex_index, s, d; X X s = py.stats.use_stat[A_STR]; X d = py.stats.use_stat[A_DEX]; X if (s * 15 < weight) X { X *wtohit = s * 15 - weight; X return 1; X } X else X { X *wtohit = 0; X if (d < 10) dex_index = 0; X else if (d < 19) dex_index = 1; X else if (d < 68) dex_index = 2; X else if (d < 108) dex_index = 3; X else if (d < 118) dex_index = 4; X else dex_index = 5; X adj_weight = (s * 10 / weight); X if (adj_weight < 2) str_index = 0; X else if (adj_weight < 3) str_index = 1; X else if (adj_weight < 4) str_index = 2; X else if (adj_weight < 5) str_index = 3; X else if (adj_weight < 7) str_index = 4; X else if (adj_weight < 9) str_index = 5; X else str_index = 6; X return (int)blows_table[str_index][dex_index]; X } X} X X X/* Special damage due to magical abilities of object -RAK- */ Xint tot_dam(i_ptr, tdam, monster) Xregister inven_type *i_ptr; Xregister int tdam; Xint monster; X{ X register creature_type *m_ptr; X register recall_type *r_ptr; X X if ((i_ptr->flags & TR_EGO_WEAPON) && X (((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) || X ((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) || X (i_ptr->tval == TV_FLASK))) X { X m_ptr = &c_list[monster]; X r_ptr = &c_recall[monster]; X /* Slay Dragon */ X if ((m_ptr->cdefense & CD_DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON)) X { X tdam = tdam * 4; X r_ptr->r_cdefense |= CD_DRAGON; X } X /* Slay Undead */ X else if ((m_ptr->cdefense & CD_UNDEAD) &&(i_ptr->flags & TR_SLAY_UNDEAD)) X { X tdam = tdam * 3; X r_ptr->r_cdefense |= CD_UNDEAD; X } X /* Slay Animal */ X else if ((m_ptr->cdefense & CD_ANIMAL) &&(i_ptr->flags & TR_SLAY_ANIMAL)) X { X tdam = tdam * 2; X r_ptr->r_cdefense |= CD_ANIMAL; X } X /* Slay Evil */ X else if ((m_ptr->cdefense & CD_EVIL) && (i_ptr->flags & TR_SLAY_EVIL)) X { X tdam = tdam * 2; X r_ptr->r_cdefense |= CD_EVIL; X } X /* Frost */ X else if ((m_ptr->cdefense & CD_FROST) && (i_ptr->flags & TR_FROST_BRAND)) X { X tdam = tdam * 3 / 2; X r_ptr->r_cdefense |= CD_FROST; X } X /* Fire */ X else if ((m_ptr->cdefense & CD_FIRE) && (i_ptr->flags & TR_FLAME_TONGUE)) X { X tdam = tdam * 3 / 2; X r_ptr->r_cdefense |= CD_FIRE; X } X } X return(tdam); X} X X X/* Critical hits, Nasty way to die. -RAK- */ Xint critical_blow(weight, plus, dam, attack_type) Xregister int weight, plus, dam; Xint attack_type; X{ X register int critical; X X critical = dam; X /* Weight of weapon, plusses to hit, and character level all */ X /* contribute to the chance of a critical */ X if (randint(5000) <= (int)(weight + 5 * plus X + (class_level_adj[py.misc.pclass][attack_type] X * py.misc.lev))) X { X weight += randint(650); X if (weight < 400) X { X critical = 2*dam + 5; X msg_print("It was a good hit! (x2 damage)"); X } X else if (weight < 700) X { X critical = 3*dam + 10; X msg_print("It was an excellent hit! (x3 damage)"); X } X else if (weight < 900) X { X critical = 4*dam + 15; X msg_print("It was a superb hit! (x4 damage)"); X } X else X { X critical = 5*dam + 20; X msg_print("It was a *GREAT* hit! (x5 damage)"); X } X } X return(critical); X} X X X/* Given direction "dir", returns new row, column location -RAK- */ Xint mmove(dir, y, x) Xint dir; Xregister int *y, *x; X{ X register int new_row, new_col; X int bool; X X switch(dir) X { X case 1: X new_row = *y + 1; X new_col = *x - 1; X break; X case 2: X new_row = *y + 1; X new_col = *x; X break; X case 3: X new_row = *y + 1; X new_col = *x + 1; X break; X case 4: X new_row = *y; X new_col = *x - 1; X break; X case 5: X new_row = *y; X new_col = *x; X break; X case 6: X new_row = *y; X new_col = *x + 1; X break; X case 7: X new_row = *y - 1; X new_col = *x - 1; X break; X case 8: X new_row = *y - 1; X new_col = *x; X break; X case 9: X new_row = *y - 1; X new_col = *x + 1; X break; X } X bool = FALSE; X if ((new_row >= 0) && (new_row < cur_height) X && (new_col >= 0) && (new_col < cur_width)) X { X *y = new_row; X *x = new_col; X bool = TRUE; X } X return(bool); X} X X/* Saving throws for player character. -RAK- */ Xint player_saves() X{ X if (randint(100) <= (py.misc.save + stat_adj(A_WIS) X + (class_level_adj[py.misc.pclass][CLA_SAVE] X * py.misc.lev / 3))) X return(TRUE); X else X return(FALSE); X} X X X/* Finds range of item in inventory list -RAK- */ Xint find_range(item1, item2, j, k) Xint item1, item2; Xregister int *j, *k; X{ X register int i; X register inven_type *i_ptr; X int flag; X X i = 0; X *j = -1; X *k = -1; X flag = FALSE; X i_ptr = &inventory[0]; X while (i < inven_ctr) X { X if (!flag) X { X if ((i_ptr->tval == item1) || (i_ptr->tval == item2)) X { X flag = TRUE; X *j = i; X } X } X else X { X if ((i_ptr->tval != item1) && (i_ptr->tval != item2)) X { X *k = i - 1; X break; X } X } X i++; X i_ptr++; X } X if (flag && (*k == -1)) X *k = inven_ctr - 1; X return(flag); X} X X X/* Teleport the player to a new location -RAK- */ Xvoid teleport(dis) Xint dis; X{ X register int y, x, i, j; X X do X { X y = randint(cur_height) - 1; X x = randint(cur_width) - 1; X while (distance(y, x, char_row, char_col) > dis) X { X y += ((char_row-y)/2); X x += ((char_col-x)/2); X } X } X while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr >= 2)); X move_rec(char_row, char_col, y, x); X for (i = char_row-1; i <= char_row+1; i++) X for (j = char_col-1; j <= char_col+1; j++) X { X cave[i][j].tl = FALSE; X lite_spot(i, j); X } X lite_spot(char_row, char_col); X char_row = y; X char_col = x; X check_view(); X creatures(FALSE); X teleport_flag = FALSE; X} X X X/* Add a comment to an object description. -CJS- */ Xvoid scribe_object() X{ X int item_val, j; X vtype out_val, tmp_str; X X if (inven_ctr > 0 || equip_ctr > 0) X { X if (get_item(&item_val, "Which one? ", 0, INVEN_ARRAY_SIZE)) X { X objdes(tmp_str, &inventory[item_val], TRUE); X (void) sprintf(out_val, "Inscribing %s", tmp_str); X msg_print(out_val); X if (inventory[item_val].inscrip[0] != '\0') X (void) sprintf(out_val, "Replace %s New inscription:", X inventory[item_val].inscrip); X else X (void) strcpy(out_val, "Inscription: "); X j = 78 - strlen(tmp_str); X if (j > 24) X j = 12; X prt(out_val, 0, 0); X if (get_string(out_val, 0, strlen(out_val), j)) X inscribe(&inventory[item_val], out_val); X } X } X else X msg_print("You are not carrying anything to inscribe."); X} X X/* Append an additional comment to an object description. -CJS- */ Xvoid add_inscribe(i_ptr, type) Xinven_type *i_ptr; Xint8u type; X{ X i_ptr->ident |= type; X} X X/* Replace any existing comment in an object description with a new one. CJS*/ Xvoid inscribe(i_ptr, str) Xinven_type *i_ptr; Xchar *str; X{ X (void) strcpy(i_ptr->inscrip, str); X} X X X/* We need to reset the view of things. -CJS- */ Xvoid check_view() X{ X register int i, j; X register cave_type *c_ptr, *d_ptr; X X c_ptr = &cave[char_row][char_col]; X /* Check for new panel */ X if (get_panel(char_row, char_col, FALSE)) X prt_map(); X /* Move the light source */ X move_light(char_row, char_col, char_row, char_col); X /* A room of light should be lit. */ X if (c_ptr->fval == LIGHT_FLOOR) X { X if ((py.flags.blind < 1) && !c_ptr->pl) X light_room(char_row, char_col); X } X /* In doorway of light-room? */ X else if (c_ptr->lr && (py.flags.blind < 1)) X { X for (i = (char_row - 1); i <= (char_row + 1); i++) X for (j = (char_col - 1); j <= (char_col + 1); j++) X { X d_ptr = &cave[i][j]; X if ((d_ptr->fval == LIGHT_FLOOR) && !d_ptr->pl) X light_room(i, j); X } X } X} END_OF_FILE if test 57629 -ne `wc -c <'misc2.c'`; then echo shar: \"'misc2.c'\" unpacked with wrong size! fi # end of 'misc2.c' fi echo shar: End of archive 5 \(of 31\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 31 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0