-+-+-+-+-+-+-+-+ START OF PART 45 -+-+-+-+-+-+-+-+ X/* The cycle lists the directions in anticlockwise order, for`09-CJS- X over two complete cycles. The chome array maps a direction on X to its position in the cycle. X*/ Xstatic int cycle`5B`5D = `7B 1, 2, 3, 6, 9, 8, 7, 4, 1, 2, 3, 6, 9, 8, 7, 4, V 1 `7D; Xstatic int chome`5B`5D = `7B -1, 8, 9, 10, 7, -1, 11, 6, 5, 4 `7D; 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`7B 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 `7B 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`09`7B X`09 i = chome`5Bdir`5D; X`09 deepleft = deepright = FALSE; X`09 shortright = shortleft = FALSE; X`09 if (see_wall(cycle`5Bi+1`5D, char_row, char_col)) X`09 `7B X`09 find_breakleft = TRUE; X`09 shortleft = TRUE; X`09 `7D X`09 else if (see_wall(cycle`5Bi+1`5D, row, col)) X`09 `7B X`09 find_breakleft = TRUE; X`09 deepleft = TRUE; X`09 `7D X`09 if (see_wall(cycle`5Bi-1`5D, char_row, char_col)) X`09 `7B X`09 find_breakright = TRUE; X`09 shortright = TRUE; X`09 `7D X`09 else if (see_wall(cycle`5Bi-1`5D, row, col)) X`09 `7B X`09 find_breakright = TRUE; X`09 deepright = TRUE; X`09 `7D X`09 if (find_breakleft && find_breakright) X`09 `7B X`09 find_openarea = FALSE; X`09 if (dir & 1) X`09`09`7B`09`09/* a hack to allow angled corridor entry */ X`09`09 if (deepleft && !deepright) X`09`09 find_prevdir = cycle`5Bi-1`5D; X`09`09 else if (deepright && !deepleft) X`09`09 find_prevdir = cycle`5Bi+1`5D; X`09`09`7D X`09 /* else if there is a wall two spaces ahead and seem to be in a X`09`09 corridor, then force a turn into the side corridor, must X`09`09 be moving straight into a corridor here */ X`09 else if (see_wall(cycle`5Bi`5D, row, col)) X`09`09`7B X`09`09 if (shortleft && !shortright) X`09`09 find_prevdir = cycle`5Bi-2`5D; X`09`09 else if (shortright && !shortleft) X`09`09 find_prevdir = cycle`5Bi+2`5D; X`09`09`7D X`09 `7D X`09 else X`09 find_openarea = TRUE; X`09`7D X `7D 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 V. 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`7D X Xvoid find_run() X`7B X /* prevent infinite loops in find mode, will stop after moving 100 times * V/ X if (find_flag++ > 100) X `7B X msg_print("You stop running to catch your breath."); X end_find(); X `7D X else X move_char(find_direction, TRUE); X`7D X X/* Switch off the run flag - and get the light correct. -CJS- */ Xvoid end_find() X`7B X if (find_flag) X `7B X find_flag = FALSE; X move_light(char_row, char_col, char_row, char_col); X `7D X`7D X X/* Do we see a wall? Used in running.`09`09-CJS- */ Xstatic int see_wall(dir, y, x) Xint dir, y, x; X`7B X char c; X X if (!mmove(dir, &y, &x))`09/* check to see if movement there possible */ X return TRUE; X#ifdef MSDOS X else if ((c = loc_symbol(y, x)) == wallsym `7C`7C c == '%') X#else X#ifdef ATARI_ST X else if ((c = loc_symbol(y, x)) == (unsigned char)240 `7C`7C c == '%') X#else X else if ((c = loc_symbol(y, x)) == '#' `7C`7C c == '%') X#endif X#endif X return TRUE; X else X return FALSE; X`7D X X/* Do we see anything? Used in running.`09`09-CJS- */ Xstatic int see_nothing(dir, y, x) Xint dir, y, x; X`7B X if (!mmove(dir, &y, &x))`09/* 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`7D 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`7B 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 `7B 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`09`7B X`09 newdir = cycle`5Bchome`5Bdir`5D+i`5D; X`09 row = y; X`09 col = x; X`09 if (mmove(newdir, &row, &col)) X`09 `7B X`09 /* Objects player can see (Including doors?) cause a stop. */ X`09 c_ptr = &cave`5Brow`5D`5Bcol`5D; X`09 if (player_light `7C`7C c_ptr->tl `7C`7C c_ptr->pl `7C`7C c_ptr->fm V) X`09`09`7B X`09`09 if (c_ptr->tptr != 0) X`09`09 `7B X`09`09 t = t_list`5Bc_ptr->tptr`5D.tval; X`09`09 if (t != TV_INVIS_TRAP && t != TV_SECRET_DOOR X`09`09`09 && (t != TV_OPEN_DOOR `7C`7C !find_ignore_doors)) X`09`09`09`7B X`09`09`09 end_find(); X`09`09`09 return; X`09`09`09`7D X`09`09 `7D X`09`09 /* Also Creatures`09`09*/ X`09`09 /* the monster should be visible since update_mon() checks X`09`09 for the special case of being in find mode */ X`09`09 if (c_ptr->cptr > 1 && m_list`5Bc_ptr->cptr`5D.ml) X`09`09 `7B X`09`09 end_find(); X`09`09 return; X`09`09 `7D X`09`09 inv = FALSE; X`09`09`7D X`09 else X`09`09inv = TRUE;`09/* Square unseen. Treat as open. */ X X`09 if (c_ptr->fval <= MAX_OPEN_SPACE `7C`7C inv) X`09`09`7B X`09`09 if (find_openarea) X`09`09 `7B X`09`09 /* Have we found a break? */ X`09`09 if (i < 0) X`09`09`09`7B X`09`09`09 if (find_breakright) X`09`09`09 `7B X`09`09`09 end_find(); X`09`09`09 return; X`09`09`09 `7D X`09`09`09`7D X`09`09 else if (i > 0) X`09`09`09`7B X`09`09`09 if (find_breakleft) X`09`09`09 `7B X`09`09`09 end_find(); X`09`09`09 return; X`09`09`09 `7D X`09`09`09`7D X`09`09 `7D X`09`09 else if (option == 0) X`09`09 option = newdir;`09/* The first new direction. */ X`09`09 else if (option2 != 0) X`09`09 `7B X`09`09 end_find();`09/* Three new directions. STOP. */ X`09`09 return; X`09`09 `7D X`09`09 else if (option != cycle`5Bchome`5Bdir`5D+i-1`5D) X`09`09 `7B X`09`09 end_find();`09/* If not adjacent to prev, STOP */ X`09`09 return; X`09`09 `7D X`09`09 else X`09`09 `7B X`09`09 /* Two adjacent choices. Make option2 the diagonal, X`09`09`09 and remember the other diagonal adjacent to the first X`09`09`09 option. */ X`09`09 if ((newdir & 1) == 1) X`09`09`09`7B X`09`09`09 check_dir = cycle`5Bchome`5Bdir`5D+i-2`5D; X`09`09`09 option2 = newdir; X`09`09`09`7D X`09`09 else X`09`09`09`7B X`09`09`09 check_dir = cycle`5Bchome`5Bdir`5D+i+1`5D; X`09`09`09 option2 = option; X`09`09`09 option = newdir; X`09`09`09`7D X`09`09 `7D X`09`09`7D X`09 else if (find_openarea) X`09`09`7B X`09`09 /* We see an obstacle. In open area, STOP if on a side X`09`09 previously open. */ X`09`09 if (i < 0) X`09`09 `7B X`09`09 if (find_breakleft) X`09`09`09`7B X`09`09`09 end_find(); X`09`09`09 return; X`09`09`09`7D X`09`09 find_breakright = TRUE; X`09`09 `7D X`09`09 else if (i > 0) X`09`09 `7B X`09`09 if (find_breakright) X`09`09`09`7B X`09`09`09 end_find(); X`09`09`09 return; X`09`09`09`7D X`09`09 find_breakleft = TRUE; X`09`09 `7D X`09`09`7D X`09 `7D X`09`7D X X if (find_openarea == FALSE) X`09`7B`09/* choose a direction. */ X`09 if (option2 == 0 `7C`7C (find_examine && !find_cut)) X`09 `7B X`09 /* There is only one option, or if two, then we always examine X`09`09 potential corners and never cur known corners, so you step X`09`09 into the straight option. */ X`09 if (option != 0) X`09`09find_direction = option; X`09 if (option2 == 0) X`09`09find_prevdir = option; X`09 else X`09`09find_prevdir = option2; X`09 `7D X`09 else X`09 `7B X`09 /* Two options! */ X`09 row = y; X`09 col = x; X`09 (void) mmove(option, &row, &col); X`09 if (!see_wall(option, row, col) X`09`09 `7C`7C !see_wall(check_dir, row, col)) X`09`09`7B X`09`09 /* Don't see that it is closed off. This could be a X`09`09 potential corner or an intersection. */ X`09`09 if (find_examine && see_nothing(option, row, col) X`09`09 && see_nothing(option2, row, col)) X`09`09 /* Can not see anything ahead and in the direction we are X`09`09 turning, assume that it is a potential corner. */ X`09`09 `7B X`09`09 find_direction = option; X`09`09 find_prevdir = option2; X`09`09 `7D X`09`09 else X`09`09 /* STOP: we are next to an intersection or a room */ X`09`09 end_find(); X`09`09`7D X`09 else if (find_cut) X`09`09`7B X`09`09 /* This corner is seen to be enclosed; we cut the corner. */ X`09`09 find_direction = option2; X`09`09 find_prevdir = option2; X`09`09`7D X`09 else X`09`09`7B X`09`09 /* This corner is seen to be enclosed, and we deliberately X`09`09 go the long way. */ X`09`09 find_direction = option; X`09`09 find_prevdir = option2; X`09`09`7D X`09 `7D X`09`7D X `7D X`7D X X X/* AC gets worse`09`09`09`09`09-RAK-`09*/ X/* Note: This routine affects magical AC bonuses so that stores`09 */ X/*`09 can detect the damage.`09`09`09`09`09 */ Xint minus_ac(typ_dam) Xint32u typ_dam; X`7B X register int i, j; X int tmp`5B6`5D, minus; X register inven_type *i_ptr; X bigvtype out_val, tmp_str; X X i = 0; X if (inventory`5BINVEN_BODY`5D.tval != TV_NOTHING) X `7B X tmp`5Bi`5D = INVEN_BODY; X i++; X `7D X if (inventory`5BINVEN_ARM`5D.tval != TV_NOTHING) X `7B X tmp`5Bi`5D = INVEN_ARM; X i++; X `7D X if (inventory`5BINVEN_OUTER`5D.tval != TV_NOTHING) X `7B X tmp`5Bi`5D = INVEN_OUTER; X i++; X `7D X if (inventory`5BINVEN_HANDS`5D.tval != TV_NOTHING) X `7B X tmp`5Bi`5D = INVEN_HANDS; X i++; X `7D X if (inventory`5BINVEN_HEAD`5D.tval != TV_NOTHING) X `7B X tmp`5Bi`5D = INVEN_HEAD; X i++; X `7D X /* also affect boots */ X if (inventory`5BINVEN_FEET`5D.tval != TV_NOTHING) X `7B X tmp`5Bi`5D = INVEN_FEET; X i++; X `7D X minus = FALSE; X if (i > 0) X `7B X j = tmp`5Brandint(i) - 1`5D; X i_ptr = &inventory`5Bj`5D; X if (i_ptr->flags & typ_dam) X`09`7B X`09 objdes(tmp_str, &inventory`5Bj`5D, FALSE); X`09 (void) sprintf(out_val, "Your %s resists damage!", tmp_str); X`09 msg_print(out_val); X`09 minus = TRUE; X`09`7D X else if ((i_ptr->ac+i_ptr->toac) > 0) X`09`7B X`09 objdes(tmp_str, &inventory`5Bj`5D, FALSE); X`09 (void) sprintf(out_val, "Your %s is damaged!", tmp_str); X`09 msg_print(out_val); X`09 i_ptr->toac--; X`09 calc_bonuses(); X`09 minus = TRUE; X`09`7D X `7D X return(minus); X`7D X X X/* Corrode the unsuspecting person's armor`09`09 -RAK-`09 */ Xvoid corrode_gas(kb_str) Xchar *kb_str; X`7B 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`7D X X X/* Poison gas the idiot.`09`09`09`09-RAK-`09*/ Xvoid poison_gas(dam, kb_str) Xint dam; Xchar *kb_str; X`7B X take_hit(dam, kb_str); X py.flags.poisoned += 12 + randint(dam); X`7D X X X/* Burn the fool up.`09`09`09`09`09-RAK-`09*/ Xvoid fire_dam(dam, kb_str) Xint dam; Xchar *kb_str; X`7B 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`7D X X X/* Freeze him to death.`09`09`09`09-RAK-`09*/ Xvoid cold_dam(dam, kb_str) Xint dam; Xchar *kb_str; X`7B 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`7D X X X/* Lightning bolt the sucker away.`09`09`09-RAK-`09*/ Xvoid light_dam(dam, kb_str) Xint dam; Xchar *kb_str; X`7B 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`7D X X X/* Throw acid on the hapless victim`09`09`09-RAK-`09*/ Xvoid acid_dam(dam, kb_str) Xint dam; Xchar *kb_str; X`7B 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`7D $ CALL UNPACK MORIA2.C;1 773170235 $ create 'f' X/* source/moria3.c: misc code, mainly to handle player commands X X Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke X X This software may be copied and distributed for educational, research, an Vd X not for profit purposes provided that this copyright and statement are X included in all such copies. */ X X#ifdef __TURBOC__ X#include`09 X#endif X X#include "config.h" X#include "constant.h" X#include "types.h" X#include "externs.h" X X#ifdef USG X#ifndef ATARIST_MWC X#include X#endif X#else X#include X#endif X X#if defined(LINT_ARGS) Xstatic void hit_trap(int, int); Xstatic void carry(int, int, int); +-+-+-+-+-+-+-+- END OF PART 45 +-+-+-+-+-+-+-+-