home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v14i053: umoria4 - single player dungeon simulation (ver. 5.5), Part21/39
- Message-ID: <3417@master.CNA.TEK.COM>
- Date: 22 Aug 92 22:12:25 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2162
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: grabiner@math.harvard.edu (David Grabiner)
- Posting-number: Volume 14, Issue 53
- Archive-name: umoria4/Part21
- Supersedes: umoria3: Volume 9, Issue 55-97; Volume 10, Issue 15-17
- Environment: Curses, Unix, Mac, MS-DOS, Atari-ST, Amiga, VMS
-
-
-
- #! /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 <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 21 (of 39)."
- # Contents: source/misc3.c.2 source/moria2.c unix/Makefile
- # Wrapped by billr@saab on Thu Aug 20 09:11:31 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'source/misc3.c.2' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/misc3.c.2'\"
- else
- echo shar: Extracting \"'source/misc3.c.2'\" \(30036 characters\)
- sed "s/^X//" >'source/misc3.c.2' <<'END_OF_FILE'
- 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#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- 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#ifdef ATARIST_MWC
- X py.flags.status &= ~(holder = PY_STR_WGT);
- X#else
- X py.flags.status &= ~PY_STR_WGT;
- X#endif
- 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 int known1p, always_known1p;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X typ = i_ptr->tval;
- X subt = i_ptr->subval;
- X known1p = known1_p (i_ptr);
- X always_known1p = (object_offset (i_ptr) == -1);
- 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 (known1p == known1_p(t_ptr)))
- X {
- X t_ptr->number += i_ptr->number;
- X break;
- X }
- X /* For items which are always known1p, i.e. never have a 'color',
- X insert them into the inventory in sorted order. */
- X else if ((typ == t_ptr->tval && subt < t_ptr->subval
- X && always_known1p)
- X || (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#ifdef ATARIST_MWC
- X py.flags.status |= (holder = PY_STR_WGT);
- X#else
- X py.flags.status |= PY_STR_WGT;
- X#endif
- 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, <ESCAPE>=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 {
- X (void) sprintf (tmp_str, "You don't know that %s.",
- X (offset == SPELL_OFFSET ? "spell" : "prayer"));
- X msg_print(tmp_str);
- X }
- 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 = 0x80000000L; 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 /* Priests don't need light because they get spells from their god,
- X so only fail when can't see if player has MAGE spells. This check
- X is done below. */
- X if (py.flags.confused > 0)
- X {
- X msg_print("You are too confused.");
- X return;
- X }
- 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 /* People with MAGE spells can't learn spells if they can't read their
- X books. */
- X if (py.flags.blind > 0)
- X {
- X msg_print("You can't see to read your spell book!");
- X return;
- X }
- X else if (no_light())
- X {
- X msg_print("You have no light to read by.");
- X return;
- X }
- 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 (inventory[i].tval == TV_MAGIC_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 their
- X 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#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- 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#ifdef ATARIST_MWC
- X py.flags.status |= (holder = PY_MANA);
- X#else
- X py.flags.status |= PY_MANA;
- X#endif
- 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#ifdef ATARIST_MWC
- X py.flags.status |= (holder = PY_MANA);
- X#else
- X py.flags.status |= PY_MANA;
- X#endif
- 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
- X if (p_ptr->lev < MAX_PLAYER_LEVEL)
- X while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp)
- X gain_level();
- X
- 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#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- 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#ifdef ATARIST_MWC
- X py.flags.status |= (holder = PY_HP);
- X#else
- X py.flags.status |= PY_HP;
- X#endif
- 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#ifdef __TURBOC__
- X /* Avoid complaint about possible loss of significance. */
- X (void) strncpy(out_val, object_str, (size_t)(pc-object_str));
- X#else
- X (void) strncpy(out_val, object_str, (pc-object_str));
- X#endif
- X /* Turbo C needs int for array index. */
- X out_val[(int)(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 == CNIL)
- 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#ifdef __TURBOC__
- X /* Avoid complaint about possible loss of significance. */
- X (void) strncpy(str1, object_str, (size_t)(string - object_str));
- X#else
- X (void) strncpy(str1, object_str, string - object_str);
- X#endif
- X /* Turbo C needs int for array index. */
- X str1[(int)(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#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X#ifdef ATARIST_MWC
- X if ((i_ptr->flags & (holder = TR_EGO_WEAPON)) &&
- X#else
- X if ((i_ptr->flags & TR_EGO_WEAPON) &&
- X#endif
- 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#ifdef ATARIST_MWC
- X else if ((m_ptr->cdefense & CD_UNDEAD)
- X && (i_ptr->flags & (holderr = TR_SLAY_UNDEAD)))
- X#else
- X else if ((m_ptr->cdefense & CD_UNDEAD)
- X && (i_ptr->flags & TR_SLAY_UNDEAD))
- X#endif
- X {
- X tdam = tdam * 3;
- X r_ptr->r_cdefense |= CD_UNDEAD;
- X }
- X /* Slay Animal */
- X else if ((m_ptr->cdefense & CD_ANIMAL)
- X && (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#ifdef ATARIST_MWC
- X else if ((m_ptr->cdefense & CD_FROST)
- X && (i_ptr->flags & (holder = TR_FROST_BRAND)))
- X#else
- X else if ((m_ptr->cdefense & CD_FROST)
- X && (i_ptr->flags & TR_FROST_BRAND))
- X#endif
- X {
- X tdam = tdam * 3 / 2;
- X r_ptr->r_cdefense |= CD_FROST;
- X }
- X /* Fire */
- X#ifdef ATARIST_MWC
- X else if ((m_ptr->cdefense & CD_FIRE)
- X && (i_ptr->flags & (holder = TR_FLAME_TONGUE)))
- X#else
- X else if ((m_ptr->cdefense & CD_FIRE)
- X && (i_ptr->flags & TR_FLAME_TONGUE))
- X#endif
- 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 /* MPW C couldn't handle the expression, so split it into two parts */
- X int16 temp = class_level_adj[py.misc.pclass][CLA_SAVE];
- X
- X if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
- X + (temp * 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}
- END_OF_FILE
- if test 30036 -ne `wc -c <'source/misc3.c.2'`; then
- echo shar: \"'source/misc3.c.2'\" unpacked with wrong size!
- fi
- # end of 'source/misc3.c.2'
- fi
- if test -f 'source/moria2.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/moria2.c'\"
- else
- echo shar: Extracting \"'source/moria2.c'\" \(19056 characters\)
- sed "s/^X//" >'source/moria2.c' <<'END_OF_FILE'
- X/* source/moria2.c: misc code, mainly handles player movement, inventory, etc
- X
- X Copyright (c) 1989-92 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 <stdio.h>
- X
- X#include "config.h"
- X#include "constant.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#if defined(LINT_ARGS)
- Xstatic int see_wall(int, int, int);
- Xstatic int see_nothing(int, int, int);
- X#else
- Xstatic int see_wall();
- X#endif
- X
- X
- X/* Change a trap from invisible to visible -RAK- */
- X/* Note: Secret doors are handled here */
- Xvoid change_trap(y, x)
- Xregister int y, x;
- X{
- X register cave_type *c_ptr;
- X register inven_type *t_ptr;
- X
- X c_ptr = &cave[y][x];
- X t_ptr = &t_list[c_ptr->tptr];
- X if (t_ptr->tval == TV_INVIS_TRAP)
- X {
- X t_ptr->tval = TV_VIS_TRAP;
- X lite_spot(y, x);
- X }
- X else if (t_ptr->tval == TV_SECRET_DOOR)
- X {
- X /* change secret door to closed door */
- X t_ptr->index = OBJ_CLOSED_DOOR;
- X t_ptr->tval = object_list[OBJ_CLOSED_DOOR].tval;
- X t_ptr->tchar = object_list[OBJ_CLOSED_DOOR].tchar;
- X lite_spot(y, x);
- X }
- X}
- X
- X
- X/* Searches for hidden things. -RAK- */
- Xvoid search(y, x, chance)
- Xint y, x, chance;
- X{
- X register int i, j;
- X register cave_type *c_ptr;
- X register inven_type *t_ptr;
- X register struct flags *p_ptr;
- X bigvtype tmp_str, tmp_str2;
- X
- X p_ptr = &py.flags;
- X if (p_ptr->confused > 0)
- X chance = chance / 10;
- X if ((p_ptr->blind > 0) || no_light())
- X chance = chance / 10;
- X if (p_ptr->image > 0)
- X chance = chance / 10;
- X for (i = (y - 1); i <= (y + 1); i++)
- X for (j = (x - 1); j <= (x + 1); j++)
- X if (randint(100) < chance) /* always in_bounds here */
- X {
- X c_ptr = &cave[i][j];
- X /* Search for hidden objects */
- X if (c_ptr->tptr != 0)
- X {
- X t_ptr = &t_list[c_ptr->tptr];
- X /* Trap on floor? */
- X if (t_ptr->tval == TV_INVIS_TRAP)
- X {
- X objdes(tmp_str2, t_ptr, TRUE);
- X (void) sprintf(tmp_str,"You have found %s",tmp_str2);
- X msg_print(tmp_str);
- X change_trap(i, j);
- X end_find();
- X }
- X /* Secret door? */
- X else if (t_ptr->tval == TV_SECRET_DOOR)
- X {
- X msg_print("You have found a secret door.");
- X change_trap(i, j);
- X end_find();
- X }
- X /* Chest is trapped? */
- X else if (t_ptr->tval == TV_CHEST)
- X {
- X /* mask out the treasure bits */
- X if ((t_ptr->flags & CH_TRAPPED) > 1)
- X if (!known2_p(t_ptr))
- X {
- X known2(t_ptr);
- X msg_print("You have discovered a trap on the chest!");
- X }
- X else
- X msg_print("The chest is trapped!");
- X }
- X }
- X }
- X}
- X
- X
- X/* The running algorithm: -CJS-
- X
- X Overview: You keep moving until something interesting happens.
- X If you are in an enclosed space, you follow corners. This is
- X the usual corridor scheme. If you are in an open space, you go
- X straight, but stop before entering enclosed space. This is
- X analogous to reaching doorways. If you have enclosed space on
- X one side only (that is, running along side a wall) stop if
- X your wall opens out, or your open space closes in. Either case
- X corresponds to a doorway.
- X
- X What happens depends on what you can really SEE. (i.e. if you
- X have no light, then running along a dark corridor is JUST like
- X running in a dark room.) The algorithm works equally well in
- X corridors, rooms, mine tailings, earthquake rubble, etc, etc.
- X
- X These conditions are kept in static memory:
- X find_openarea You are in the open on at least one
- X side.
- X find_breakleft You have a wall on the left, and will
- X stop if it opens
- X find_breakright You have a wall on the right, and will
- X stop if it opens
- X
- X To initialize these conditions is the task of find_init. If
- X moving from the square marked @ to the square marked . (in the
- X two diagrams below), then two adjacent sqares on the left and
- X the right (L and R) are considered. If either one is seen to
- X be closed, then that side is considered to be closed. If both
- X sides are closed, then it is an enclosed (corridor) run.
- X
- X LL L
- X @. L.R
- X RR @R
- X
- X Looking at more than just the immediate squares is
- X significant. Consider the following case. A run along the
- X corridor will stop just before entering the center point,
- X because a choice is clearly established. Running in any of
- X three available directions will be defined as a corridor run.
- X Note that a minor hack is inserted to make the angled corridor
- X entry (with one side blocked near and the other side blocked
- X further away from the runner) work correctly. The runner moves
- X diagonally, but then saves the previous direction as being
- X straight into the gap. Otherwise, the tail end of the other
- X entry would be perceived as an alternative on the next move.
- X
- X #.#
- X ##.##
- X .@...
- X ##.##
- X #.#
- X
- X Likewise, a run along a wall, and then into a doorway (two
- X runs) will work correctly. A single run rightwards from @ will
- X stop at 1. Another run right and down will enter the corridor
- X and make the corner, stopping at the 2.
- X
- X #@ 1
- X ########### ######
- X 2 #
- X #############
- X #
- X
- X After any move, the function area_affect is called to
- X determine the new surroundings, and the direction of
- X subsequent moves. It takes a location (at which the runner has
- X just arrived) and the previous direction (from which the
- X runner is considered to have come). Moving one square in some
- X direction places you adjacent to three or five new squares
- X (for straight and diagonal moves) to which you were not
- X previously adjacent.
- X
- X ...! ... EG Moving from 1 to 2.
- X .12! .1.! . means previously adjacent
- X ...! ..2! ! means newly adjacent
- X !!!
- X
- X You STOP if you can't even make the move in the chosen
- X direction. You STOP if any of the new squares are interesting
- X in any way: usually containing monsters or treasure. You STOP
- X if any of the newly adjacent squares seem to be open, and you
- X are also looking for a break on that side. (i.e. find_openarea
- X AND find_break) You STOP if any of the newly adjacent squares
- X do NOT seem to be open and you are in an open area, and that
- X side was previously entirely open.
- X
- X Corners: If you are not in the open (i.e. you are in a
- X corridor) and there is only one way to go in the new squares,
- X then turn in that direction. If there are more than two new
- X ways to go, STOP. If there are two ways to go, and those ways
- X are separated by a square which does not seem to be open, then
- X STOP.
- X
- X Otherwise, we have a potential corner. There are two new open
- X squares, which are also adjacent. One of the new squares is
- X diagonally located, the other is straight on (as in the
- X diagram). We consider two more squares further out (marked
- X below as ?).
- X .X
- X @.?
- X #?
- X If they are both seen to be closed, then it is seen that no
- X benefit is gained from moving straight. It is a known corner.
- X To cut the corner, go diagonally, otherwise go straight, but
- X pretend you stepped diagonally into that next location for a
- X full view next time. Conversely, if one of the ? squares is
- X not seen to be closed, then there is a potential choice. We check
- X to see whether it is a potential corner or an intersection/room entrance.
- X If the square two spaces straight ahead, and the space marked with 'X'
- X are both blank, then it is a potential corner and enter if find_examine
- X is set, otherwise must stop because it is not a corner. */
- X
- X/* The cycle lists the directions in anticlockwise order, for -CJS-
- X over two complete cycles. The chome array maps a direction on
- X to its position in the cycle.
- X*/
- Xstatic int cycle[] = { 1, 2, 3, 6, 9, 8, 7, 4, 1, 2, 3, 6, 9, 8, 7, 4, 1 };
- Xstatic int chome[] = { -1, 8, 9, 10, 7, -1, 11, 6, 5, 4 };
- Xstatic int find_openarea, find_breakright, find_breakleft, find_prevdir;
- Xstatic int find_direction; /* Keep a record of which way we are going. */
- X
- Xvoid find_init(dir)
- Xint dir;
- X{
- X int row, col, deepleft, deepright;
- X register int i, shortleft, shortright;
- X
- X row = char_row;
- X col = char_col;
- X if (!mmove(dir, &row, &col))
- X find_flag = FALSE;
- X else
- X {
- X find_direction = dir;
- X find_flag = 1;
- X find_breakright = find_breakleft = FALSE;
- X find_prevdir = dir;
- X if (py.flags.blind < 1)
- X {
- X i = chome[dir];
- X deepleft = deepright = FALSE;
- X shortright = shortleft = FALSE;
- X if (see_wall(cycle[i+1], char_row, char_col))
- X {
- X find_breakleft = TRUE;
- X shortleft = TRUE;
- X }
- X else if (see_wall(cycle[i+1], row, col))
- X {
- X find_breakleft = TRUE;
- X deepleft = TRUE;
- X }
- X if (see_wall(cycle[i-1], char_row, char_col))
- X {
- X find_breakright = TRUE;
- X shortright = TRUE;
- X }
- X else if (see_wall(cycle[i-1], row, col))
- X {
- X find_breakright = TRUE;
- X deepright = TRUE;
- X }
- X if (find_breakleft && find_breakright)
- X {
- X find_openarea = FALSE;
- X if (dir & 1)
- X { /* a hack to allow angled corridor entry */
- X if (deepleft && !deepright)
- X find_prevdir = cycle[i-1];
- X else if (deepright && !deepleft)
- X find_prevdir = cycle[i+1];
- X }
- X /* else if there is a wall two spaces ahead and seem to be in a
- X corridor, then force a turn into the side corridor, must
- X be moving straight into a corridor here */
- X else if (see_wall(cycle[i], row, col))
- X {
- X if (shortleft && !shortright)
- X find_prevdir = cycle[i-2];
- X else if (shortright && !shortleft)
- X find_prevdir = cycle[i+2];
- X }
- X }
- X else
- X find_openarea = TRUE;
- X }
- X }
- X
- X /* We must erase the player symbol '@' here, because sub3_move_light()
- X does not erase the previous location of the player when in find mode
- X and when find_prself is FALSE. The player symbol is not draw at all
- X in this case while moving, so the only problem is on the first turn
- X of find mode, when the initial position of the character must be erased.
- X Hence we must do the erasure here. */
- X if (! light_flag && ! find_prself)
- X print(loc_symbol(char_row, char_col), char_row, char_col);
- X
- X move_char(dir, TRUE);
- X if (find_flag == FALSE)
- X command_count = 0;
- X}
- X
- Xvoid find_run()
- X{
- X /* prevent infinite loops in find mode, will stop after moving 100 times */
- X if (find_flag++ > 100)
- X {
- X msg_print("You stop running to catch your breath.");
- X end_find();
- X }
- X else
- X move_char(find_direction, TRUE);
- X}
- X
- X/* Switch off the run flag - and get the light correct. -CJS- */
- Xvoid end_find()
- X{
- X if (find_flag)
- X {
- X find_flag = FALSE;
- X move_light(char_row, char_col, char_row, char_col);
- X }
- X}
- X
- X/* Do we see a wall? Used in running. -CJS- */
- Xstatic int see_wall(dir, y, x)
- Xint dir, y, x;
- X{
- X char c;
- X
- X if (!mmove(dir, &y, &x)) /* check to see if movement there possible */
- X return TRUE;
- X#ifdef MSDOS
- X else if ((c = loc_symbol(y, x)) == wallsym || c == '%')
- X#else
- X#ifdef ATARI_ST
- X else if ((c = loc_symbol(y, x)) == (unsigned char)240 || c == '%')
- X#else
- X else if ((c = loc_symbol(y, x)) == '#' || c == '%')
- X#endif
- X#endif
- X return TRUE;
- X else
- X return FALSE;
- X}
- X
- X/* Do we see anything? Used in running. -CJS- */
- Xstatic int see_nothing(dir, y, x)
- Xint dir, y, x;
- X{
- X if (!mmove(dir, &y, &x)) /* check to see if movement there possible */
- X return FALSE;
- X else if (loc_symbol(y, x) == ' ')
- X return TRUE;
- X else
- X return FALSE;
- X}
- X
- X
- X/* Determine the next direction for a run, or if we should stop. -CJS- */
- Xvoid area_affect(dir, y, x)
- Xint dir, y, x;
- X{
- X int newdir, t, inv, check_dir, row, col;
- X register int i, max, option, option2;
- X register cave_type *c_ptr;
- X
- X if (py.flags.blind < 1)
- X {
- X option = 0;
- X option2 = 0;
- X dir = find_prevdir;
- X max = (dir & 1) + 1;
- X /* Look at every newly adjacent square. */
- X for(i = -max; i <= max; i++)
- X {
- X newdir = cycle[chome[dir]+i];
- X row = y;
- X col = x;
- X if (mmove(newdir, &row, &col))
- X {
- X /* Objects player can see (Including doors?) cause a stop. */
- X c_ptr = &cave[row][col];
- X if (player_light || c_ptr->tl || c_ptr->pl || c_ptr->fm)
- X {
- X if (c_ptr->tptr != 0)
- X {
- X t = t_list[c_ptr->tptr].tval;
- X if (t != TV_INVIS_TRAP && t != TV_SECRET_DOOR
- X && (t != TV_OPEN_DOOR || !find_ignore_doors))
- X {
- X end_find();
- X return;
- X }
- X }
- X /* Also Creatures */
- X /* the monster should be visible since update_mon() checks
- X for the special case of being in find mode */
- X if (c_ptr->cptr > 1 && m_list[c_ptr->cptr].ml)
- X {
- X end_find();
- X return;
- X }
- X inv = FALSE;
- X }
- X else
- X inv = TRUE; /* Square unseen. Treat as open. */
- X
- X if (c_ptr->fval <= MAX_OPEN_SPACE || inv)
- X {
- X if (find_openarea)
- X {
- X /* Have we found a break? */
- X if (i < 0)
- X {
- X if (find_breakright)
- X {
- X end_find();
- X return;
- X }
- X }
- X else if (i > 0)
- X {
- X if (find_breakleft)
- X {
- X end_find();
- X return;
- X }
- X }
- X }
- X else if (option == 0)
- X option = newdir; /* The first new direction. */
- X else if (option2 != 0)
- X {
- X end_find(); /* Three new directions. STOP. */
- X return;
- X }
- X else if (option != cycle[chome[dir]+i-1])
- X {
- X end_find(); /* If not adjacent to prev, STOP */
- X return;
- X }
- X else
- X {
- X /* Two adjacent choices. Make option2 the diagonal,
- X and remember the other diagonal adjacent to the first
- X option. */
- X if ((newdir & 1) == 1)
- X {
- X check_dir = cycle[chome[dir]+i-2];
- X option2 = newdir;
- X }
- X else
- X {
- X check_dir = cycle[chome[dir]+i+1];
- X option2 = option;
- X option = newdir;
- X }
- X }
- X }
- X else if (find_openarea)
- X {
- X /* We see an obstacle. In open area, STOP if on a side
- X previously open. */
- X if (i < 0)
- X {
- X if (find_breakleft)
- X {
- X end_find();
- X return;
- X }
- X find_breakright = TRUE;
- X }
- X else if (i > 0)
- X {
- X if (find_breakright)
- X {
- X end_find();
- X return;
- X }
- X find_breakleft = TRUE;
- X }
- X }
- X }
- X }
- X
- X if (find_openarea == FALSE)
- X { /* choose a direction. */
- X if (option2 == 0 || (find_examine && !find_cut))
- X {
- X /* There is only one option, or if two, then we always examine
- X potential corners and never cur known corners, so you step
- X into the straight option. */
- X if (option != 0)
- X find_direction = option;
- X if (option2 == 0)
- X find_prevdir = option;
- X else
- X find_prevdir = option2;
- X }
- X else
- X {
- X /* Two options! */
- X row = y;
- X col = x;
- X (void) mmove(option, &row, &col);
- X if (!see_wall(option, row, col)
- X || !see_wall(check_dir, row, col))
- X {
- X /* Don't see that it is closed off. This could be a
- X potential corner or an intersection. */
- X if (find_examine && see_nothing(option, row, col)
- X && see_nothing(option2, row, col))
- X /* Can not see anything ahead and in the direction we are
- X turning, assume that it is a potential corner. */
- X {
- X find_direction = option;
- X find_prevdir = option2;
- X }
- X else
- X /* STOP: we are next to an intersection or a room */
- X end_find();
- X }
- X else if (find_cut)
- X {
- X /* This corner is seen to be enclosed; we cut the corner. */
- X find_direction = option2;
- X find_prevdir = option2;
- X }
- X else
- X {
- X /* This corner is seen to be enclosed, and we deliberately
- X go the long way. */
- X find_direction = option;
- X find_prevdir = option2;
- X }
- X }
- X }
- X }
- X}
- X
- X
- X/* AC gets worse -RAK- */
- X/* Note: This routine affects magical AC bonuses so that stores */
- X/* can detect the damage. */
- Xint minus_ac(typ_dam)
- Xint32u typ_dam;
- X{
- X register int i, j;
- X int tmp[6], minus;
- X register inven_type *i_ptr;
- X bigvtype out_val, tmp_str;
- X
- X i = 0;
- X if (inventory[INVEN_BODY].tval != TV_NOTHING)
- X {
- X tmp[i] = INVEN_BODY;
- X i++;
- X }
- X if (inventory[INVEN_ARM].tval != TV_NOTHING)
- X {
- X tmp[i] = INVEN_ARM;
- X i++;
- X }
- X if (inventory[INVEN_OUTER].tval != TV_NOTHING)
- X {
- X tmp[i] = INVEN_OUTER;
- X i++;
- X }
- X if (inventory[INVEN_HANDS].tval != TV_NOTHING)
- X {
- X tmp[i] = INVEN_HANDS;
- X i++;
- X }
- X if (inventory[INVEN_HEAD].tval != TV_NOTHING)
- X {
- X tmp[i] = INVEN_HEAD;
- X i++;
- X }
- X /* also affect boots */
- X if (inventory[INVEN_FEET].tval != TV_NOTHING)
- X {
- X tmp[i] = INVEN_FEET;
- X i++;
- X }
- X minus = FALSE;
- X if (i > 0)
- X {
- X j = tmp[randint(i) - 1];
- X i_ptr = &inventory[j];
- X if (i_ptr->flags & typ_dam)
- X {
- X objdes(tmp_str, &inventory[j], FALSE);
- X (void) sprintf(out_val, "Your %s resists damage!", tmp_str);
- X msg_print(out_val);
- X minus = TRUE;
- X }
- X else if ((i_ptr->ac+i_ptr->toac) > 0)
- X {
- X objdes(tmp_str, &inventory[j], FALSE);
- X (void) sprintf(out_val, "Your %s is damaged!", tmp_str);
- X msg_print(out_val);
- X i_ptr->toac--;
- X calc_bonuses();
- X minus = TRUE;
- X }
- X }
- X return(minus);
- X}
- X
- X
- X/* Corrode the unsuspecting person's armor -RAK- */
- Xvoid corrode_gas(kb_str)
- Xchar *kb_str;
- X{
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X#ifdef ATARIST_MWC
- X if (!minus_ac((int32u) (holder = TR_RES_ACID)))
- X#else
- X if (!minus_ac((int32u) TR_RES_ACID))
- X#endif
- X take_hit(randint(8), kb_str);
- X if (inven_damage(set_corrodes, 5) > 0)
- X msg_print("There is an acrid smell coming from your pack.");
- X}
- X
- X
- X/* Poison gas the idiot. -RAK- */
- Xvoid poison_gas(dam, kb_str)
- Xint dam;
- Xchar *kb_str;
- X{
- X take_hit(dam, kb_str);
- X py.flags.poisoned += 12 + randint(dam);
- X}
- X
- X
- X/* Burn the fool up. -RAK- */
- Xvoid fire_dam(dam, kb_str)
- Xint dam;
- Xchar *kb_str;
- X{
- X if (py.flags.fire_resist)
- X dam = dam / 3;
- X if (py.flags.resist_heat > 0)
- X dam = dam / 3;
- X take_hit(dam, kb_str);
- X if (inven_damage(set_flammable, 3) > 0)
- X msg_print("There is smoke coming from your pack!");
- X}
- X
- X
- X/* Freeze him to death. -RAK- */
- Xvoid cold_dam(dam, kb_str)
- Xint dam;
- Xchar *kb_str;
- X{
- X if (py.flags.cold_resist)
- X dam = dam / 3;
- X if (py.flags.resist_cold > 0)
- X dam = dam / 3;
- X take_hit(dam, kb_str);
- X if (inven_damage(set_frost_destroy, 5) > 0)
- X msg_print("Something shatters inside your pack!");
- X}
- X
- X
- X/* Lightning bolt the sucker away. -RAK- */
- Xvoid light_dam(dam, kb_str)
- Xint dam;
- Xchar *kb_str;
- X{
- X if (py.flags.lght_resist)
- X take_hit((dam / 3), kb_str);
- X else
- X take_hit(dam, kb_str);
- X if (inven_damage(set_lightning_destroy, 3) > 0)
- X msg_print("There are sparks coming from your pack!");
- X}
- X
- X
- X/* Throw acid on the hapless victim -RAK- */
- Xvoid acid_dam(dam, kb_str)
- Xint dam;
- Xchar *kb_str;
- X{
- X register int flag;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X flag = 0;
- X#ifdef ATARIST_MWC
- X if (minus_ac((int32u) (holder = TR_RES_ACID)))
- X#else
- X if (minus_ac((int32u) TR_RES_ACID))
- X#endif
- X flag = 1;
- X if (py.flags.acid_resist)
- X flag += 2;
- X take_hit (dam / (flag + 1), kb_str);
- X if (inven_damage(set_acid_affect, 3) > 0)
- X msg_print("There is an acrid smell coming from your pack!");
- X}
- END_OF_FILE
- if test 19056 -ne `wc -c <'source/moria2.c'`; then
- echo shar: \"'source/moria2.c'\" unpacked with wrong size!
- fi
- # end of 'source/moria2.c'
- fi
- if test -f 'unix/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unix/Makefile'\"
- else
- echo shar: Extracting \"'unix/Makefile'\" \(4363 characters\)
- sed "s/^X//" >'unix/Makefile' <<'END_OF_FILE'
- X# BINDIR is the directory where the moria binary while be put
- X# LIBDIR is where the other files (score, news, hours) will be put
- X# LIBDIR must be the same directory defined in config.h
- X# OWNER is who you want the game to be chown to.
- X# GROUP is who you wnat the game to be chgrp to.
- XBINDIR = /usr/public
- XLIBDIR = /usr/public/morialib
- XOWNER = wilson
- XGROUP = wilson
- X
- X# For testing and debugging the program, it is best to use this line.
- X# CFLAGS = -g
- X# For playing the game, you may want to use this line
- XCFLAGS = -O
- X
- X# For BSD Systems
- XCURSES = -lcurses -ltermcap
- X# For SYS V Systems
- X# CURSES = -lcurses
- X# For XENIX, some XENIX systems may need -ltinfo
- X# CURSES = -ltcap -ltermcap -lx
- X
- X# For AIX systems, compiling in the BSD world; SYS_V must not be defined in
- X# config.h if you use this.
- X#LFLAGS = -lbsd
- X# Normal systems don't require anything here.
- XLFLAGS =
- X
- XCC = cc
- X
- XSRCS = main.c misc1.c misc2.c misc3.c misc4.c store1.c files.c io.c \
- X create.c desc.c generate.c sets.c dungeon.c creature.c death.c \
- X eat.c help.c magic.c potions.c prayer.c save.c staffs.c wands.c \
- X scrolls.c spells.c wizard.c store2.c signals.c moria1.c moria2.c \
- X moria3.c moria4.c monsters.c treasure.c variable.c rnd.c recall.c \
- X unix.c player.c tables.c
- X
- XOBJS = main.o misc1.o misc2.o misc3.o misc4.o store1.o files.o io.o \
- X create.o desc.o generate.o sets.o dungeon.o creature.o death.o \
- X eat.o help.o magic.o potions.o prayer.o save.o staffs.o wands.o \
- X scrolls.o spells.o wizard.o store2.o signals.o moria1.o moria2.o \
- X moria3.o moria4.o monsters.o treasure.o variable.o rnd.o recall.o \
- X unix.o player.o tables.o
- X
- XLIBFILES = hours news origcmds.hlp owizcmds.hlp roglcmds.hlp rwizcmds.hlp \
- X version.hlp welcome.hlp
- X
- Xmoria : $(OBJS)
- X $(CC) -o moria $(CFLAGS) $(OBJS) $(CURSES) $(LFLAGS)
- X
- Xlintout : $(SRCS)
- X lint $(SRCS) $(CURSES) > lintout
- X
- Xlintout2 : $(SRCS)
- X lint -bach $(SRCS) $(CURSES) > lintout
- X
- XTAGS : $(SRCS)
- X ctags -x $(SRCS) > TAGS
- X
- X# you must define BINDIR and LIBDIR before installing
- X# assumes that BINDIR and LIBDIR exist
- Xinstall:
- X chmod 755 $(BINDIR)
- X cp moria $(BINDIR)
- X chmod 4711 $(BINDIR)/moria
- X chmod 711 $(LIBDIR)
- X (cd files; cp $(LIBFILES) $(LIBDIR))
- X (cd $(LIBDIR); chmod 444 $(LIBFILES))
- X (cd $(LIBDIR); touch scores; chmod 644 scores)
- X chown $(OWNER) $(BINDIR)/moria
- X chgrp $(GROUP) $(BINDIR)/moria
- X (cd $(LIBDIR); chown $(OWNER) $(LIBFILES) scores)
- X (cd $(LIBDIR); chgrp $(GROUP) $(LIBFILES) scores)
- X# If you are short on disk space, or aren't interested in debugging moria.
- X# strip $(BINDIR)/moria
- X
- Xclean:
- X rm -r *.o
- X rm -i moria
- X
- Xcreate.o: constant.h types.h externs.h config.h
- Xcreature.o: constant.h types.h externs.h config.h
- Xdeath.o: constant.h types.h externs.h config.h
- Xdesc.o: constant.h types.h externs.h config.h
- Xdungeon.o: constant.h types.h externs.h config.h
- Xeat.o: constant.h types.h externs.h config.h
- Xfiles.o: constant.h types.h externs.h config.h
- Xgenerate.o: constant.h types.h externs.h config.h
- Xhelp.o: constant.h types.h externs.h config.h
- Xio.o: constant.h types.h externs.h config.h
- Xmagic.o: constant.h types.h externs.h config.h
- Xmain.o: constant.h types.h externs.h config.h
- Xmisc1.o: constant.h types.h externs.h config.h
- Xmisc2.o: constant.h types.h externs.h config.h
- Xmisc3.o: constant.h types.h externs.h config.h
- Xmisc4.o: constant.h types.h externs.h config.h
- Xmonsters.o: constant.h types.h config.h
- Xmoria1.o: constant.h types.h externs.h config.h
- Xmoria2.o: constant.h types.h externs.h config.h
- Xmoria3.o: constant.h types.h externs.h config.h
- Xmoria4.o: constant.h types.h externs.h config.h
- Xplayer.o: constant.h types.h config.h
- Xpotions.o: constant.h types.h externs.h config.h
- Xprayer.o: constant.h types.h externs.h config.h
- Xrecall.o: constant.h config.h types.h externs.h
- Xrnd.o: constant.h types.h
- Xsave.o: constant.h types.h externs.h config.h
- Xscrolls.o: constant.h types.h externs.h config.h
- Xsets.o: constant.h config.h
- Xsignals.o: constant.h types.h externs.h config.h
- Xspells.o: constant.h types.h externs.h config.h
- Xstaffs.o: constant.h types.h externs.h config.h
- Xstore1.o: constant.h types.h externs.h config.h
- Xstore2.o: constant.h types.h externs.h config.h
- Xtables.o: constant.h types.h config.h
- Xtreasure.o: constant.h types.h config.h
- Xunix.o: constant.h config.h types.h externs.h
- Xvariable.o: constant.h types.h config.h
- Xwands.o: constant.h types.h externs.h config.h
- Xwizard.o: constant.h types.h externs.h config.h
- END_OF_FILE
- if test 4363 -ne `wc -c <'unix/Makefile'`; then
- echo shar: \"'unix/Makefile'\" unpacked with wrong size!
- fi
- # end of 'unix/Makefile'
- fi
- echo shar: End of archive 21 \(of 39\).
- cp /dev/null ark21isdone
- 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 32 33 34 35 36 37 38 39 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 39 archives.
- echo "Now run "bldfiles.sh" to build split files"
- 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
-