home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v09i058: umoria3 - single player dungeon simulation (ver. 5.2), Part04/31
- Message-ID: <5589@tekred.CNA.TEK.COM>
- Date: 16 May 90 19:11:09 GMT
- Sender: news@tekred.CNA.TEK.COM
- Lines: 2342
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
- Posting-number: Volume 9, Issue 58
- Archive-name: umoria3/Part04
- 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 <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 31)."
- # Contents: source/moria2.c
- # Wrapped by billr@saab on Wed May 16 11:58:18 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- 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'\" \(59994 characters\)
- sed "s/^X//" >'source/moria2.c' <<'END_OF_FILE'
- X/* moria2.c: misc code, mainly to handle player commands
- 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 <ctype.h>
- X
- X#include "constant.h"
- X#include "config.h"
- X#include "types.h"
- X#include "externs.h"
- X
- X#ifdef USG
- X#ifndef ATARIST_MWC
- X#include <string.h>
- X#endif
- X#else
- X#include <strings.h>
- X#endif
- X
- X
- X#if defined(LINT_ARGS)
- Xstatic int look_ray(int, int, int);
- Xstatic int look_see(int, int, int *);
- Xstatic void hit_trap(int, int);
- Xstatic void carry(int, int, int);
- Xstatic int summon_object(int, int, int, int);
- Xstatic void py_attack(int, int);
- Xstatic void chest_trap(int, int);
- Xstatic void inven_throw(int, struct inven_type *);
- Xstatic void facts(struct inven_type *, int *, int *, int *, int *);
- Xstatic void drop_throw(int, int, struct inven_type *);
- Xstatic void py_bash(int, int);
- X#else
- Xstatic int look_ray();
- Xstatic int look_see();
- X#endif
- X
- X/* Player hit a trap. (Chuckle) -RAK- */
- Xstatic void hit_trap(y, x)
- Xint y, x;
- X{
- X int i, ty, tx, num, dam;
- X register cave_type *c_ptr;
- X register struct misc *p_ptr;
- X register inven_type *t_ptr;
- X bigvtype tmp;
- X
- X end_find();
- X change_trap(y, x);
- X c_ptr = &cave[y][x];
- X p_ptr = &py.misc;
- X t_ptr = &t_list[c_ptr->tptr];
- X dam = pdamroll(t_ptr->damage);
- X switch(t_ptr->subval)
- X {
- X case 1: /* Open pit*/
- X msg_print("You fell into a pit!");
- X if (py.flags.ffall)
- X msg_print("You gently float down.");
- X else
- X {
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X }
- X break;
- X case 2: /* Arrow trap*/
- X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
- X {
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X msg_print("An arrow hits you.");
- X }
- X else
- X msg_print("An arrow barely misses you.");
- X break;
- X case 3: /* Covered pit*/
- X msg_print("You fell into a covered pit.");
- X if (py.flags.ffall)
- X msg_print("You gently float down.");
- X else
- X {
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X }
- X place_trap(y, x, 0);
- X break;
- X case 4: /* Trap door*/
- X msg_print("You fell through a trap door!");
- X new_level_flag = TRUE;
- X dun_level++;
- X if (py.flags.ffall)
- X msg_print("You gently float down.");
- X else
- X {
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X }
- X break;
- X case 5: /* Sleep gas*/
- X if (py.flags.paralysis == 0)
- X {
- X msg_print("A strange white mist surrounds you!");
- X if (py.flags.free_act)
- X msg_print("You are unaffected.");
- X else
- X {
- X msg_print("You fall asleep.");
- X py.flags.paralysis += randint(10) + 4;
- X }
- X }
- X break;
- X case 6: /* Hid Obj*/
- X (void) delete_object(y, x);
- X place_object(y, x);
- X msg_print("Hmmm, there was something under this rock.");
- X break;
- X case 7: /* STR Dart*/
- X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
- X {
- X if (!py.flags.sustain_str)
- X {
- X (void) dec_stat(A_STR);
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X msg_print("A small dart weakens you!");
- X }
- X else
- X msg_print("A small dart hits you.");
- X }
- X else
- X msg_print("A small dart barely misses you.");
- X break;
- X case 8: /* Teleport*/
- X teleport_flag = TRUE;
- X msg_print("You hit a teleport trap!");
- X break;
- X case 9: /* Rockfall*/
- X take_hit(dam, "a falling rock");
- X (void) delete_object(y, x);
- X place_rubble(y, x);
- X msg_print("You are hit by falling rock.");
- X break;
- X case 10: /* Corrode gas*/
- X corrode_gas("corrosion gas");
- X msg_print("A strange red gas surrounds you.");
- X break;
- X case 11: /* Summon mon*/
- X (void) delete_object(y, x); /* Rune disappears. */
- X num = 2 + randint (3);
- X for (i = 0; i < num; i++)
- X {
- X ty = y;
- X tx = x;
- X (void) summon_monster(&ty, &tx, FALSE);
- X }
- X break;
- X case 12: /* Fire trap*/
- X fire_dam(dam, "a fire trap");
- X msg_print("You are enveloped in flames!");
- X break;
- X case 13: /* Acid trap*/
- X acid_dam(dam, "an acid trap");
- X msg_print("You are splashed with acid!");
- X break;
- X case 14: /* Poison gas*/
- X poison_gas(dam, "a poison gas trap");
- X msg_print("A pungent green gas surrounds you!");
- X break;
- X case 15: /* Blind Gas */
- X msg_print("A black gas surrounds you!");
- X py.flags.blind += randint(50) + 50;
- X break;
- X case 16: /* Confuse Gas*/
- X msg_print("A gas of scintillating colors surrounds you!");
- X py.flags.confused += randint(15) + 15;
- X break;
- X case 17: /* Slow Dart*/
- X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
- X {
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X msg_print("A small dart hits you!");
- X if (py.flags.free_act)
- X msg_print("You are unaffected.");
- X else
- X py.flags.slow += randint(20) + 10;
- X }
- X else
- X msg_print("A small dart barely misses you.");
- X break;
- X case 18: /* CON Dart*/
- X if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
- X {
- X if (!py.flags.sustain_con)
- X {
- X (void) dec_stat(A_CON);
- X objdes(tmp, t_ptr, TRUE);
- X take_hit(dam, tmp);
- X msg_print("A small dart saps your health!");
- X }
- X else
- X msg_print("A small dart hits you.");
- X }
- X else
- X msg_print("A small dart barely misses you.");
- X break;
- X case 19: /*Secret Door*/
- X break;
- X case 99: /* Scare Mon*/
- X break;
- X
- X /* Town level traps are special, the stores. */
- X case 101: /* General */
- X enter_store(0);
- X break;
- X case 102: /* Armory */
- X enter_store(1);
- X break;
- X case 103: /* Weaponsmith*/
- X enter_store(2);
- X break;
- X case 104: /* Temple */
- X enter_store(3);
- X break;
- X case 105: /* Alchemy */
- X enter_store(4);
- X break;
- X case 106: /* Magic-User */
- X enter_store(5);
- X break;
- X
- X default:
- X msg_print("Unknown trap value.");
- X break;
- X }
- X}
- X
- X
- X/* Return spell number and failure chance -RAK- */
- X/* returns -1 if no spells in book
- X returns 1 if choose a spell in book to cast
- X returns 0 if don't choose a spell, i.e. exit with an escape */
- Xint cast_spell(prompt, item_val, sn, sc)
- Xchar *prompt;
- Xint item_val;
- Xint *sn, *sc;
- X{
- X int32u j;
- X register int i, k;
- X int spell[31], result, first_spell;
- X register spell_type *s_ptr;
- X
- X result = -1;
- X i = 0;
- X j = inventory[item_val].flags;
- X first_spell = bit_pos(&j);
- X /* set j again, since bit_pos modified it */
- X j = inventory[item_val].flags & spell_learned;
- X s_ptr = magic_spell[py.misc.pclass-1];
- X while (j)
- X {
- X k = bit_pos(&j);
- X if (s_ptr[k].slevel <= py.misc.lev)
- X {
- X spell[i] = k;
- X i++;
- X }
- X }
- X if (i > 0)
- X {
- X result = get_spell(spell, i, sn, sc, prompt, first_spell);
- X if (result && magic_spell[py.misc.pclass-1][*sn].smana > py.misc.cmana)
- X {
- X if (py.misc.pclass)
- X result = get_check("You summon your limited strength to cast this one! Confirm?");
- X else
- X result = get_check("The gods may think you presumptuous for this! Confirm?");
- X }
- X }
- X return(result);
- X}
- X
- X
- X/* Player is on an object. Many things can happen based -RAK- */
- X/* on the TVAL of the object. Traps are set off, money and most */
- X/* objects are picked up. Some objects, such as open doors, just*/
- X/* sit there. */
- Xstatic void carry(y, x, pickup)
- Xint y, x;
- Xint pickup;
- X{
- X register int locn, i;
- X bigvtype out_val, tmp_str;
- X register cave_type *c_ptr;
- X register inven_type *i_ptr;
- X
- X c_ptr = &cave[y][x];
- X i_ptr = &t_list[c_ptr->tptr];
- X i = t_list[c_ptr->tptr].tval;
- X if (i <= TV_MAX_PICK_UP)
- X {
- X end_find();
- X /* There's GOLD in them thar hills! */
- X if (i == TV_GOLD)
- X {
- X py.misc.au += i_ptr->cost;
- X objdes(tmp_str, i_ptr, TRUE);
- X (void) sprintf(out_val,
- X "You have found %ld gold pieces worth of %s",
- X i_ptr->cost, tmp_str);
- X prt_gold();
- X (void) delete_object(y, x);
- X msg_print(out_val);
- X }
- X else
- X {
- X if (inven_check_num(i_ptr)) /* Too many objects? */
- X { /* Okay, pick it up */
- X if (pickup && prompt_carry_flag)
- X {
- X objdes(tmp_str, i_ptr, TRUE);
- X /* change the period to a question mark */
- X tmp_str[strlen(tmp_str)-1] = '?';
- X (void) sprintf(out_val, "Pick up %s", tmp_str);
- X pickup = get_check(out_val);
- X }
- X /* Check to see if it will change the players speed. */
- X if (pickup && !inven_check_weight(i_ptr))
- X {
- X objdes(tmp_str, i_ptr, TRUE);
- X /* change the period to a question mark */
- X tmp_str[strlen(tmp_str)-1] = '?';
- X (void) sprintf(out_val,
- X "Exceed your weight limit to pick up %s",
- X tmp_str);
- X pickup = get_check(out_val);
- X }
- X /* Attempt to pick up an object. */
- X if (pickup)
- X {
- X locn = inven_carry(i_ptr);
- X objdes(tmp_str, &inventory[locn], TRUE);
- X (void) sprintf(out_val, "You have %s (%c)",tmp_str,locn+'a');
- X msg_print(out_val);
- X (void) delete_object(y, x);
- X }
- X }
- X else
- X {
- X objdes(tmp_str, i_ptr, TRUE);
- X (void) sprintf(out_val, "You can't carry %s", tmp_str);
- X msg_print(out_val);
- X }
- X }
- X }
- X /* OPPS! */
- X else if (i == TV_INVIS_TRAP || i == TV_VIS_TRAP || i == TV_STORE_DOOR)
- X hit_trap(y, x);
- X}
- X
- X
- X/* Deletes a monster entry from the level -RAK- */
- Xvoid delete_monster(j)
- Xint j;
- X{
- X register monster_type *m_ptr;
- X
- X m_ptr = &m_list[j];
- X cave[m_ptr->fy][m_ptr->fx].cptr = 0;
- X if (m_ptr->ml)
- X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
- X if (j != mfptr - 1)
- X {
- X m_ptr = &m_list[mfptr - 1];
- X cave[m_ptr->fy][m_ptr->fx].cptr = j;
- X m_list[j] = m_list[mfptr - 1];
- X }
- X mfptr--;
- X m_list[mfptr] = blank_monster;
- X if (mon_tot_mult > 0)
- X mon_tot_mult--;
- X}
- X
- X/* The following two procedures implement the same function as delete monster.
- X However, they are used within creatures(), because deleting a monster
- X while scanning the m_list causes two problems, monsters might get two
- X turns, and m_ptr/monptr might be invalid after the delete_monster.
- X Hence the delete is done in two steps. */
- X/* fix1_delete_monster does everything delete_monster does except delete
- X the monster record and reduce mfptr, this is called in breathe, and
- X a couple of places in creatures.c */
- Xvoid fix1_delete_monster(j)
- Xint j;
- X{
- X register monster_type *m_ptr;
- X
- X m_ptr = &m_list[j];
- X /* force the hp negative to ensure that the monster is dead, for example,
- X if the monster was just eaten by another, it will still have positive
- X hit points */
- X m_ptr->hp = -1;
- X cave[m_ptr->fy][m_ptr->fx].cptr = 0;
- X if (m_ptr->ml)
- X lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
- X if (mon_tot_mult > 0)
- X mon_tot_mult--;
- X}
- X
- X/* fix2_delete_monster does everything in delete_monster that wasn't done
- X by fix1_monster_delete above, this is only called in creatures() */
- Xvoid fix2_delete_monster(j)
- Xint j;
- X{
- X register monster_type *m_ptr;
- X
- X if (j != mfptr - 1)
- X {
- X m_ptr = &m_list[mfptr - 1];
- X cave[m_ptr->fy][m_ptr->fx].cptr = j;
- X m_list[j] = m_list[mfptr - 1];
- X }
- X m_list[mfptr - 1] = blank_monster;
- X mfptr--;
- X}
- X
- X
- X/* Creates objects nearby the coordinates given -RAK- */
- Xstatic int summon_object(y, x, num, typ)
- Xint y, x, num, typ;
- X{
- X register int i, j, k;
- X register cave_type *c_ptr;
- X int real_typ, res;
- X
- X if (typ == 1)
- X real_typ = 1; /* typ == 1 -> objects */
- X else
- X real_typ = 256; /* typ == 2 -> gold */
- X res = 0;
- X do
- X {
- X i = 0;
- X do
- X {
- X j = y - 3 + randint(5);
- X k = x - 3 + randint(5);
- X if (in_bounds(j, k) && los(y, x, j, k))
- X {
- X c_ptr = &cave[j][k];
- X if (c_ptr->fval <= MAX_OPEN_SPACE && (c_ptr->tptr == 0))
- X {
- X if (typ == 3) /* typ == 3 -> 50% objects, 50% gold */
- X {
- X if (randint(100) < 50)
- X real_typ = 1;
- X else
- X real_typ = 256;
- X }
- X if (real_typ == 1)
- X place_object(j, k);
- X else
- X place_gold(j, k);
- X lite_spot(j, k);
- X if (test_light(j, k))
- X res += real_typ;
- X i = 20;
- X }
- X }
- X i++;
- X }
- X while (i <= 20);
- X num--;
- X }
- X while (num != 0);
- X return res;
- X}
- X
- X
- X/* Deletes object from given location -RAK- */
- Xint delete_object(y, x)
- Xint y, x;
- X{
- X register int delete;
- X register cave_type *c_ptr;
- X
- X c_ptr = &cave[y][x];
- X if (c_ptr->fval == BLOCKED_FLOOR)
- X c_ptr->fval = CORR_FLOOR;
- X pusht(c_ptr->tptr);
- X c_ptr->tptr = 0;
- X c_ptr->fm = FALSE;
- X lite_spot(y, x);
- X if (test_light(y, x))
- X delete = TRUE;
- X else
- X delete = FALSE;
- X return(delete);
- X}
- X
- X
- X/* Allocates objects upon a creatures death -RAK- */
- X/* Oh well, another creature bites the dust. Reward the victor*/
- X/* based on flags set in the main creature record */
- X/* Returns a mask of bits from the given flags which indicates what the
- X monster is seen to have dropped. This may be added to monster memory. */
- Xint32u monster_death(y, x, flags)
- Xint y, x;
- Xregister int32u flags;
- X{
- X register int i, number;
- X int32u dump, res;
- X#if defined(ATARIST_MWC)
- X int32u holder; /* avoid a compiler bug */
- X#endif
- X
- X#if !defined(ATARIST_MWC)
- X if (flags & CM_CARRY_OBJ)
- X i = 1;
- X else
- X i = 0;
- X if (flags & CM_CARRY_GOLD)
- X i += 2;
- X
- X number = 0;
- X if ((flags & CM_60_RANDOM) && (randint(100) < 60))
- X number++;
- X if ((flags & CM_90_RANDOM) && (randint(100) < 90))
- X number++;
- X if (flags & CM_1D2_OBJ)
- X number += randint(2);
- X if (flags & CM_2D2_OBJ)
- X number += damroll(2, 2);
- X if (flags & CM_4D2_OBJ)
- X number += damroll(4, 2);
- X if (number > 0)
- X dump = summon_object(y, x, number, i);
- X else
- X dump = 0;
- X#else
- X holder = CM_CARRY_OBJ;
- X if (flags & holder)
- X i = 1;
- X else
- X i = 0;
- X holder = CM_CARRY_GOLD;
- X if (flags & holder)
- X i += 2;
- X
- X number = 0;
- X holder = CM_60_RANDOM;
- X if ((flags & holder) && (randint(100) < 60))
- X number++;
- X holder = CM_90_RANDOM;
- X if ((flags & holder) && (randint(100) < 90))
- X number++;
- X holder = CM_1D2_OBJ;
- X if (flags & holder)
- X number += randint(2);
- X holder = CM_2D2_OBJ;
- X if (flags & holder)
- X number += damroll(2, 2);
- X holder = CM_4D2_OBJ;
- X if (flags & holder)
- X number += damroll(4, 2);
- X if (number > 0)
- X dump = summon_object(y, x, number, i);
- X else
- X dump = 0;
- X
- X
- X#endif
- X
- X#if defined(ATARIST_MWC)
- X holder = CM_WIN;
- X if (flags & holder)
- X#else
- X if (flags & CM_WIN)
- X#endif
- X {
- X total_winner = TRUE;
- X prt_winner();
- X msg_print("*** CONGRATULATIONS *** You have won the game.");
- X msg_print("You cannot save this game, but you may retire when ready.");
- X }
- X
- X if (dump)
- X {
- X res = 0;
- X if (dump & 255)
- X#ifdef ATARIST_MWC
- X {
- X holder = CM_CARRY_OBJ;
- X res |= holder;
- X }
- X#else
- X res |= CM_CARRY_OBJ;
- X#endif
- X if (dump >= 256)
- X#ifdef ATARIST_MWC
- X {
- X holder = CM_CARRY_GOLD;
- X res |= holder;
- X }
- X#else
- X res |= CM_CARRY_GOLD;
- X#endif
- X dump = (dump % 256) + (dump / 256); /* number of items */
- X res |= dump << CM_TR_SHIFT;
- X }
- X else
- X res = 0;
- X
- X return res;
- X}
- X
- X
- X/* Decreases monsters hit points and deletes monster if needed. */
- X/* (Picking on my babies.) -RAK- */
- Xint mon_take_hit(monptr, dam)
- Xint monptr, dam;
- X{
- X register int32u i;
- X int32 new_exp, new_exp_frac;
- X register monster_type *m_ptr;
- X register struct misc *p_ptr;
- X register creature_type *c_ptr;
- X int m_take_hit;
- X int32u tmp;
- X#ifdef ATARIST_MWC
- X int32u holder;
- X#endif
- X
- X m_ptr = &m_list[monptr];
- X m_ptr->hp -= dam;
- X m_ptr->csleep = 0;
- X if (m_ptr->hp < 0)
- X {
- X i = monster_death((int)m_ptr->fy, (int)m_ptr->fx,
- X c_list[m_ptr->mptr].cmove);
- X if ((py.flags.blind < 1 && m_ptr->ml)
- X || (c_list[m_ptr->mptr].cmove & CM_WIN))
- X {
- X#ifdef ATARIST_MWC
- X holder = CM_TREASURE;
- X tmp = (c_recall[m_ptr->mptr].r_cmove & holder) >> CM_TR_SHIFT;
- X if (tmp > ((i & holder) >> CM_TR_SHIFT))
- X i = (i & ~holder) | (tmp << CM_TR_SHIFT);
- X c_recall[m_ptr->mptr].r_cmove =
- X (c_recall[m_ptr->mptr].r_cmove & ~holder) | i;
- X#else
- X tmp = (c_recall[m_ptr->mptr].r_cmove & CM_TREASURE) >> CM_TR_SHIFT;
- X if (tmp > ((i & CM_TREASURE) >> CM_TR_SHIFT))
- X i = (i & ~CM_TREASURE) | (tmp << CM_TR_SHIFT);
- X c_recall[m_ptr->mptr].r_cmove =
- X (c_recall[m_ptr->mptr].r_cmove & ~CM_TREASURE) | i;
- X#endif
- X if (c_recall[m_ptr->mptr].r_kills < MAX_SHORT)
- X c_recall[m_ptr->mptr].r_kills++;
- X }
- X c_ptr = &c_list[m_ptr->mptr];
- X p_ptr = &py.misc;
- X
- X new_exp = ((long)c_ptr->mexp * c_ptr->level) / p_ptr->lev;
- X new_exp_frac = ((((long)c_ptr->mexp * c_ptr->level) % p_ptr->lev)
- X * 0x10000L / p_ptr->lev) + p_ptr->exp_frac;
- X if (new_exp_frac >= 0x10000L)
- X {
- X new_exp++;
- X p_ptr->exp_frac = new_exp_frac - 0x10000L;
- X }
- X else
- X p_ptr->exp_frac = new_exp_frac;
- X
- X p_ptr->exp += new_exp;
- X /* can't call prt_experience() here, as that would result in "new level"
- X message appearing before "monster dies" message */
- X m_take_hit = m_ptr->mptr;
- X /* in case this is called from within creatures(), this is a
- X horrible hack, the m_list/creatures() code needs to be
- X rewritten */
- X if (hack_monptr < monptr)
- X delete_monster(monptr);
- X else
- X fix1_delete_monster(monptr);
- X }
- X else
- X m_take_hit = -1;
- X return(m_take_hit);
- X}
- X
- X
- X/* Player attacks a (poor, defenseless) creature -RAK- */
- Xstatic void py_attack(y, x)
- Xint y, x;
- X{
- X register int k, blows;
- X int crptr, monptr, tot_tohit, base_tohit;
- X vtype m_name, out_val;
- X register inven_type *i_ptr;
- X register struct misc *p_ptr;
- X
- X crptr = cave[y][x].cptr;
- X monptr = m_list[crptr].mptr;
- X m_list[crptr].csleep = 0;
- X i_ptr = &inventory[INVEN_WIELD];
- X /* Does the player know what he's fighting? */
- X if (!m_list[crptr].ml)
- X (void) strcpy(m_name, "it");
- X else
- X (void) sprintf(m_name, "the %s", c_list[monptr].name);
- X if (i_ptr->tval != TV_NOTHING) /* Proper weapon */
- X blows = attack_blows((int)i_ptr->weight, &tot_tohit);
- X else /* Bare hands? */
- X {
- X blows = 2;
- X tot_tohit = -3;
- X }
- X if ((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW))
- X /* Fix for arrows */
- X blows = 1;
- X p_ptr = &py.misc;
- X tot_tohit += p_ptr->ptohit;
- X /* if creature not lit, make it more difficult to hit */
- X if (m_list[crptr].ml)
- X base_tohit = p_ptr->bth;
- X else
- X base_tohit = (p_ptr->bth / 2) - (tot_tohit * (BTH_PLUS_ADJ-1))
- X - (p_ptr->lev * class_level_adj[p_ptr->pclass][CLA_BTH] / 2);
- X
- X /* Loop for number of blows, trying to hit the critter. */
- X do
- X {
- X if (test_hit(base_tohit, (int)p_ptr->lev, tot_tohit,
- X (int)c_list[monptr].ac, CLA_BTH))
- X {
- X (void) sprintf(out_val, "You hit %s.", m_name);
- X msg_print(out_val);
- X if (i_ptr->tval != TV_NOTHING)
- X {
- X k = pdamroll(i_ptr->damage);
- X k = tot_dam(i_ptr, k, monptr);
- X k = critical_blow((int)i_ptr->weight, tot_tohit, k, CLA_BTH);
- X }
- X else /* Bare hands!? */
- X {
- X k = damroll(1, 1);
- X k = critical_blow(1, 0, k, CLA_BTH);
- X }
- X k += p_ptr->ptodam;
- X if (k < 0) k = 0;
- X
- X if (py.flags.confuse_monster)
- X {
- X py.flags.confuse_monster = FALSE;
- X msg_print("Your hands stop glowing.");
- X if ((c_list[monptr].cdefense & CD_NO_SLEEP)
- X || (randint(MAX_MONS_LEVEL) < c_list[monptr].level))
- X (void) sprintf(out_val, "%s is unaffected.", m_name);
- X else
- X {
- X (void) sprintf(out_val, "%s appears confused.", m_name);
- X m_list[crptr].confused = TRUE;
- X }
- X msg_print(out_val);
- X if (m_list[crptr].ml && randint(4) == 1)
- X c_recall[monptr].r_cdefense |=
- X c_list[monptr].cdefense & CD_NO_SLEEP;
- X }
- X
- X /* See if we done it in. */
- X if (mon_take_hit(crptr, k) >= 0)
- X {
- X (void) sprintf(out_val, "You have slain %s.", m_name);
- X msg_print(out_val);
- X prt_experience();
- X blows = 0;
- X }
- X
- X if ((i_ptr->tval >= TV_SLING_AMMO)
- X && (i_ptr->tval <= TV_ARROW)) /* Use missiles up*/
- X {
- X i_ptr->number--;
- X inven_weight -= i_ptr->weight;
- X py.flags.status |= PY_STR_WGT;
- X if (i_ptr->number == 0)
- X {
- X equip_ctr--;
- X py_bonuses(i_ptr, -1);
- X invcopy(i_ptr, OBJ_NOTHING);
- X calc_bonuses();
- X }
- X }
- X }
- X else
- X {
- X (void) sprintf(out_val, "You miss %s.", m_name);
- X msg_print(out_val);
- X }
- X blows--;
- X }
- X while (blows >= 1);
- X}
- X
- X
- X/* Moves player from one space to another. -RAK- */
- X/* Note: This routine has been pre-declared; see that for argument*/
- Xvoid move_char(dir, do_pickup)
- Xint dir, do_pickup;
- X{
- X int old_row, old_col, old_find_flag;
- X int y, x;
- X register int i, j;
- X register cave_type *c_ptr, *d_ptr;
- X
- X if ((py.flags.confused > 0) && /* Confused? */
- X (randint(4) > 1) && /* 75% random movement */
- X (dir != 5)) /* Never random if sitting*/
- X {
- X dir = randint(9);
- X end_find();
- X }
- X y = char_row;
- X x = char_col;
- X if (mmove(dir, &y, &x)) /* Legal move? */
- X {
- X c_ptr = &cave[y][x];
- X /* if there is no creature, or an unlit creature in the walls then... */
- X /* disallow attacks against unlit creatures in walls because moving into
- X a wall is a free turn normally, hence don't give player free turns
- X attacking each wall in an attempt to locate the invisible creature,
- X instead force player to tunnel into walls which always takes a turn */
- X if ((c_ptr->cptr < 2)
- X || (!m_list[c_ptr->cptr].ml && c_ptr->fval >= MIN_CLOSED_SPACE))
- X {
- X if (c_ptr->fval <= MAX_OPEN_SPACE) /* Open floor spot */
- X {
- X /* Make final assignments of char co-ords */
- X old_row = char_row;
- X old_col = char_col;
- X char_row = y;
- X char_col = x;
- X /* Move character record (-1) */
- X move_rec(old_row, old_col, char_row, char_col);
- X /* Check for new panel */
- X if (get_panel(char_row, char_col, FALSE))
- X prt_map();
- X /* Check to see if he should stop */
- X if (find_flag)
- X area_affect(dir, char_row, char_col);
- X /* Check to see if he notices something */
- X /* fos may be negative if have good rings of searching */
- X if ((py.misc.fos <= 1) || (randint(py.misc.fos) == 1) ||
- X (search_flag))
- X search(char_row, char_col, py.misc.srh);
- X /* A room of light should be lit. */
- X if (c_ptr->fval == LIGHT_FLOOR)
- X {
- X if (!c_ptr->pl && !py.flags.blind)
- 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 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 /* Move the light source */
- X move_light(old_row, old_col, char_row, char_col);
- X /* An object is beneath him. */
- X if (c_ptr->tptr != 0)
- X {
- X carry(char_row, char_col, do_pickup);
- X /* if stepped on falling rock trap, and space contains
- X rubble, then step back into a clear area */
- X if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
- X {
- X move_rec(char_row, char_col, old_row, old_col);
- X move_light(char_row, char_col, old_row, old_col);
- X char_row = old_row;
- X char_col = old_col;
- X /* check to see if we have stepped back onto another
- X trap, if so, set it off */
- X c_ptr = &cave[char_row][char_col];
- X if (c_ptr->tptr != 0)
- X {
- X i = t_list[c_ptr->tptr].tval;
- X if (i == TV_INVIS_TRAP || i == TV_VIS_TRAP
- X || i == TV_STORE_DOOR)
- X hit_trap(char_row, char_col);
- X }
- X }
- X }
- X }
- X else /*Can't move onto floor space*/
- X {
- X if (!find_flag && (c_ptr->tptr != 0))
- X {
- X if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
- X msg_print("There is rubble blocking your way.");
- X else if (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR)
- X msg_print("There is a closed door blocking your way.");
- X }
- X else
- X end_find();
- X free_turn_flag = TRUE;
- X }
- X }
- X else /* Attacking a creature! */
- X {
- X old_find_flag = find_flag;
- X end_find();
- X /* if player can see monster, and was in find mode, then nothing */
- X if (m_list[c_ptr->cptr].ml && old_find_flag)
- X {
- X /* did not do anything this turn */
- X free_turn_flag = TRUE;
- X }
- X else
- X {
- X if (py.flags.afraid < 1) /* Coward? */
- X py_attack(y, x);
- X else /* Coward! */
- X msg_print("You are too afraid!");
- X }
- X }
- X }
- X}
- X
- X
- X/* Chests have traps too. -RAK- */
- X/* Note: Chest traps are based on the FLAGS value */
- Xstatic void chest_trap(y, x)
- Xint y, x;
- X{
- X register int i;
- X int j, k;
- X register inven_type *t_ptr;
- X
- X t_ptr = &t_list[cave[y][x].tptr];
- X if (CH_LOSE_STR & t_ptr->flags)
- X {
- X msg_print("A small needle has pricked you!");
- X if (!py.flags.sustain_str)
- X {
- X (void) dec_stat(A_STR);
- X take_hit(damroll(1, 4), "a poison needle");
- X msg_print("You feel weakened!");
- X }
- X else
- X msg_print("You are unaffected.");
- X }
- X if (CH_POISON & t_ptr->flags)
- X {
- X msg_print("A small needle has pricked you!");
- X take_hit(damroll(1, 6), "a poison needle");
- X py.flags.poisoned += 10 + randint(20);
- X }
- X if (CH_PARALYSED & t_ptr->flags)
- X {
- X msg_print("A puff of yellow gas surrounds you!");
- X if (py.flags.free_act)
- X msg_print("You are unaffected.");
- X else
- X {
- X msg_print("You choke and pass out.");
- X py.flags.paralysis = 10 + randint(20);
- X }
- X }
- X if (CH_SUMMON & t_ptr->flags)
- X {
- X for (i = 0; i < 3; i++)
- X {
- X j = y;
- X k = x;
- X (void) summon_monster(&j, &k, FALSE);
- X }
- X }
- X if (CH_EXPLODE & t_ptr->flags)
- X {
- X msg_print("There is a sudden explosion!");
- X (void) delete_object(y, x);
- X take_hit(damroll(5, 8), "an exploding chest");
- X }
- X}
- X
- X
- X/* Opens a closed door or closed chest. -RAK- */
- Xvoid openobject()
- X{
- X int y, x, i, dir;
- X int flag, no_object;
- X register cave_type *c_ptr;
- X register inven_type *t_ptr;
- X register struct misc *p_ptr;
- X register monster_type *m_ptr;
- X vtype m_name, out_val;
- X
- X y = char_row;
- X x = char_col;
- X if (get_dir(NULL, &dir))
- X {
- X (void) mmove(dir, &y, &x);
- X c_ptr = &cave[y][x];
- X no_object = FALSE;
- X if (c_ptr->cptr > 1 && c_ptr->tptr != 0 &&
- X (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR
- X || t_list[c_ptr->tptr].tval == TV_CHEST))
- X {
- X m_ptr = &m_list[c_ptr->cptr];
- X if (m_ptr->ml)
- X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
- X else
- X (void) strcpy (m_name, "Something");
- X (void) sprintf(out_val, "%s is in your way!", m_name);
- X msg_print(out_val);
- X }
- X else if (c_ptr->tptr != 0)
- X /* Closed door */
- X if (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR)
- X {
- X t_ptr = &t_list[c_ptr->tptr];
- X if (t_ptr->p1 > 0) /* It's locked. */
- X {
- X p_ptr = &py.misc;
- X i = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
- X + (class_level_adj[p_ptr->pclass][CLA_DISARM]
- X * p_ptr->lev / 3);
- X if (py.flags.confused > 0)
- X msg_print("You are too confused to pick the lock.");
- X else if ((i-t_ptr->p1) > randint(100))
- X {
- X msg_print("You have picked the lock.");
- X py.misc.exp++;
- X prt_experience();
- X t_ptr->p1 = 0;
- X }
- X else
- X count_msg_print("You failed to pick the lock.");
- X }
- X else if (t_ptr->p1 < 0) /* It's stuck */
- X msg_print("It appears to be stuck.");
- X if (t_ptr->p1 == 0)
- X {
- X invcopy(&t_list[c_ptr->tptr], OBJ_OPEN_DOOR);
- X c_ptr->fval = CORR_FLOOR;
- X lite_spot(y, x);
- X command_count = 0;
- X }
- X }
- X /* Open a closed chest. */
- X else if (t_list[c_ptr->tptr].tval == TV_CHEST)
- X {
- X p_ptr = &py.misc;
- X i = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
- X + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
- X t_ptr = &t_list[c_ptr->tptr];
- X flag = FALSE;
- X if (CH_LOCKED & t_ptr->flags)
- X if (py.flags.confused > 0)
- X msg_print("You are too confused to pick the lock.");
- X else if ((i-(int)t_ptr->level) > randint(100))
- X {
- X msg_print("You have picked the lock.");
- X flag = TRUE;
- X py.misc.exp += t_ptr->level;
- X prt_experience();
- X }
- X else
- X count_msg_print("You failed to pick the lock.");
- X else
- X flag = TRUE;
- X if (flag)
- X {
- X t_ptr->flags &= ~CH_LOCKED;
- X t_ptr->name2 = SN_EMPTY;
- X known2(t_ptr);
- X t_ptr->cost = 0;
- X }
- X flag = FALSE;
- X /* Was chest still trapped? (Snicker) */
- X if ((CH_LOCKED & t_ptr->flags) == 0)
- X {
- X chest_trap(y, x);
- X if (c_ptr->tptr != 0)
- X flag = TRUE;
- X }
- X /* Chest treasure is allocated as if a creature */
- X /* had been killed. */
- X if (flag)
- X {
- X /* clear the cursed chest/monster win flag, so that people
- X can not win by opening a cursed chest */
- X t_list[c_ptr->tptr].flags &= ~TR_CURSED;
- X (void) monster_death(y, x, t_list[c_ptr->tptr].flags);
- X t_list[c_ptr->tptr].flags = 0;
- X }
- X }
- X else
- X no_object = TRUE;
- X else
- X no_object = TRUE;
- X
- X if (no_object)
- X {
- X msg_print("I do not see anything you can open there.");
- X free_turn_flag = TRUE;
- X }
- X }
- X}
- X
- X
- X/* Closes an open door. -RAK- */
- Xvoid closeobject()
- X{
- X int y, x, dir, no_object;
- X vtype out_val, m_name;
- X register cave_type *c_ptr;
- X register monster_type *m_ptr;
- X
- X y = char_row;
- X x = char_col;
- X if (get_dir(NULL, &dir))
- X {
- X (void) mmove(dir, &y, &x);
- X c_ptr = &cave[y][x];
- X no_object = FALSE;
- X if (c_ptr->tptr != 0)
- X if (t_list[c_ptr->tptr].tval == TV_OPEN_DOOR)
- X if (c_ptr->cptr == 0)
- X if (t_list[c_ptr->tptr].p1 == 0)
- X {
- X invcopy(&t_list[c_ptr->tptr], OBJ_CLOSED_DOOR);
- X c_ptr->fval = BLOCKED_FLOOR;
- X lite_spot(y, x);
- X }
- X else
- X msg_print("The door appears to be broken.");
- X else
- X {
- X m_ptr = &m_list[c_ptr->cptr];
- X if (m_ptr->ml)
- X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
- X else
- X (void) strcpy (m_name, "Something");
- X (void) sprintf(out_val, "%s is in your way!", m_name);
- X msg_print(out_val);
- X }
- X else
- X no_object = TRUE;
- X else
- X no_object = TRUE;
- X
- X if (no_object)
- X {
- X msg_print("I do not see anything you can close there.");
- X free_turn_flag = TRUE;
- X }
- X }
- X}
- X
- X
- X/* Tunneling through real wall: 10, 11, 12 -RAK- */
- X/* Used by TUNNEL and WALL_TO_MUD */
- Xint twall(y, x, t1, t2)
- Xint y, x, t1, t2;
- X{
- X register int i, j;
- X register cave_type *c_ptr;
- X int res, found;
- X
- X res = FALSE;
- X if (t1 > t2)
- X {
- X c_ptr = &cave[y][x];
- X if (c_ptr->lr)
- X {
- X /* should become a room space, check to see whether it should be
- X LIGHT_FLOOR or DARK_FLOOR */
- X found = FALSE;
- X for (i = y-1; i <= y+1; i++)
- X for (j = x-1; j <= x+1; j++)
- X if (cave[i][j].fval <= MAX_CAVE_ROOM)
- X {
- X c_ptr->fval = cave[i][j].fval;
- X c_ptr->pl = cave[i][j].pl;
- X found = TRUE;
- X break;
- X }
- X if (!found)
- X {
- X c_ptr->fval = CORR_FLOOR;
- X c_ptr->pl = FALSE;
- X }
- X }
- X else
- X {
- X /* should become a corridor space */
- X c_ptr->fval = CORR_FLOOR;
- X c_ptr->pl = FALSE;
- X }
- X c_ptr->fm = FALSE;
- X if (panel_contains(y, x))
- X if ((c_ptr->tl || c_ptr->pl) && c_ptr->tptr != 0)
- X msg_print("You have found something!");
- X lite_spot(y, x);
- X res = TRUE;
- X }
- X return(res);
- X}
- X
- X
- X/* Tunnels through rubble and walls -RAK- */
- X/* Must take into account: secret doors, special tools */
- Xvoid tunnel(dir)
- Xint dir;
- X{
- X register int i, tabil;
- X register cave_type *c_ptr;
- X register inven_type *i_ptr;
- X int y, x;
- X monster_type *m_ptr;
- X vtype out_val, m_name;
- X
- X if ((py.flags.confused > 0) && /* Confused? */
- X (randint(4) > 1)) /* 75% random movement */
- X dir = randint(9);
- X y = char_row;
- X x = char_col;
- X (void) mmove(dir, &y, &x);
- X
- X c_ptr = &cave[y][x];
- X /* Compute the digging ability of player; based on */
- X /* strength, and type of tool used */
- X tabil = py.stats.use_stat[A_STR];
- X i_ptr = &inventory[INVEN_WIELD];
- X if (c_ptr->cptr > 1)
- X {
- X m_ptr = &m_list[c_ptr->cptr];
- X if (m_ptr->ml)
- X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
- X else
- X (void) strcpy (m_name, "Something");
- X (void) sprintf(out_val, "%s is in your way!", m_name);
- X msg_print(out_val);
- X
- X /* let the player attack the creature */
- X if (py.flags.afraid < 1)
- X py_attack(y, x);
- X else
- X msg_print("You are too afraid!");
- X }
- X else if (i_ptr->tval != TV_NOTHING)
- X {
- X if (TR_TUNNEL & i_ptr->flags)
- X tabil += 25 + i_ptr->p1*50;
- X else
- X {
- X tabil += (i_ptr->damage[0]*i_ptr->damage[1]) + i_ptr->tohit
- X + i_ptr->todam;
- X /* divide by two so that digging without shovel isn't too easy */
- X tabil >>= 1;
- X }
- X
- X /* Regular walls; Granite, magma intrusion, quartz vein */
- X /* Don't forget the boundary walls, made of titanium (255)*/
- X switch(c_ptr->fval)
- X {
- X case GRANITE_WALL:
- X i = randint(1200) + 80;
- X if (twall(y, x, tabil, i))
- X msg_print("You have finished the tunnel.");
- X else
- X count_msg_print("You tunnel into the granite wall.");
- X break;
- X case MAGMA_WALL:
- X i = randint(600) + 10;
- X if (twall(y, x, tabil, i))
- X msg_print("You have finished the tunnel.");
- X else
- X count_msg_print("You tunnel into the magma intrusion.");
- X break;
- X case QUARTZ_WALL:
- X i = randint(400) + 10;
- X if (twall(y, x, tabil, i))
- X msg_print("You have finished the tunnel.");
- X else
- X count_msg_print("You tunnel into the quartz vein.");
- X break;
- X case BOUNDARY_WALL:
- X msg_print("This seems to be permanent rock.");
- X break;
- X default:
- X /* Is there an object in the way? (Rubble and secret doors)*/
- X if (c_ptr->tptr != 0)
- X {
- X /* Rubble. */
- X if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
- X {
- X if (tabil > randint(180))
- X {
- X (void) delete_object(y, x);
- X msg_print("You have removed the rubble.");
- X if (randint(10) == 1)
- X {
- X place_object(y, x);
- X if (test_light(y, x))
- X msg_print("You have found something!");
- X }
- X lite_spot(y, x);
- X }
- X else
- X count_msg_print("You dig in the rubble.");
- X }
- X /* Secret doors.*/
- X else if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
- X {
- X count_msg_print("You tunnel into the granite wall.");
- X search(char_row, char_col, py.misc.srh);
- X }
- X else
- X {
- X msg_print("You can't tunnel through that.");
- X free_turn_flag = TRUE;
- X }
- X }
- X else
- X {
- X msg_print("Tunnel through what? Empty air?!?");
- X free_turn_flag = TRUE;
- X }
- X break;
- X }
- X }
- X else
- X msg_print("You dig with your hands, making no progress.");
- X}
- X
- X
- X/* Disarms a trap -RAK- */
- Xvoid disarm_trap()
- X{
- X int y, x, level, tmp, dir, no_disarm;
- X register int tot, i;
- X register cave_type *c_ptr;
- X register inven_type *i_ptr;
- X monster_type *m_ptr;
- X vtype m_name, out_val;
- X
- X y = char_row;
- X x = char_col;
- X if (get_dir(NULL, &dir))
- X {
- X (void) mmove(dir, &y, &x);
- X c_ptr = &cave[y][x];
- X no_disarm = FALSE;
- X if (c_ptr->cptr > 1 && c_ptr->tptr != 0 &&
- X (t_list[c_ptr->tptr].tval == TV_VIS_TRAP
- X || t_list[c_ptr->tptr].tval == TV_CHEST))
- X {
- X m_ptr = &m_list[c_ptr->cptr];
- X if (m_ptr->ml)
- X (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
- X else
- X (void) strcpy (m_name, "Something");
- X (void) sprintf(out_val, "%s is in your way!", m_name);
- X msg_print(out_val);
- X }
- X else if (c_ptr->tptr != 0)
- X {
- X tot = py.misc.disarm + 2*todis_adj() + stat_adj(A_INT)
- X + (class_level_adj[py.misc.pclass][CLA_DISARM] * py.misc.lev / 3);
- X if ((py.flags.blind > 0) || (no_light()))
- X tot = tot / 10;
- X if (py.flags.confused > 0)
- X tot = tot / 10;
- X if (py.flags.image > 0)
- X tot = tot / 10;
- X i_ptr = &t_list[c_ptr->tptr];
- X i = i_ptr->tval;
- X level = i_ptr->level;
- X if (i == TV_VIS_TRAP) /* Floor trap */
- X {
- X if ((tot + 100 - level) > randint(100))
- X {
- X msg_print("You have disarmed the trap.");
- X py.misc.exp += i_ptr->p1;
- X (void) delete_object(y, x);
- X /* make sure we move onto the trap even if confused */
- X tmp = py.flags.confused;
- X py.flags.confused = 0;
- X move_char(dir, FALSE);
- X py.flags.confused = tmp;
- X prt_experience();
- X }
- X /* avoid randint(0) call */
- X else if ((tot > 5) && (randint(tot) > 5))
- X count_msg_print("You failed to disarm the trap.");
- X else
- X {
- X msg_print("You set the trap off!");
- X /* make sure we move onto the trap even if confused */
- X tmp = py.flags.confused;
- X py.flags.confused = 0;
- X move_char(dir, FALSE);
- X py.flags.confused += tmp;
- X }
- X }
- X else if (i == TV_CHEST)
- X {
- X if (!known2_p(i_ptr))
- X {
- X msg_print("I don't see a trap.");
- X free_turn_flag = TRUE;
- X }
- X else if (CH_TRAPPED & i_ptr->flags)
- X {
- X if ((tot - level) > randint(100))
- X {
- X i_ptr->flags &= ~CH_TRAPPED;
- X if (CH_LOCKED & i_ptr->flags)
- X i_ptr->name2 = SN_LOCKED;
- X else
- X i_ptr->name2 = SN_DISARMED;
- X msg_print("You have disarmed the chest.");
- X known2(i_ptr);
- X py.misc.exp += level;
- X prt_experience();
- X }
- X else if ((tot > 5) && (randint(tot) > 5))
- X count_msg_print("You failed to disarm the chest.");
- X else
- X {
- X msg_print("You set a trap off!");
- X known2(i_ptr);
- X chest_trap(y, x);
- X }
- X }
- X else
- X {
- X msg_print("The chest was not trapped.");
- X free_turn_flag = TRUE;
- X }
- X }
- X else
- X no_disarm = TRUE;
- X }
- X else
- X no_disarm = TRUE;
- X
- X if (no_disarm)
- X {
- X msg_print("I do not see anything to disarm there.");
- X free_turn_flag = TRUE;
- X }
- X }
- X}
- X
- X
- X/* An enhanced look, with peripheral vision. Looking all 8 -CJS-
- X directions will see everything which ought to be visible. Can
- X specify direction 5, which looks in all directions.
- X
- X For the purpose of hindering vision, each place is regarded as
- X a diamond just touching its four immediate neighbours. A
- X diamond is opaque if it is a wall, or shut door, or something
- X like that. A place is visible if any part of its diamond is
- X visible: i.e. there is a line from the view point to part of
- X the diamond which does not pass through any opaque diamonds.
- X
- X Consider the following situation:
- X
- X @.... X X X X X
- X .##.. / \ / \ / \ / \ / \
- X ..... X @ X . X . X 1 X . X
- X \ / \ / \ / \ / \ /
- X X X X X X
- X Expanded view, with / \ / \ / \ / \ / \
- X diamonds inscribed X . X # X # X 2 X . X
- X about each point, \ / \ / \ / \ / \ /
- X and some locations X X X X X
- X numbered. / \ / \ / \ / \ / \
- X X . X . X . X 3 X 4 X
- X \ / \ / \ / \ / \ /
- X X X X X X
- X - Location 1 is fully visible.
- X - Location 2 is visible, even though partially obscured.
- X - Location 3 is invisible, but if either # were
- X transparent, it would be visible.
- X - Location 4 is completely obscured by a single #.
- X
- X The function which does the work is look_ray. It sets up its
- X own co-ordinate frame (global variables map back to the
- X dungeon frame) and looks for everything between two angles
- X specified from a central line. It is recursive, and each call
- X looks at stuff visible along a line parallel to the center
- X line, and a set distance away from it. A diagonal look uses
- X more extreme peripheral vision from the closest horizontal and
- X vertical directions; horizontal or vertical looks take a call
- X for each side of the central line. */
- X
- X/* Globally accessed variables: gl_nseen counts the number of places where
- X something is seen. gl_rock indicates a look for rock or objects.
- X
- X The others map co-ords in the ray frame to dungeon co-ords.
- X
- X dungeon y = char_row + gl_fyx * (ray x) + gl_fyy * (ray y)
- X dungeon x = char_col + gl_fxx * (ray x) + gl_fxy * (ray y) */
- Xstatic int gl_fxx, gl_fxy, gl_fyx, gl_fyy;
- Xstatic int gl_nseen, gl_noquery;
- Xstatic int gl_rock;
- X/* Intended to be indexed by dir/2, since is only relevant to horizontal or
- X vertical directions. */
- Xstatic int set_fxy[] = { 0, 1, 0, 0, -1 };
- Xstatic int set_fxx[] = { 0, 0, -1, 1, 0 };
- Xstatic int set_fyy[] = { 0, 0, 1, -1, 0 };
- Xstatic int set_fyx[] = { 0, 1, 0, 0, -1 };
- X/* Map diagonal-dir/2 to a normal-dir/2. */
- Xstatic int map_diag1[] = { 1, 3, 0, 2, 4 };
- Xstatic int map_diag2[] = { 2, 1, 0, 4, 3 };
- X
- X#define GRADF 10000 /* Any sufficiently big number will do */
- X
- X/* Look at what we can see. This is a free move.
- X
- X Prompts for a direction, and then looks at every object in
- X turn within a cone of vision in that direction. For each
- X object, the cursor is moved over the object, a description is
- X given, and we wait for the user to type something. Typing
- X ESCAPE will abort the entire look.
- X
- X Looks first at real objects and monsters, and looks at rock
- X types only after all other things have been seen. Only looks at rock
- X types if the highlight_seams option is set. */
- X
- Xvoid look()
- X{
- X register int i, abort;
- X int dir, dummy;
- X
- X if (py.flags.blind > 0)
- X msg_print("You can't see a damn thing!");
- X else if (py.flags.image > 0)
- X msg_print("You can't believe what you are seeing! It's like a dream!");
- X else if (get_alldir("Look which direction?", &dir))
- X {
- X abort = FALSE;
- X gl_nseen = 0;
- X gl_rock = 0;
- X gl_noquery = FALSE; /* Have to set this up for the look_see */
- X if (look_see(0, 0, &dummy))
- X abort = TRUE;
- X else
- X {
- X do
- X {
- X abort = FALSE;
- X if (dir == 5)
- X {
- X for (i = 1; i <= 4; i++)
- X {
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
- X if (look_ray(0, 2*GRADF-1, 1))
- X {
- X abort = TRUE;
- X break;
- X }
- X gl_fxy = -gl_fxy;
- X gl_fyy = -gl_fyy;
- X if (look_ray(0, 2*GRADF, 2))
- X {
- X abort = TRUE;
- X break;
- X }
- X }
- X }
- X else if ((dir & 1) == 0) /* Straight directions */
- X {
- X i = dir >> 1;
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
- X if (look_ray(0, GRADF, 1))
- X abort = TRUE;
- X else
- X {
- X gl_fxy = -gl_fxy;
- X gl_fyy = -gl_fyy;
- X abort = look_ray(0, GRADF, 2);
- X }
- X }
- X else
- X {
- X i = map_diag1[dir >> 1];
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = -set_fxy[i]; gl_fyy = -set_fyy[i];
- X if (look_ray(1, 2*GRADF, GRADF))
- X abort = TRUE;
- X else
- X {
- X i = map_diag2[dir >> 1];
- X gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
- X gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
- X abort = look_ray(1, 2*GRADF-1, GRADF);
- X }
- X }
- X }
- X while (abort == FALSE && highlight_seams && (++gl_rock < 2));
- X if (abort)
- X msg_print("--Aborting look--");
- X else
- X {
- X if (gl_nseen)
- X {
- X if (dir == 5)
- X msg_print("That's all you see.");
- X else
- X msg_print("That's all you see in that direction.");
- X }
- X else if (dir == 5)
- X msg_print("You see nothing of interest.");
- X else
- X msg_print("You see nothing of interest in that direction.");
- X }
- X }
- X }
- X}
- X
- X/* Look at everything within a cone of vision between two ray
- X lines emanating from the player, and y or more places away
- X from the direct line of view. This is recursive.
- X
- X Rays are specified by gradients, y over x, multiplied by
- X 2*GRADF. This is ONLY called with gradients between 2*GRADF
- X (45 degrees) and 1 (almost horizontal).
- X
- X (y axis)/ angle from
- X ^ / ___ angle to
- X | / ___
- X ...|../.....___.................... parameter y (look at things in the
- X | / ___ cone, and on or above this line)
- X |/ ___
- X @--------------------> direction in which you are looking. (x axis)
- X |
- X | */
- Xstatic int look_ray(y, from, to)
- Xint y, from, to;
- X{
- X register int max_x, x;
- X int transparent;
- X
- X /* from is the larger angle of the ray, since we scan towards the
- X center line. If from is smaller, then the ray does not exist. */
- X if (from <= to || y > MAX_SIGHT)
- X return FALSE;
- X /* Find first visible location along this line. Minimum x such
- X that (2x-1)/x < from/GRADF <=> x > GRADF(2x-1)/from. This may
- X be called with y=0 whence x will be set to 0. Thus we need a
- X special fix. */
- X x = (long)GRADF * (2 * y - 1) / from + 1;
- X if (x <= 0)
- X x = 1;
- X
- X /* Find last visible location along this line.
- X Maximum x such that (2x+1)/x > to/GRADF <=> x < GRADF(2x+1)/to */
- X max_x = ((long)GRADF * (2 * y + 1) - 1) / to;
- X if (max_x > MAX_SIGHT)
- X max_x = MAX_SIGHT;
- X if (max_x < x)
- X return FALSE;
- X
- X /* gl_noquery is a HACK to prevent doubling up on direct lines of
- X sight. If 'to' is greater than 1, we do not really look at
- X stuff along the direct line of sight, but we do have to see
- X what is opaque for the purposes of obscuring other objects. */
- X if (y == 0 && to > 1 || y == x && from < GRADF*2)
- X gl_noquery = TRUE;
- X else
- X gl_noquery = FALSE;
- X if (look_see(x, y, &transparent))
- X return TRUE;
- X if (y == x)
- X gl_noquery = FALSE;
- X if (transparent)
- X goto init_transparent;
- X
- X for (;;)
- X {
- X /* Look down the window we've found. */
- X if (look_ray(y+1, from, (int)((2 * y + 1) * (long)GRADF / x)))
- X return TRUE;
- X /* Find the start of next window. */
- X do
- X {
- X if (x == max_x)
- X return FALSE;
- X /* See if this seals off the scan. (If y is zero, then it will.) */
- X from = (2 * y - 1) * (long)GRADF / x;
- X if (from <= to)
- X return FALSE;
- X x++;
- X if (look_see(x, y, &transparent))
- X return TRUE;
- X }
- X while(!transparent);
- X init_transparent:
- X /* Find the end of this window of visibility. */
- X do
- X {
- X if (x == max_x)
- X /* The window is trimmed by an earlier limit. */
- X return look_ray(y+1, from, to);
- X x++;
- X if (look_see(x, y, &transparent))
- X return TRUE;
- X }
- X while(transparent);
- X }
- X}
- X
- Xstatic int look_see(x, y, transparent)
- Xregister int x, y;
- Xint *transparent;
- X{
- X char *dstring, *string, query;
- X register cave_type *c_ptr;
- X register int j;
- X bigvtype out_val, tmp_str;
- X
- X if (x < 0 || y < 0 || y > x)
- X {
- X (void) sprintf(tmp_str, "Illegal call to look_see(%d, %d)", x, y);
- X msg_print(tmp_str);
- X }
- X if (x == 0 && y == 0)
- X dstring = "You are on";
- X else
- X dstring = "You see";
- X j = char_col + gl_fxx * x + gl_fxy * y;
- X y = char_row + gl_fyx * x + gl_fyy * y;
- X x = j;
- X if (!panel_contains(y, x))
- X {
- X *transparent = FALSE;
- X return FALSE;
- X }
- X c_ptr = &cave[y][x];
- X *transparent = c_ptr->fval <= MAX_OPEN_SPACE;
- X if (gl_noquery)
- X return FALSE; /* Don't look at a direct line of sight. A hack. */
- X out_val[0] = 0;
- X if (gl_rock == 0 && c_ptr->cptr > 1 && m_list[c_ptr->cptr].ml)
- X {
- X j = m_list[c_ptr->cptr].mptr;
- X (void) sprintf(out_val, "%s %s %s. [(r)ecall]",
- X dstring,
- X is_a_vowel( c_list[j].name[0] ) ? "an" : "a",
- X c_list[j].name);
- X dstring = "It is on";
- X prt(out_val, 0, 0);
- X move_cursor_relative(y, x);
- X query = inkey();
- X if (query == 'r' || query == 'R')
- X {
- X save_screen();
- X query = roff_recall(j);
- X restore_screen();
- X }
- X }
- X if (c_ptr->tl || c_ptr->pl || c_ptr->fm)
- X {
- X if (c_ptr->tptr != 0)
- X {
- X if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
- X goto granite;
- X if (gl_rock ==0 && t_list[c_ptr->tptr].tval != TV_INVIS_TRAP)
- X {
- X objdes(tmp_str, &t_list[c_ptr->tptr], TRUE);
- X (void) sprintf(out_val, "%s %s ---pause---", dstring, tmp_str);
- X dstring = "It is in";
- X prt(out_val, 0, 0);
- X move_cursor_relative(y, x);
- X query = inkey();
- X }
- X }
- X if ((gl_rock || out_val[0]) && c_ptr->fval >= MIN_CLOSED_SPACE)
- X {
- X switch(c_ptr->fval)
- X {
- X case BOUNDARY_WALL:
- X case GRANITE_WALL:
- X granite:
- X /* Granite is only interesting if it contains something. */
- X if(out_val[0])
- X string = "a granite wall";
- X else
- X string = NULL; /* In case we jump here */
- X break;
- X case MAGMA_WALL: string = "some dark rock";
- X break;
- X case QUARTZ_WALL: string = "a quartz vein";
- X break;
- X default: string = NULL;
- X break;
- X }
- X if (string)
- X {
- X (void) sprintf(out_val, "%s %s ---pause---", dstring, string);
- X prt(out_val, 0, 0);
- X move_cursor_relative(y, x);
- X query = inkey();
- X }
- X }
- X }
- X if (out_val[0])
- X {
- X gl_nseen++;
- X if (query == ESCAPE)
- X return TRUE;
- X }
- X
- X return FALSE;
- X}
- X
- X
- Xstatic void inven_throw(item_val, t_ptr)
- Xint item_val;
- Xinven_type *t_ptr;
- X{
- X register inven_type *i_ptr;
- X
- X i_ptr = &inventory[item_val];
- X *t_ptr = *i_ptr;
- X if (i_ptr->number > 1)
- X {
- X t_ptr->number = 1;
- X i_ptr->number--;
- X inven_weight -= i_ptr->weight;
- X py.flags.status |= PY_STR_WGT;
- X }
- X else
- X inven_destroy(item_val);
- X}
- X
- X
- X/* Obtain the hit and damage bonuses and the maximum distance for a
- X thrown missile. */
- Xstatic void facts(i_ptr, tbth, tpth, tdam, tdis)
- Xregister inven_type *i_ptr;
- Xint *tbth, *tpth, *tdam, *tdis;
- X{
- X register int tmp_weight;
- X
- X if (i_ptr->weight < 1)
- X tmp_weight = 1;
- X else
- X tmp_weight = i_ptr->weight;
- X
- X /* Throwing objects */
- X *tdam = pdamroll(i_ptr->damage) + i_ptr->todam;
- X *tbth = py.misc.bthb * 75 / 100;
- X *tpth = py.misc.ptohit + i_ptr->tohit;
- X
- X /* Add this back later if the correct throwing device. -CJS- */
- X if (inventory[INVEN_WIELD].tval != TV_NOTHING)
- X *tpth -= inventory[INVEN_WIELD].tohit;
- X
- X *tdis = (((py.stats.use_stat[A_STR]+20)*10)/tmp_weight);
- X if (*tdis > 10) *tdis = 10;
- X
- X /* multiply damage bonuses instead of adding, when have proper
- X missile/weapon combo, this makes them much more useful */
- X
- X /* Using Bows, slings, or crossbows */
- X if (inventory[INVEN_WIELD].tval == TV_BOW)
- X switch(inventory[INVEN_WIELD].p1)
- X {
- X case 1:
- X if (i_ptr->tval == TV_SLING_AMMO) /* Sling and ammo */
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 2;
- X *tdis = 20;
- X }
- X break;
- X case 2:
- X if (i_ptr->tval == TV_ARROW) /* Short Bow and Arrow */
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 2;
- X *tdis = 25;
- X }
- X break;
- X case 3:
- X if (i_ptr->tval == TV_ARROW) /* Long Bow and Arrow */
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 3;
- X *tdis = 30;
- X }
- X break;
- X case 4:
- X if (i_ptr->tval == TV_ARROW) /* Composite Bow and Arrow*/
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 4;
- X *tdis = 35;
- X }
- X break;
- X case 5:
- X if (i_ptr->tval == TV_BOLT) /* Light Crossbow and Bolt*/
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 3;
- X *tdis = 25;
- X }
- X break;
- X case 6:
- X if (i_ptr->tval == TV_BOLT) /* Heavy Crossbow and Bolt*/
- X {
- X *tbth = py.misc.bthb;
- X *tpth += 2 * inventory[INVEN_WIELD].tohit;
- X *tdam += inventory[INVEN_WIELD].todam;
- X *tdam = *tdam * 4;
- X *tdis = 35;
- X }
- X break;
- X }
- X}
- X
- X
- Xstatic void drop_throw(y, x, t_ptr)
- Xint y, x;
- Xinven_type *t_ptr;
- X{
- X register int i, j, k;
- X int flag, cur_pos;
- X bigvtype out_val, tmp_str;
- X register cave_type *c_ptr;
- X
- X flag = FALSE;
- X i = y;
- X j = x;
- X k = 0;
- X if (randint(10) > 1)
- X {
- X do
- X {
- X if (in_bounds(i, j))
- X {
- X c_ptr = &cave[i][j];
- X if (c_ptr->fval <= MAX_OPEN_SPACE && c_ptr->tptr == 0)
- X flag = TRUE;
- X }
- X if (!flag)
- X {
- X i = y + randint(3) - 2;
- X j = x + randint(3) - 2;
- X k++;
- X }
- X }
- X while ((!flag) && (k <= 9));
- X }
- X if (flag)
- X {
- X cur_pos = popt();
- X cave[i][j].tptr = cur_pos;
- X t_list[cur_pos] = *t_ptr;
- X lite_spot(i, j);
- X }
- X else
- X {
- X objdes(tmp_str, t_ptr, FALSE);
- X (void) sprintf(out_val, "The %s disappears.", tmp_str);
- X msg_print(out_val);
- X }
- X}
- X
- X/* Throw an object across the dungeon. -RAK- */
- X/* Note: Flasks of oil do fire damage */
- X/* Note: Extra damage and chance of hitting when missiles are used*/
- X/* with correct weapon. I.E. wield bow and throw arrow. */
- Xvoid throw_object()
- X{
- X int item_val, tbth, tpth, tdam, tdis;
- X int y, x, oldy, oldx, cur_dis, dir;
- X int flag, visible;
- X bigvtype out_val, tmp_str;
- X inven_type throw_obj;
- X register cave_type *c_ptr;
- X register monster_type *m_ptr;
- X register int i;
- X char tchar;
- X
- X if (inven_ctr == 0)
- X {
- X msg_print("But you are not carrying anything.");
- X free_turn_flag = TRUE;
- X }
- X else if (get_item(&item_val, "Fire/Throw which one?", 0, inven_ctr-1))
- X {
- X if (get_dir(NULL, &dir))
- X {
- X desc_remain(item_val);
- X if (py.flags.confused > 0)
- X {
- X msg_print("You are confused.");
- X do
- X {
- X dir = randint(9);
- X }
- X while (dir == 5);
- X }
- X inven_throw(item_val, &throw_obj);
- X facts(&throw_obj, &tbth, &tpth, &tdam, &tdis);
- X tchar = throw_obj.tchar;
- X flag = FALSE;
- X y = char_row;
- X x = char_col;
- X oldy = char_row;
- X oldx = char_col;
- X cur_dis = 0;
- X do
- X {
- X (void) mmove(dir, &y, &x);
- X cur_dis++;
- X lite_spot(oldy, oldx);
- X if (cur_dis > tdis) flag = TRUE;
- X c_ptr = &cave[y][x];
- X if ((c_ptr->fval <= MAX_OPEN_SPACE) && (!flag))
- X {
- X if (c_ptr->cptr > 1)
- X {
- X flag = TRUE;
- X m_ptr = &m_list[c_ptr->cptr];
- X tbth = tbth - cur_dis;
- X /* if monster not lit, make it much more difficult to
- X hit, subtract off most bonuses, and reduce bthb
- X depending on distance */
- X if (!m_ptr->ml)
- X tbth = (tbth / (cur_dis+2))
- X - (py.misc.lev *
- X class_level_adj[py.misc.pclass][CLA_BTHB] / 2)
- X - (tpth * (BTH_PLUS_ADJ-1));
- X if (test_hit(tbth, (int)py.misc.lev, tpth,
- X (int)c_list[m_ptr->mptr].ac, CLA_BTHB))
- X {
- X i = m_ptr->mptr;
- X objdes(tmp_str, &throw_obj, FALSE);
- X /* Does the player know what he's fighting? */
- X if (!m_ptr->ml)
- X {
- X (void) sprintf(out_val,
- X "You hear a cry as the %s finds a mark.", tmp_str);
- X visible = FALSE;
- X }
- X else
- X {
- X (void) sprintf(out_val, "The %s hits the %s.",
- X tmp_str, c_list[i].name);
- X visible = TRUE;
- X }
- X msg_print(out_val);
- X tdam = tot_dam(&throw_obj, tdam, i);
- X tdam = critical_blow((int)throw_obj.weight,
- X tpth, tdam, CLA_BTHB);
- X i = mon_take_hit((int)c_ptr->cptr, tdam);
- X if (i >= 0)
- X {
- X if (!visible)
- X msg_print("You have killed something!");
- X else
- X {
- X (void) sprintf(out_val,"You have killed the %s.",
- X c_list[i].name);
- X msg_print(out_val);
- X }
- X prt_experience();
- X }
- X }
- X else
- X drop_throw(oldy, oldx, &throw_obj);
- X }
- X else
- X { /* do not test c_ptr->fm here */
- X if (panel_contains(y, x) && (py.flags.blind < 1)
- X && (c_ptr->tl || c_ptr->pl))
- X {
- X print(tchar, y, x);
- X put_qio(); /* show object moving */
- X }
- X }
- X }
- X else
- X {
- X flag = TRUE;
- X drop_throw(oldy, oldx, &throw_obj);
- X }
- X oldy = y;
- X oldx = x;
- X }
- X while (!flag);
- X }
- X }
- X}
- X
- X
- X/* Make a bash attack on someone. -CJS-
- X Used to be part of bash above. */
- Xstatic void py_bash(y, x)
- Xint y, x;
- X{
- X int monster, k, avg_max_hp, base_tohit;
- X register creature_type *c_ptr;
- X register monster_type *m_ptr;
- X vtype m_name, out_val;
- X
- X monster = cave[y][x].cptr;
- X m_ptr = &m_list[monster];
- X c_ptr = &c_list[m_ptr->mptr];
- X m_ptr->csleep = 0;
- X /* Does the player know what he's fighting? */
- X if (!m_ptr->ml)
- X (void) strcpy(m_name, "it");
- X else
- X (void) sprintf(m_name, "the %s", c_ptr->name);
- X base_tohit = py.stats.use_stat[A_STR] + inventory[INVEN_ARM].weight/2
- X + py.misc.wt/10;
- X if (!m_ptr->ml)
- X base_tohit = (base_tohit / 2) - (py.stats.use_stat[A_DEX]*(BTH_PLUS_ADJ-1))
- X - (py.misc.lev * class_level_adj[py.misc.pclass][CLA_BTH] / 2);
- X
- X if (test_hit(base_tohit, (int)py.misc.lev,
- X (int)py.stats.use_stat[A_DEX], (int)c_ptr->ac, CLA_BTH))
- X {
- X (void) sprintf(out_val, "You hit %s.", m_name);
- X msg_print(out_val);
- X k = pdamroll(inventory[INVEN_ARM].damage);
- X k = critical_blow((int)(inventory[INVEN_ARM].weight / 4
- X + py.stats.use_stat[A_STR]), 0, k, CLA_BTH);
- X k += py.misc.wt/60 + 3;
- X
- X /* See if we done it in. */
- X if (mon_take_hit(monster, k) >= 0)
- X {
- X (void) sprintf(out_val, "You have slain %s.", m_name);
- X msg_print(out_val);
- X prt_experience();
- X }
- X else
- X {
- X m_name[0] = toupper((int)m_name[0]); /* Capitalize */
- X /* Can not stun Balrog */
- X avg_max_hp = (c_ptr->cdefense & CD_MAX_HP ?
- X c_ptr->hd[0] * c_ptr->hd[1] :
- X (c_ptr->hd[0] * (c_ptr->hd[1] + 1)) >> 1);
- X if ((100 + randint(400) + randint(400))
- X > (m_ptr->hp + avg_max_hp))
- X {
- X m_ptr->stunned += randint(3) + 1;
- X if (m_ptr->stunned > 24) m_ptr->stunned = 24;
- X (void) sprintf(out_val, "%s appears stunned!", m_name);
- X }
- X else
- X (void) sprintf(out_val, "%s ignores your bash!", m_name);
- X msg_print(out_val);
- X }
- X }
- X else
- X {
- X (void) sprintf(out_val, "You miss %s.", m_name);
- X msg_print(out_val);
- X }
- X if (randint(150) > py.stats.use_stat[A_DEX])
- X {
- X msg_print("You are off balance.");
- X py.flags.paralysis = 1 + randint(2);
- X }
- X}
- X
- X
- X/* Bash open a door or chest -RAK- */
- X/* Note: Affected by strength and weight of character
- X
- X For a closed door, p1 is positive if locked; negative if
- X stuck. A disarm spell unlocks and unjams doors!
- X
- X For an open door, p1 is positive for a broken door.
- X
- X A closed door can be opened - harder if locked. Any door might
- X be bashed open (and thereby broken). Bashing a door is
- X (potentially) faster! You move into the door way. To open a
- X stuck door, it must be bashed. A closed door can be jammed
- X (which makes it stuck if previously locked).
- X
- X Creatures can also open doors. A creature with open door
- X ability will (if not in the line of sight) move though a
- X closed or secret door with no changes. If in the line of
- X sight, closed door are openned, & secret door revealed.
- X Whether in the line of sight or not, such a creature may
- X unlock or unstick a door.
- X
- X A creature with no such ability will attempt to bash a
- X non-secret door. */
- Xvoid bash()
- X{
- X int y, x, dir, tmp, no_bash;
- X register cave_type *c_ptr;
- X register inven_type *t_ptr;
- X
- X y = char_row;
- X x = char_col;
- X if (get_dir(NULL, &dir))
- X {
- X no_bash = FALSE;
- X (void) mmove(dir, &y, &x);
- X c_ptr = &cave[y][x];
- X if (c_ptr->cptr > 1)
- X {
- X if (py.flags.afraid > 0)
- X msg_print("You are afraid!");
- X else
- X py_bash(y, x);
- X }
- X else if (c_ptr->tptr != 0)
- X {
- X t_ptr = &t_list[c_ptr->tptr];
- X if (t_ptr->tval == TV_CLOSED_DOOR)
- X {
- X count_msg_print("You smash into the door!");
- X tmp = py.stats.use_stat[A_STR] + py.misc.wt / 2;
- X /* Use (roughly) similar method as for monsters. */
- X if (randint(tmp*(20+abs(t_ptr->p1))) < 10*(tmp-abs(t_ptr->p1)))
- X {
- X msg_print("The door crashes open!");
- X invcopy(&t_list[c_ptr->tptr], OBJ_OPEN_DOOR);
- X t_ptr->p1 = randint(2) - 1; /* 50% chance of breaking door */
- X c_ptr->fval = CORR_FLOOR;
- X if (py.flags.confused == 0)
- X move_char(dir, FALSE);
- X else
- X lite_spot(y, x);
- X }
- X else if (randint(150) > py.stats.use_stat[A_DEX])
- X {
- X msg_print("You are off-balance.");
- X py.flags.paralysis = 1 + randint(2);
- X }
- X else if (command_count == 0)
- X msg_print("The door holds firm.");
- X }
- X else if (t_ptr->tval == TV_CHEST)
- X {
- X if (randint(10) == 1)
- X {
- X msg_print("You have destroyed the chest.");
- X msg_print("and its contents!");
- X t_ptr->index = OBJ_RUINED_CHEST;
- X t_ptr->flags = 0;
- X }
- X else if ((CH_LOCKED & t_ptr->flags) && (randint(10) == 1))
- X {
- X msg_print("The lock breaks open!");
- X t_ptr->flags &= ~CH_LOCKED;
- X }
- X else
- X count_msg_print("The chest holds firm.");
- X }
- X else
- X no_bash = TRUE;
- X }
- X else
- X no_bash = TRUE;
- X
- X if (no_bash)
- X {
- X msg_print("I do not see anything you can bash there.");
- X free_turn_flag = TRUE;
- X }
- X }
- X}
- END_OF_FILE
- if test 59994 -ne `wc -c <'source/moria2.c'`; then
- echo shar: \"'source/moria2.c'\" unpacked with wrong size!
- fi
- # end of 'source/moria2.c'
- fi
- echo shar: End of archive 4 \(of 31\).
- cp /dev/null ark4isdone
- 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
-