-+-+-+-+-+-+-+-+ START OF PART 44 -+-+-+-+-+-+-+-+
X print(loc_symbol(y, x), y, x);
X`7D
X
X
X/* Normal movement`09`09`09`09`09*/
X/* When FIND_FLAG, light only permanent features`09*/
Xstatic void sub1_move_light(y1, x1, y2, x2)
Xregister int x1, x2;
Xint y1, y2;
X`7B
X register int i, j;
X register cave_type *c_ptr;
X int tval, top, left, bottom, right;
X
X if (light_flag)
X `7B
X for (i = y1-1; i <= y1+1; i++)`09 /* Turn off lamp light`09*/
X`09for (j = x1-1; j <= x1+1; j++)
X`09 cave`5Bi`5D`5Bj`5D.tl = FALSE;
X if (find_flag && !find_prself)
X`09light_flag = FALSE;
X `7D
X else if (!find_flag `7C`7C find_prself)
X light_flag = TRUE;
X
X for (i = y2-1; i <= y2+1; i++)
X for (j = x2-1; j <= x2+1; j++)
X `7B
X`09c_ptr = &cave`5Bi`5D`5Bj`5D;
X`09/* only light up if normal movement */
X`09if (light_flag)
X`09 c_ptr->tl = TRUE;
X`09if (c_ptr->fval >= MIN_CAVE_WALL)
X`09 c_ptr->pl = TRUE;
X`09else if (!c_ptr->fm && c_ptr->tptr != 0)
X`09 `7B
X`09 tval = t_list`5Bc_ptr->tptr`5D.tval;
X`09 if ((tval >= TV_MIN_VISIBLE) && (tval <= TV_MAX_VISIBLE))
X`09 c_ptr->fm = TRUE;
X`09 `7D
X `7D
X
X /* From uppermost to bottom most lines player was on.`09 */
X if (y1 < y2)
X `7B
X top = y1 - 1;
X bottom = y2 + 1;
X `7D
X else
X `7B
X top = y2 - 1;
X bottom = y1 + 1;
X `7D
X if (x1 < x2)
X `7B
X left = x1 - 1;
X right = x2 + 1;
X `7D
X else
X `7B
X left = x2 - 1;
X right = x1 + 1;
X `7D
X for (i = top; i <= bottom; i++)
X for (j = left; j <= right; j++) /* Leftmost to rightmost do*/
X print(loc_symbol(i, j), i, j);
X`7D
X
X
X/* When blinded, move only the player symbol.`09`09*/
X/* With no light, movement becomes involved.`09`09*/
Xstatic void sub3_move_light(y1, x1, y2, x2)
Xregister int y1, x1;
Xint y2, x2;
X`7B
X register int i, j;
X
X if (light_flag)
X `7B
X for (i = y1-1; i <= y1+1; i++)
X`09for (j = x1-1; j <= x1+1; j++)
X`09 `7B
X`09 cave`5Bi`5D`5Bj`5D.tl = FALSE;
X`09 print(loc_symbol(i, j), i, j);
X`09 `7D
X light_flag = FALSE;
X `7D
X else if (!find_flag `7C`7C find_prself)
X print(loc_symbol(y1, x1), y1, x1);
X
X if (!find_flag `7C`7C find_prself)
X print('@', y2, x2);
X`7D
X
X
X/* Package for moving the character's light about the screen`09 */
X/* Four cases : Normal, Finding, Blind, and Nolight`09 -RAK-`09 */
Xvoid move_light(y1, x1, y2, x2)
Xint y1, x1, y2, x2;
X`7B
X if (py.flags.blind > 0 `7C`7C !player_light)
X sub3_move_light(y1, x1, y2, x2);
X else
X sub1_move_light(y1, x1, y2, x2);
X`7D
X
X
X/* Something happens to disturb the player.`09`09-CJS-
X The first arg indicates a major disturbance, which affects search.
X The second arg indicates a light change. */
Xvoid disturb(s, l)
Xint s, l;
X`7B
X command_count = 0;
X if (s && (py.flags.status & PY_SEARCH))
X search_off();
X if (py.flags.rest != 0)
X rest_off();
X if (l `7C`7C find_flag)
X `7B
X find_flag = FALSE;
X check_view();
X `7D
X flush();
X`7D
X
X
X/* Search Mode enhancement`09`09`09`09-RAK-`09*/
Xvoid search_on()
X`7B
X change_speed(1);
X py.flags.status `7C= PY_SEARCH;
X prt_state();
X prt_speed();
X py.flags.food_digested++;
X`7D
X
Xvoid search_off()
X`7B
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X check_view();
X change_speed(-1);
X#ifdef ATARIST_MWC
X py.flags.status &= `7E(holder = PY_SEARCH);
X#else
X py.flags.status &= `7EPY_SEARCH;
X#endif
X prt_state();
X prt_speed();
X py.flags.food_digested--;
X`7D
X
X
X/* Resting allows a player to safely restore his hp`09-RAK-`09*/
Xvoid rest()
X`7B
X int rest_num;
X vtype rest_str;
X
X if (command_count > 0)
X `7B
X rest_num = command_count;
X command_count = 0;
X `7D
X else
X `7B
X prt("Rest for how long? ", 0, 0);
X rest_num = 0;
X if (get_string(rest_str, 0, 19, 5))
X`09`7B
X`09 if (rest_str`5B0`5D == '*')
X`09 rest_num = -MAX_SHORT;
X`09 else
X`09 rest_num = atoi(rest_str);
X`09`7D
X `7D
X /* check for reasonable value, must be positive number in range of a
X short, or must be -MAX_SHORT */
X if ((rest_num == -MAX_SHORT)
X `7C`7C (rest_num > 0) && (rest_num < MAX_SHORT))
X `7B
X if (py.flags.status & PY_SEARCH)
X`09search_off();
X py.flags.rest = rest_num;
X py.flags.status `7C= PY_REST;
X prt_state();
X py.flags.food_digested--;
X prt ("Press any key to stop resting...", 0, 0);
X put_qio();
X `7D
X else
X `7B
X if (rest_num != 0)
X`09msg_print ("Invalid rest count.");
X erase_line(MSG_LINE, 0);
X free_turn_flag = TRUE;
X `7D
X`7D
X
Xvoid rest_off()
X`7B
X#ifdef ATARIST_MWC
X int32u holder;
X#endif
X
X py.flags.rest = 0;
X#ifdef ATARIST_MWC
X py.flags.status &= `7E(holder = PY_REST);
X#else
X py.flags.status &= `7EPY_REST;
X#endif
X prt_state();
X msg_print(CNIL); /* flush last message, or delete "press any key" message
V */
X py.flags.food_digested++;
X`7D
X
X
X/* Attacker's level and plusses, defender's AC`09`09-RAK-`09*/
Xint test_hit(bth, level, pth, ac, attack_type)
Xint bth, level, pth, ac, attack_type;
X`7B
X register int i, die;
X
X disturb (1, 0);
X i = bth + pth * BTH_PLUS_ADJ
X + (level * class_level_adj`5Bpy.misc.pclass`5D`5Battack_type`5D);
X /* pth could be less than 0 if player wielding weapon too heavy for him */
X /* always miss 1 out of 20, always hit 1 out of 20 */
X die = randint (20);
X if ((die != 1) && ((die == 20)
X`09`09 `7C`7C ((i > 0) && (randint (i) > ac)))) /* normal hit */
X return TRUE;
X else
X return FALSE;
X`7D
X
X
X/* Decreases players hit points and sets death flag if necessary*/
X/*`09`09`09`09`09`09`09 -RAK-`09 */
Xvoid take_hit(damage, hit_from)
Xint damage;
Xchar *hit_from;
X`7B
X if (py.flags.invuln > 0) damage = 0;
X py.misc.chp -= damage;
X if (py.misc.chp < 0)
X `7B
X if (!death)
X`09`7B
X`09 death = TRUE;
X`09 (void) strcpy(died_from, hit_from);
X`09 total_winner = FALSE;
X`09`7D
X new_level_flag = TRUE;
X `7D
X else
X prt_chp();
X`7D
$ CALL UNPACK MORIA1.C;1 1448022143
$ create 'f'
X/* source/moria2.c: misc code, mainly handles player movement, inventory, et
Vc
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#include
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`09`09-RAK-`09*/
X/* Note: Secret doors are handled here`09`09`09`09 */
Xvoid change_trap(y, x)
Xregister int y, x;
X`7B
X register cave_type *c_ptr;
X register inven_type *t_ptr;
X
X c_ptr = &cave`5By`5D`5Bx`5D;
X t_ptr = &t_list`5Bc_ptr->tptr`5D;
X if (t_ptr->tval == TV_INVIS_TRAP)
X `7B
X t_ptr->tval = TV_VIS_TRAP;
X lite_spot(y, x);
X `7D
X else if (t_ptr->tval == TV_SECRET_DOOR)
X `7B
X /* change secret door to closed door */
X t_ptr->index = OBJ_CLOSED_DOOR;
X t_ptr->tval = object_list`5BOBJ_CLOSED_DOOR`5D.tval;
X t_ptr->tchar = object_list`5BOBJ_CLOSED_DOOR`5D.tchar;
X lite_spot(y, x);
X `7D
X`7D
X
X
X/* Searches for hidden things.`09`09`09-RAK-`09*/
Xvoid search(y, x, chance)
Xint y, x, chance;
X`7B
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) `7C`7C 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)`09/* always in_bounds here */
X`09`7B
X`09 c_ptr = &cave`5Bi`5D`5Bj`5D;
X`09 /* Search for hidden objects`09`09 */
X`09 if (c_ptr->tptr != 0)
X`09 `7B
X`09 t_ptr = &t_list`5Bc_ptr->tptr`5D;
X`09 /* Trap on floor?`09`09 */
X`09 if (t_ptr->tval == TV_INVIS_TRAP)
X`09`09`7B
X`09`09 objdes(tmp_str2, t_ptr, TRUE);
X`09`09 (void) sprintf(tmp_str,"You have found %s",tmp_str2);
X`09`09 msg_print(tmp_str);
X`09`09 change_trap(i, j);
X`09`09 end_find();
X`09`09`7D
X`09 /* Secret door?`09`09 */
X`09 else if (t_ptr->tval == TV_SECRET_DOOR)
X`09`09`7B
X`09`09 msg_print("You have found a secret door.");
X`09`09 change_trap(i, j);
X`09`09 end_find();
X`09`09`7D
X`09 /* Chest is trapped?`09 */
X`09 else if (t_ptr->tval == TV_CHEST)
X`09`09`7B
X`09`09 /* mask out the treasure bits */
X`09`09 if ((t_ptr->flags & CH_TRAPPED) > 1)
X`09`09 if (!known2_p(t_ptr))
X`09`09 `7B
X`09`09`09known2(t_ptr);
X`09`09`09msg_print("You have discovered a trap on the chest!");
X`09`09 `7D
X`09`09 else
X`09`09 msg_print("The chest is trapped!");
X`09`09`7D
X`09 `7D
X`09`7D
X`7D
X
X
X/* The running algorithm:`09`09`09-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`09find_openarea`09 You are in the open on at least one
X`09`09`09 side.
X`09find_breakleft`09 You have a wall on the left, and will
X`09`09`09 stop if it opens
X`09find_breakright`09 You have a wall on the right, and will
X`09`09`09 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`09 LL`09`09L
X`09@.`09 L.R
X`09 RR`09 @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`09 #.#
X`09 ##.##
X`09 .@...
X`09 ##.##
X`09 #.#
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`09#@`09 1
X`09########### ######
X`092`09 #
X`09#############
X`09#
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 ...!`09 ...`09 EG Moving from 1 to 2.
X .12!`09 .1.!`09`09 . means previously adjacent
X ...!`09 ..2!`09`09 ! means newly adjacent
X`09`09 !!!
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`09 .X
X`09 @.?
X`09 #?
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
+-+-+-+-+-+-+-+- END OF PART 44 +-+-+-+-+-+-+-+-