[comp.sources.games] v01i013: rogue - a rogue 5.3 clone, Part03/05

games-request@tekred.TEK.COM (05/11/87)

Submitted by: Tim Stoehr <tims@zues.TEK.COM>
Comp.sources.games: Volume 1, Issue 13
Archive-name: rogue/Part03

#! /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 3 (of 5)."
# Contents:  move.c rogue.h save.c score.c spec_hit.c
# Wrapped by billr@tekred on Mon May 11 12:19:19 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f move.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"move.c\"
else
echo shar: Extracting \"move.c\" \(9678 characters\)
sed "s/^X//" >move.c <<'END_OF_move.c'
X/*
X * move.c
X *
X * This source herein may be modified and/or distributed by anybody who
X * so desires, with the following restrictions:
X *    1.)  No portion of this notice shall be removed.
X *    2.)  Credit shall not be taken for the creation of this source.
X *    3.)  This code is not to be traded, sold, or used for personal
X *         gain or profit.
X *
X */
X
X#ifndef CURSES
X#include <curses.h>
X#endif CURSES
X#include "rogue.h"
X
Xshort m_moves = 0;
Xboolean jump = 1;
Xchar *you_can_move_again = "you can move again";
X
Xextern short cur_room, halluc, blind, levitate;
Xextern short cur_level, max_level;
Xextern short bear_trap, haste_self, confused;
Xextern short e_rings, regeneration, auto_search;
Xextern char hunger_str[];
Xextern boolean being_held, interrupted, r_teleport;
X
Xone_move_rogue(dirch, pickup)
Xshort dirch, pickup;
X{
X	short row, col;
X	object *obj;
X	char desc[DCOLS];
X	short n, status;
X
X	row = rogue.row;
X	col = rogue.col;
X
X	if (confused) {
X		dirch = gr_dir();
X	}
X	get_dir_rc(dirch, &row, &col, 1);
X
X	if (!can_move(rogue.row, rogue.col, row, col)) {
X		return(MOVE_FAILED);
X	}
X	if (being_held || bear_trap) {
X		if (!(dungeon[row][col] & MONSTER)) {
X			if (being_held) {
X				message("you are being held", 1);
X			} else {
X				message("you are still stuck in the bear trap", 0);
X				(void) reg_move();
X			}
X			return(MOVE_FAILED);
X		}
X	}
X	if (r_teleport) {
X		if (rand_percent(R_TELE_PERCENT)) {
X			tele();
X			return(STOPPED_ON_SOMETHING);
X		}
X	}
X	if (dungeon[row][col] & MONSTER) {
X		rogue_hit(object_at(&level_monsters, row, col), 0);
X		(void) reg_move();
X		return(MOVE_FAILED);
X	}
X	if (dungeon[row][col] & DOOR) {
X		if (cur_room == PASSAGE) {
X			cur_room = get_room_number(row, col);
X			light_up_room(cur_room);
X			wake_room(cur_room, 1, row, col);
X		} else {
X			light_passage(row, col);
X		}
X	} else if ((dungeon[rogue.row][rogue.col] & DOOR) &&
X		   (dungeon[row][col] & TUNNEL)) {
X		light_passage(row, col);
X		wake_room(cur_room, 0, rogue.row, rogue.col);
X		darken_room(cur_room);
X		cur_room = PASSAGE;
X	} else if (dungeon[row][col] & TUNNEL) {
X			light_passage(row, col);
X	}
X	mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
X	mvaddch(row, col, rogue.fchar);
X
X	if (!jump) {
X		refresh();
X	}
X	rogue.row = row;
X	rogue.col = col;
X	if (dungeon[row][col] & OBJECT) {
X		if (levitate && pickup) {
X			return(STOPPED_ON_SOMETHING);
X		}
X		if (pickup && !levitate) {
X			if (obj = pick_up(row, col, &status)) {
X				get_desc(obj, desc);
X				if (obj->what_is == GOLD) {
X					free_object(obj);
X					goto NOT_IN_PACK;
X				}
X			} else if (!status) {
X				goto MVED;
X			} else {
X				goto MOVE_ON;
X			}
X		} else {
XMOVE_ON:
X			obj = object_at(&level_objects, row, col);
X			(void) strcpy(desc, "moved onto ");
X			get_desc(obj, desc+11);
X			goto NOT_IN_PACK;
X		}
X		n = strlen(desc);
X		desc[n] = '(';
X		desc[n+1] = obj->ichar;
X		desc[n+2] = ')';
X		desc[n+3] = 0;
XNOT_IN_PACK:
X		message(desc, 1);
X		(void) reg_move();
X		return(STOPPED_ON_SOMETHING);
X	}
X	if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) {
X		if ((!levitate) && (dungeon[row][col] & TRAP)) {
X			trap_player(row, col);
X		}
X		(void) reg_move();
X		return(STOPPED_ON_SOMETHING);
X	}
XMVED:	if (reg_move()) {			/* fainted from hunger */
X			return(STOPPED_ON_SOMETHING);
X	}
X	return((confused ? STOPPED_ON_SOMETHING : MOVED));
X}
X
Xmultiple_move_rogue(dirch)
X{
X	short row, col;
X	short m;
X
X	switch(dirch) {
X	case '\010':
X	case '\012':
X	case '\013':
X	case '\014':
X	case '\031':
X	case '\025':
X	case '\016':
X	case '\002':
X		do {
X			row = rogue.row;
X			col = rogue.col;
X			if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) ||
X				(m == STOPPED_ON_SOMETHING) ||
X				interrupted) {
X				break;
X			}
X		} while (!next_to_something(row, col));
X		break;
X	case 'H':
X	case 'J':
X	case 'K':
X	case 'L':
X	case 'B':
X	case 'Y':
X	case 'U':
X	case 'N':
X		while (	(!interrupted) &&
X				(one_move_rogue((dirch + 32), 1) == MOVED)) ;
X		break;
X	}
X}
X
Xis_passable(row, col)
Xregister row, col;
X{
X	if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) ||
X		(col > (DCOLS-1))) {
X		return(0);
X	}
X	if (dungeon[row][col] & HIDDEN) {
X		return((dungeon[row][col] & TRAP) ? 1 : 0);
X	}
X	return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP));
X}
X
Xnext_to_something(drow, dcol)
Xregister drow, dcol;
X{
X	short i, j, i_end, j_end, row, col;
X	short pass_count = 0;
X	unsigned short s;
X
X	if (confused) {
X		return(1);
X	}
X	if (blind) {
X		return(0);
X	}
X	i_end = (rogue.row < (DROWS-2)) ? 1 : 0;
X	j_end = (rogue.col < (DCOLS-1)) ? 1 : 0;
X
X	for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
X		for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) {
X			if ((i == 0) && (j == 0)) {
X				continue;
X			}
X			if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) {
X				continue;
X			}
X			row = rogue.row + i;
X			col = rogue.col + j;
X			s = dungeon[row][col];
X			if (s & HIDDEN) {
X				continue;
X			}
X			/* If the rogue used to be right, up, left, down, or right of
X			 * row,col, and now isn't, then don't stop */
X			if (s & (MONSTER | OBJECT | STAIRS)) {
X				if (((row == drow) || (col == dcol)) &&
X					(!((row == rogue.row) || (col == rogue.col)))) {
X					continue;
X				}
X				return(1);
X			}
X			if (s & TRAP) {
X				if (!(s & HIDDEN)) {
X					if (((row == drow) || (col == dcol)) &&
X						(!((row == rogue.row) || (col == rogue.col)))) {
X						continue;
X					}
X					return(1);
X				}
X			}
X			if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) {
X				if (++pass_count > 1) {
X					return(1);
X				}
X			}
X			if ((s & DOOR) && ((i == 0) || (j == 0))) {
X					return(1);
X			}
X		}
X	}
X	return(0);
X}
X
Xcan_move(row1, col1, row2, col2) 
X{
X	if (!is_passable(row2, col2)) {
X		return(0);
X	}
X	if ((row1 != row2) && (col1 != col2)) {
X		if ((dungeon[row1][col1]&DOOR)||(dungeon[row2][col2]&DOOR)) {
X			return(0);
X		}
X		if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) {
X			return(0);
X		}
X	}
X	return(1);
X}
X
Xmove_onto()
X{
X	short ch;
X	boolean first_miss = 1;
X
X	while (!is_direction(ch = rgetchar())) {
X		sound_bell();
X		if (first_miss) {
X			message("direction? ", 0);
X			first_miss = 0;
X		}
X	}
X	check_message();
X	if (ch != CANCEL) {
X		(void) one_move_rogue(ch, 0);
X	}
X}
X
Xboolean
Xis_direction(c)
X{
X	return(
X		(c == 'h') ||
X		(c == 'j') ||
X		(c == 'k') ||
X		(c == 'l') ||
X		(c == 'b') ||
X		(c == 'y') ||
X		(c == 'u') ||
X		(c == 'n') ||
X		(c == CANCEL)
X		);
X}
X
Xboolean
Xcheck_hunger(messages_only)
Xboolean messages_only;
X{
X	register short i, n;
X	boolean fainted = 0;
X
X	if (rogue.moves_left == HUNGRY) {
X		(void) strcpy(hunger_str, "hungry");
X		message(hunger_str, 0);
X		print_stats(STAT_HUNGER);
X	}
X	if (rogue.moves_left == WEAK) {
X		(void) strcpy(hunger_str, "weak");
X		message(hunger_str, 1);
X		print_stats(STAT_HUNGER);
X	}
X	if (rogue.moves_left <= FAINT) {
X		if (rogue.moves_left == FAINT) {
X			(void) strcpy(hunger_str, "faint");
X			message(hunger_str, 1);
X			print_stats(STAT_HUNGER);
X		}
X		n = get_rand(0, (FAINT - rogue.moves_left));
X		if (n > 0) {
X			fainted = 1;
X			if (rand_percent(40)) {
X				rogue.moves_left++;
X			}
X			message("you faint", 1);
X			for (i = 0; i < n; i++) {
X				if (coin_toss()) {
X					mv_mons();
X				}
X			}
X			message(you_can_move_again, 1);
X		}
X	}
X	if (messages_only) {
X		return(fainted);
X	}
X	if (rogue.moves_left <= STARVE) {
X		killed_by((object *) 0, STARVATION);
X	}
X
X	switch(e_rings) {
X	/*case -2:
X		Subtract 0, i.e. do nothing.
X		break;*/
X	case -1:
X		rogue.moves_left -= (rogue.moves_left % 2);
X		break;
X	case 0:
X		rogue.moves_left--;
X		break;
X	case 1:
X		rogue.moves_left--;
X		(void) check_hunger(1);
X		rogue.moves_left -= (rogue.moves_left % 2);
X		break;
X	case 2:
X		rogue.moves_left--;
X		(void) check_hunger(1);
X		rogue.moves_left--;
X		break;
X	}
X	return(fainted);
X}
X
Xboolean
Xreg_move()
X{
X	boolean fainted;
X
X	if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) {
X		fainted = check_hunger(0);
X	} else {
X		fainted = 0;
X	}
X
X	mv_mons();
X
X	if (++m_moves >= 120) {
X		m_moves = 0;
X		wanderer();
X	}
X	if (halluc) {
X		if (!(--halluc)) {
X			unhallucinate();
X		} else {
X			hallucinate();
X		}
X	}
X	if (blind) {
X		if (!(--blind)) {
X			unblind();
X		}
X	}
X	if (confused) {
X		if (!(--confused)) {
X			unconfuse();
X		}
X	}
X	if (bear_trap) {
X		bear_trap--;
X	}
X	if (levitate) {
X		if (!(--levitate)) {
X			message("you float gently to the ground", 1);
X			if (dungeon[rogue.row][rogue.col] & TRAP) {
X				trap_player(rogue.row, rogue.col);
X			}
X		}
X	}
X	if (haste_self) {
X		if (!(--haste_self)) {
X			message("you feel yourself slowing down", 0);
X		}
X	}
X	heal();
X	if (auto_search > 0) {
X		search(auto_search, auto_search);
X	}
X	return(fainted);
X}
X
Xrest(count)
X{
X	int i;
X
X	interrupted = 0;
X
X	for (i = 0; i < count; i++) {
X		if (interrupted) {
X			break;
X		}
X		(void) reg_move();
X	}
X}
X
Xgr_dir()
X{
X	short d;
X
X	d = get_rand(1, 8);
X
X	switch(d) {
X		case 1:
X			d = 'j';
X		case 2:
X			d = 'k';
X		case 3:
X			d = 'l';
X		case 4:
X			d = 'h';
X		case 5:
X			d = 'y';
X		case 6:
X			d = 'u';
X		case 7:
X			d = 'b';
X		case 8:
X			d = 'n';
X	}
X	return(d);
X}
X
Xheal()
X{
X	static short heal_exp = -1, n, c = 0;
X	static boolean alt;
X
X	if (rogue.hp_current == rogue.hp_max) {
X		c = 0;
X		return;
X	}
X	if (rogue.exp != heal_exp) {
X		heal_exp = rogue.exp;
X
X		switch(heal_exp) {
X		case 1:
X			n = 20;
X			break;
X		case 2:
X			n = 18;
X			break;
X		case 3:
X			n = 17;
X			break;
X		case 4:
X			n = 14;
X			break;
X		case 5:
X			n = 13;
X			break;
X		case 6:
X			n = 10;
X			break;
X		case 7:
X			n = 9;
X			break;
X		case 8:
X			n = 8;
X			break;
X		case 9:
X			n = 7;
X			break;
X		case 10:
X			n = 4;
X			break;
X		case 11:
X			n = 3;
X			break;
X		case 12:
X		default:
X			n = 2;
X		}
X	}
X	if (++c >= n) {
X		c = 0;
X		rogue.hp_current++;
X		if (alt = !alt) {
X			rogue.hp_current++;
X		}
X		if ((rogue.hp_current += regeneration) > rogue.hp_max) {
X			rogue.hp_current = rogue.hp_max;
X		}
X		print_stats(STAT_HP);
X	}
X}
END_OF_move.c
if test 9678 -ne `wc -c <move.c`; then
    echo shar: \"move.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rogue.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rogue.h\"
else
echo shar: Extracting \"rogue.h\" \(10039 characters\)
sed "s/^X//" >rogue.h <<'END_OF_rogue.h'
X/*
X * object.h
X *
X * This source herein may be modified and/or distributed by anybody who
X * so desires, with the following restrictions:
X *    1.)  This notice shall not be removed.
X *    2.)  Credit shall not be taken for the creation of this source.
X *    3.)  This code is not to be traded, sold, or used for personal
X *         gain or profit.
X *
X */
X
X#define boolean char
X
X#define NOTHING		((unsigned short)     0)
X#define OBJECT		((unsigned short)    01)
X#define MONSTER		((unsigned short)    02)
X#define STAIRS		((unsigned short)    04)
X#define HORWALL		((unsigned short)   010)
X#define VERTWALL	((unsigned short)   020)
X#define DOOR		((unsigned short)   040)
X#define FLOOR		((unsigned short)  0100)
X#define TUNNEL		((unsigned short)  0200)
X#define TRAP		((unsigned short)  0400)
X#define HIDDEN		((unsigned short) 01000)
X
X#define ARMOR		((unsigned short)   01)
X#define WEAPON		((unsigned short)   02)
X#define SCROLL		((unsigned short)   04)
X#define POTION		((unsigned short)  010)
X#define GOLD		((unsigned short)  020)
X#define FOOD		((unsigned short)  040)
X#define WAND		((unsigned short) 0100)
X#define RING		((unsigned short) 0200)
X#define AMULET		((unsigned short) 0400)
X#define ALL_OBJECTS	((unsigned short) 0777)
X
X#define LEATHER 0
X#define RINGMAIL 1
X#define SCALE 2
X#define CHAIN 3
X#define BANDED 4
X#define SPLINT 5
X#define PLATE 6
X#define ARMORS 7
X
X#define BOW 0
X#define DART 1
X#define ARROW 2
X#define DAGGER 3
X#define SHURIKEN 4
X#define MACE 5
X#define LONG_SWORD 6
X#define TWO_HANDED_SWORD 7
X#define WEAPONS 8
X
X#define MAX_PACK_COUNT 24
X
X#define PROTECT_ARMOR 0
X#define HOLD_MONSTER 1
X#define ENCH_WEAPON 2
X#define ENCH_ARMOR 3
X#define IDENTIFY 4
X#define TELEPORT 5
X#define SLEEP 6
X#define SCARE_MONSTER 7
X#define REMOVE_CURSE 8
X#define CREATE_MONSTER 9
X#define AGGRAVATE_MONSTER 10
X#define MAGIC_MAPPING 11
X#define SCROLLS 12
X
X#define INCREASE_STRENGTH 0
X#define RESTORE_STRENGTH 1
X#define HEALING 2
X#define EXTRA_HEALING 3
X#define POISON 4
X#define RAISE_LEVEL 5
X#define BLINDNESS 6
X#define HALLUCINATION 7
X#define DETECT_MONSTER 8
X#define DETECT_OBJECTS 9
X#define CONFUSION 10
X#define LEVITATION 11
X#define HASTE_SELF 12
X#define SEE_INVISIBLE 13
X#define POTIONS 14
X
X#define TELE_AWAY 0
X#define SLOW_MONSTER 1
X#define CONFUSE_MONSTER 2
X#define INVISIBILITY 3
X#define POLYMORPH 4
X#define HASTE_MONSTER 5
X#define PUT_TO_SLEEP 6
X#define MAGIC_MISSILE 7
X#define CANCELLATION 8
X#define DO_NOTHING 9
X#define WANDS 10
X
X#define STEALTH 0
X#define R_TELEPORT 1
X#define REGENERATION 2
X#define SLOW_DIGEST 3
X#define ADD_STRENGTH 4
X#define SUSTAIN_STRENGTH 5
X#define DEXTERITY 6
X#define ADORNMENT 7
X#define R_SEE_INVISIBLE 8
X#define MAINTAIN_ARMOR 9
X#define SEARCHING 10
X#define RINGS 11
X
X#define RATION 0
X#define FRUIT 1
X
X#define NOT_USED		((unsigned short)   0)
X#define BEING_WIELDED	((unsigned short)  01)
X#define BEING_WORN		((unsigned short)  02)
X#define ON_LEFT_HAND	((unsigned short)  04)
X#define ON_RIGHT_HAND	((unsigned short) 010)
X#define ON_EITHER_HAND	((unsigned short) 014)
X#define BEING_USED		((unsigned short) 017)
X
X#define NO_TRAP -1
X#define TRAP_DOOR 0
X#define BEAR_TRAP 1
X#define TELE_TRAP 2
X#define DART_TRAP 3
X#define SLEEPING_GAS_TRAP 4
X#define RUST_TRAP 5
X#define TRAPS 6
X
X#define STEALTH_FACTOR 3
X#define R_TELE_PERCENT 8
X
X#define UNIDENTIFIED ((unsigned short) 00)	/* MUST BE ZERO! */
X#define IDENTIFIED ((unsigned short) 01)
X#define CALLED ((unsigned short) 02)
X
X#define DROWS 24
X#define DCOLS 80
X#define MAX_TITLE_LENGTH 30
X#define MORE "-more-"
X#define MAXSYLLABLES 40
X#define MAX_METAL 14
X#define WAND_MATERIALS 30
X#define GEMS 14
X
X#define GOLD_PERCENT 46
X
Xstruct id {
X	short value;
X	char *title;
X	char *real;
X	unsigned short id_status;
X};
X
X/* The following #defines provide more meaningful names for some of the
X * struct object fields that are used for monsters.  This, since each monster
X * and object (scrolls, potions, etc) are represented by a struct object.
X * Ideally, this should be handled by some kind of union structure.
X */
X
X#define m_damage damage
X#define hp_to_kill quantity
X#define m_char ichar
X#define first_level is_protected
X#define last_level is_cursed
X#define m_hit_chance class
X#define stationary_damage identified
X#define drop_percent which_kind
X#define trail_char d_enchant
X#define slowed_toggle quiver
X#define moves_confused hit_enchant
X#define nap_length picked_up
X#define disguise what_is
X#define next_monster next_object
X
Xstruct obj {				/* comment is monster meaning */
X	unsigned long m_flags;	/* monster flags */
X	char *damage;			/* damage it does */
X	short quantity;			/* hit points to kill */
X	short ichar;			/* 'A' is for aquatar */
X	short kill_exp;			/* exp for killing it */
X	short is_protected;		/* level starts */
X	short is_cursed;		/* level ends */
X	short class;			/* chance of hitting you */
X	short identified;		/* 'F' damage, 1,2,3... */
X	unsigned short which_kind; /* item carry/drop % */
X	short o_row, o_col, o;	/* o is how many times stuck at o_row, o_col */
X	short row, col;			/* current row, col */
X	short d_enchant;		/* room char when detect_monster */
X	short quiver;			/* monster slowed toggle */
X	short trow, tcol;		/* target row, col */
X	short hit_enchant;		/* how many moves is confused */
X	unsigned short what_is;	/* imitator's charactor (?!%: */
X	short picked_up;		/* sleep from wand of sleep */
X	unsigned short in_use_flags;
X	struct obj *next_object;	/* next monster */
X};
X
Xtypedef struct obj object;
X
X#define INIT_HP 12
X
Xstruct fight {
X	object *armor;
X	object *weapon;
X	object *left_ring, *right_ring;
X	short hp_current;
X	short hp_max;
X	short str_current;
X	short str_max;
X	object pack;
X	long gold;
X	short exp;
X	long exp_points;
X	short row, col;
X	short fchar;
X	short moves_left;
X};
X
Xtypedef struct fight fighter;
X
Xstruct dr {
X	short oth_room;
X	short oth_row,
X	      oth_col;
X	short door_row,
X		  door_col;
X};
X
Xtypedef struct dr door;
X
Xstruct rm {
X	char bottom_row, right_col, left_col, top_row;
X	door doors[4];
X	unsigned short is_room;
X};
X
Xtypedef struct rm room;
X
X#define MAXROOMS 9
X#define BIG_ROOM 10
X
X#define NO_ROOM -1
X
X#define PASSAGE -3		/* cur_room value */
X
X#define AMULET_LEVEL 26
X
X#define R_NOTHING	((unsigned short) 01)
X#define R_ROOM		((unsigned short) 02)
X#define R_MAZE		((unsigned short) 04)
X#define R_DEADEND	((unsigned short) 010)
X#define R_CROSS		((unsigned short) 020)
X
X#define MAX_EXP_LEVEL 21
X#define MAX_EXP 10000000L
X#define MAX_GOLD 900000
X#define MAX_ARMOR 99
X#define MAX_HP 800
X#define MAX_STRENGTH 99
X#define LAST_DUNGEON 99
X
X#define STAT_LEVEL 01
X#define STAT_GOLD 02
X#define STAT_HP 04
X#define STAT_STRENGTH 010
X#define STAT_ARMOR 020
X#define STAT_EXP 040
X#define STAT_HUNGER 0100
X#define STAT_LABEL 0200
X#define STAT_ALL 0377
X
X#define PARTY_TIME 10	/* one party somewhere in each 10 level span */
X
X#define MAX_TRAPS 10	/* maximum traps per level */
X
X#define HIDE_PERCENT 12
X
Xstruct tr {
X	short trap_type;
X	short trap_row, trap_col;
X};
X
Xtypedef struct tr trap;
X
Xextern fighter rogue;
Xextern room rooms[];
Xextern trap traps[];
Xextern unsigned short dungeon[DROWS][DCOLS];
Xextern object level_objects;
X
Xextern struct id id_scrolls[];
Xextern struct id id_potions[];
Xextern struct id id_wands[];
Xextern struct id id_rings[];
Xextern struct id id_weapons[];
Xextern struct id id_armors[];
X
Xextern object mon_tab[];
Xextern object level_monsters;
X
X#define MONSTERS 26
X
X#define HASTED					01L
X#define SLOWED					02L
X#define INVISIBLE				04L
X#define ASLEEP				   010L
X#define WAKENS				   020L
X#define WANDERS				   040L
X#define FLIES				  0100L
X#define FLITS				  0200L
X#define CAN_FLIT			  0400L		/* can, but usually doesn't, flit */
X#define CONFUSED	 		 01000L
X#define RUSTS				 02000L
X#define HOLDS				 04000L
X#define FREEZES				010000L
X#define STEALS_GOLD			020000L
X#define STEALS_ITEM			040000L
X#define STINGS			   0100000L
X#define DRAINS_LIFE		   0200000L
X#define DROPS_LEVEL		   0400000L
X#define SEEKS_GOLD		  01000000L
X#define FREEZING_ROGUE	  02000000L
X#define RUST_VANISHED	  04000000L
X#define CONFUSES		 010000000L
X#define IMITATES		 020000000L
X#define FLAMES			 040000000L
X#define STATIONARY		0100000000L		/* damage will be 1,2,3,... */
X#define NAPPING			0200000000L		/* can't wake up for a while */
X#define ALREADY_MOVED	0400000000L
X
X#define SPECIAL_HIT		(RUSTS|HOLDS|FREEZES|STEALS_GOLD|STEALS_ITEM|STINGS|DRAINS_LIFE|DROPS_LEVEL)
X
X#define WAKE_PERCENT 45
X#define FLIT_PERCENT 33
X#define PARTY_WAKE_PERCENT 75
X
X#define HYPOTHERMIA 1
X#define STARVATION 2
X#define POISON_DART 3
X#define QUIT 4
X#define WIN 5
X
X#define UP 0
X#define UPRIGHT 1
X#define RIGHT 2
X#define RIGHTDOWN 3
X#define DOWN 4
X#define DOWNLEFT 5
X#define LEFT 6
X#define LEFTUP 7
X#define DIRS 8
X
X#define ROW1 7
X#define ROW2 15
X
X#define COL1 26
X#define COL2 52
X
X#define MOVED 0
X#define MOVE_FAILED -1
X#define STOPPED_ON_SOMETHING -2
X#define CANCEL '\033'
X#define LIST '*'
X
X#define HUNGRY 300
X#define WEAK 150
X#define FAINT 20
X#define STARVE 0
X
X#define MIN_ROW 1
X
X/* external routine declarations.
X */
Xchar *strcpy();
Xchar *strncpy();
Xchar *strcat();
Xchar *sprintf();
X
Xchar *mon_name();
Xchar *get_ench_color();
Xchar *name_of();
Xchar *md_gln();
Xchar *md_getenv();
Xchar *md_malloc();
Xboolean is_direction();
Xboolean mon_sees();
Xboolean mask_pack();
Xboolean mask_room();
Xboolean is_digit();
Xboolean check_hunger();
Xboolean reg_move();
Xboolean md_df();
Xboolean has_been_touched();
Xobject *add_to_pack();
Xobject *alloc_object();
Xobject *get_letter_object();
Xobject *gr_monster();
Xobject *get_thrown_at_monster();
Xobject *get_zapped_monster();
Xobject *check_duplicate();
Xobject *gr_object();
Xobject *object_at();
Xobject *pick_up();
Xstruct id *get_id_table();
Xunsigned short gr_what_is();
Xlong rrandom();
Xlong lget_number();
Xlong xxx();
Xint byebye(), onintr(), error_save();
X
Xstruct rogue_time {
X	short year;		/* >= 1987 */
X	short month;	/* 1 - 12 */
X	short day;		/* 1 - 31 */
X	short hour;		/* 0 - 23 */
X	short minute;	/* 0 - 59 */
X	short second;	/* 0 - 59 */
X};
X
X#ifdef CURSES
Xstruct _win_st {
X	short _cury, _curx;
X	short _maxy, _maxx;
X};
X
Xtypedef struct _win_st WINDOW;
X
Xextern int LINES, COLS;
Xextern WINDOW *curscr;
Xextern char *CL;
X
Xchar *md_gdtcf();
X
X#endif CURSES
END_OF_rogue.h
if test 10039 -ne `wc -c <rogue.h`; then
    echo shar: \"rogue.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f save.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"save.c\"
else
echo shar: Extracting \"save.c\" \(9632 characters\)
sed "s/^X//" >save.c <<'END_OF_save.c'
X/*
X * save.c
X *
X * This source herein may be modified and/or distributed by anybody who
X * so desires, with the following restrictions:
X *    1.)  No portion of this notice shall be removed.
X *    2.)  Credit shall not be taken for the creation of this source.
X *    3.)  This code is not to be traded, sold, or used for personal
X *         gain or profit.
X *
X */
X
X#ifndef CURSES
X#include <curses.h>
X#endif CURSES
X#include <stdio.h>
X#include "rogue.h"
X
Xshort write_failed = 0;
Xchar *save_file = "";
X
Xextern boolean detect_monster;
Xextern short cur_level, max_level;
Xextern char hunger_str[];
Xextern char login_name[];
Xextern short party_room;
Xextern short party_counter;
Xextern short foods;
Xextern boolean is_wood[];
Xextern short cur_room;
Xextern boolean being_held;
Xextern short bear_trap;
Xextern short halluc;
Xextern short blind;
Xextern short confused;
Xextern short levitate;
Xextern short haste_self;
Xextern boolean see_invisible;
Xextern boolean detect_monster;
Xextern boolean wizard;
Xextern boolean score_only;
Xextern short m_moves;
X
Xextern boolean msg_cleared;
X
Xsave_game()
X{
X	char fname[64];
X
X	if (!get_input_line("file name?", save_file, fname, "game not saved",
X			0, 1)) {
X		return;
X	}
X	check_message();
X	message(fname, 0);
X	save_into_file(fname);
X}
X
Xsave_into_file(sfile)
Xchar *sfile;
X{
X	FILE *fp;
X	int file_id;
X	char name_buffer[80];
X	char *hptr;
X	struct rogue_time rt_buf;
X
X	if (sfile[0] == '~') {
X		if (hptr = md_getenv("HOME")) {
X			(void) strcpy(name_buffer, hptr);
X			(void) strcat(name_buffer, sfile+1);
X			sfile = name_buffer;
X		}
X	}
X	if (	((fp = fopen(sfile, "w")) == NULL) ||
X			((file_id = md_get_file_id(sfile)) == -1)) {
X		message("problem accessing the save file", 0);
X		return;
X	}
X	md_ignore_signals();
X	write_failed = 0;
X	(void) xxx(1);
X	r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
X	r_write(fp, (char *) &cur_level, sizeof(cur_level));
X	r_write(fp, (char *) &max_level, sizeof(max_level));
X	write_string(hunger_str, fp);
X	write_string(login_name, fp);
X	r_write(fp, (char *) &party_room, sizeof(party_room));
X	r_write(fp, (char *) &party_counter, sizeof(party_counter));
X	write_pack(&level_monsters, fp);
X	write_pack(&level_objects, fp);
X	r_write(fp, (char *) &file_id, sizeof(file_id));
X	rw_dungeon(fp, 1);
X	r_write(fp, (char *) &foods, sizeof(foods));
X	r_write(fp, (char *) &rogue, sizeof(fighter));
X	write_pack(&rogue.pack, fp);
X	rw_id(id_potions, fp, POTIONS, 1);
X	rw_id(id_scrolls, fp, SCROLLS, 1);
X	rw_id(id_wands, fp, WANDS, 1);
X	rw_id(id_rings, fp, RINGS, 1);
X	r_write(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
X	r_write(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
X	r_write(fp, (char *) &cur_room, sizeof(cur_room));
X	rw_rooms(fp, 1);
X	r_write(fp, (char *) &being_held, sizeof(being_held));
X	r_write(fp, (char *) &bear_trap, sizeof(bear_trap));
X	r_write(fp, (char *) &halluc, sizeof(halluc));
X	r_write(fp, (char *) &blind, sizeof(blind));
X	r_write(fp, (char *) &confused, sizeof(confused));
X	r_write(fp, (char *) &levitate, sizeof(levitate));
X	r_write(fp, (char *) &haste_self, sizeof(haste_self));
X	r_write(fp, (char *) &see_invisible, sizeof(see_invisible));
X	r_write(fp, (char *) &detect_monster, sizeof(detect_monster));
X	r_write(fp, (char *) &wizard, sizeof(wizard));
X	r_write(fp, (char *) &score_only, sizeof(score_only));
X	r_write(fp, (char *) &m_moves, sizeof(m_moves));
X	md_gct(&rt_buf);
X	rt_buf.second += 10;		/* allow for some processing time */
X	r_write(fp, (char *) &rt_buf, sizeof(rt_buf));
X	fclose(fp);
X
X	if (write_failed) {
X		(void) md_df(sfile);	/* delete file */
X	} else {
X		clean_up("");
X	}
X}
X
Xrestore(fname)
Xchar *fname;
X{
X	FILE *fp;
X	struct rogue_time saved_time, mod_time;
X	char buf[4];
X	char tbuf[40];
X	int new_file_id, saved_file_id;
X
X	if (	((new_file_id = md_get_file_id(fname)) == -1) ||
X			((fp = fopen(fname, "r")) == NULL)) {
X		clean_up("cannot open file");
X	}
X	if (md_link_count(fname) > 1) {
X		clean_up("file has link");
X	}
X	(void) xxx(1);
X	r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
X	r_read(fp, (char *) &cur_level, sizeof(cur_level));
X	r_read(fp, (char *) &max_level, sizeof(max_level));
X	read_string(hunger_str, fp);
X
X	(void) strcpy(tbuf, login_name);
X	read_string(login_name, fp);
X	if (strcmp(tbuf, login_name)) {
X		clean_up("you're not the original player");
X	}
X
X	r_read(fp, (char *) &party_room, sizeof(party_room));
X	r_read(fp, (char *) &party_counter, sizeof(party_counter));
X	read_pack(&level_monsters, fp, 0);
X	read_pack(&level_objects, fp, 0);
X	r_read(fp, (char *) &saved_file_id, sizeof(saved_file_id));
X	if (new_file_id != saved_file_id) {
X		clean_up("sorry, saved game is not in the same file");
X	}
X	rw_dungeon(fp, 0);
X	r_read(fp, (char *) &foods, sizeof(foods));
X	r_read(fp, (char *) &rogue, sizeof(fighter));
X	read_pack(&rogue.pack, fp, 1);
X	rw_id(id_potions, fp, POTIONS, 0);
X	rw_id(id_scrolls, fp, SCROLLS, 0);
X	rw_id(id_wands, fp, WANDS, 0);
X	rw_id(id_rings, fp, RINGS, 0);
X	r_read(fp, (char *) traps, (MAX_TRAPS * sizeof(trap)));
X	r_read(fp, (char *) is_wood, (WANDS * sizeof(boolean)));
X	r_read(fp, (char *) &cur_room, sizeof(cur_room));
X	rw_rooms(fp, 0);
X	r_read(fp, (char *) &being_held, sizeof(being_held));
X	r_read(fp, (char *) &bear_trap, sizeof(bear_trap));
X	r_read(fp, (char *) &halluc, sizeof(halluc));
X	r_read(fp, (char *) &blind, sizeof(blind));
X	r_read(fp, (char *) &confused, sizeof(confused));
X	r_read(fp, (char *) &levitate, sizeof(levitate));
X	r_read(fp, (char *) &haste_self, sizeof(haste_self));
X	r_read(fp, (char *) &see_invisible, sizeof(see_invisible));
X	r_read(fp, (char *) &detect_monster, sizeof(detect_monster));
X	r_read(fp, (char *) &wizard, sizeof(wizard));
X	r_read(fp, (char *) &score_only, sizeof(score_only));
X	r_read(fp, (char *) &m_moves, sizeof(m_moves));
X	r_read(fp, (char *) &saved_time, sizeof(saved_time));
X
X	if (fread(buf, sizeof(char), 1, fp) > 0) {
X		clear();
X		clean_up("extra characters in file");
X	}
X
X	md_gfmt(fname, &mod_time);	/* get file modification time */
X
X	if (has_been_touched(&saved_time, &mod_time)) {
X		clear();
X		clean_up("sorry, file has been touched");
X	}
X	if ((!wizard) && !md_df(fname)) {
X		clean_up("cannot delete file");
X	}
X	msg_cleared = 0;
X	ring_stats(0);
X	fclose(fp);
X}
X
Xwrite_pack(pack, fp)
Xobject *pack;
XFILE *fp;
X{
X	object t;
X
X	while (pack = pack->next_object) {
X		r_write(fp, (char *) pack, sizeof(object));
X	}
X	t.ichar = t.what_is = 0;
X	r_write(fp, (char *) &t, sizeof(object));
X}
X
Xread_pack(pack, fp, is_rogue)
Xobject *pack;
XFILE *fp;
Xboolean is_rogue;
X{
X	object read_obj, *new_obj;
X
X	for (;;) {
X		r_read(fp, (char *) &read_obj, sizeof(object));
X		if (read_obj.ichar == 0) {
X			pack->next_object = (object *) 0;
X			break;
X		}
X		new_obj = alloc_object();
X		*new_obj = read_obj;
X		if (is_rogue) {
X			if (new_obj->in_use_flags & BEING_WORN) {
X					do_wear(new_obj);
X			} else if (new_obj->in_use_flags & BEING_WIELDED) {
X					do_wield(new_obj);
X			} else if (new_obj->in_use_flags & (ON_EITHER_HAND)) {
X				do_put_on(new_obj,
X					((new_obj->in_use_flags & ON_LEFT_HAND) ? 1 : 0));
X			}
X		}
X		pack->next_object = new_obj;
X		pack = new_obj;
X	}
X}
X
Xrw_dungeon(fp, rw)
XFILE *fp;
Xboolean rw;
X{
X	short i, j;
X	char buf[DCOLS];
X
X	for (i = 0; i < DROWS; i++) {
X		if (rw) {
X			r_write(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
X			for (j = 0; j < DCOLS; j++) {
X				buf[j] = mvinch(i, j);
X			}
X			r_write(fp, buf, DCOLS);
X		} else {
X			r_read(fp, (char *) dungeon[i], (DCOLS * sizeof(dungeon[0][0])));
X			r_read(fp, buf, DCOLS);
X			for (j = 0; j < DCOLS; j++) {
X				mvaddch(i, j, buf[j]);
X			}
X		}
X	}
X}
X
Xrw_id(id_table, fp, n, wr)
Xstruct id id_table[];
XFILE *fp;
Xint n;
Xboolean wr;
X{
X	short i;
X
X	for (i = 0; i < n; i++) {
X		if (wr) {
X			r_write(fp, (char *) &(id_table[i].value), sizeof(short));
X			r_write(fp, (char *) &(id_table[i].id_status),
X				sizeof(unsigned short));
X			write_string(id_table[i].title, fp);
X		} else {
X			r_read(fp, (char *) &(id_table[i].value), sizeof(short));
X			r_read(fp, (char *) &(id_table[i].id_status),
X				sizeof(unsigned short));
X			read_string(id_table[i].title, fp);
X		}
X	}
X}
X
Xwrite_string(s, fp)
Xchar *s;
XFILE *fp;
X{
X	short n;
X
X	n = strlen(s) + 1;
X	xxxx(s, n);
X	r_write(fp, (char *) &n, sizeof(short));
X	r_write(fp, s, n);
X}
X
Xread_string(s, fp)
Xchar *s;
XFILE *fp;
X{
X	short n;
X
X	r_read(fp, (char *) &n, sizeof(short));
X	r_read(fp, s, n);
X	xxxx(s, n);
X}
X
Xrw_rooms(fp, rw)
XFILE *fp;
Xboolean rw;
X{
X	short i;
X
X	for (i = 0; i < MAXROOMS; i++) {
X		rw ? r_write(fp, (char *) (rooms + i), sizeof(room)) :
X			r_read(fp, (char *) (rooms + i), sizeof(room));
X	}
X}
X
Xr_read(fp, buf, n)
XFILE *fp;
Xchar *buf;
Xint n;
X{
X	if (fread(buf, sizeof(char), n, fp) != n) {
X		clean_up("read() failed, don't know why");
X	}
X}
X
Xr_write(fp, buf, n)
XFILE *fp;
Xchar *buf;
Xint n;
X{
X	if (!write_failed) {
X		if (fwrite(buf, sizeof(char), n, fp) != n) {
X			message("write() failed, don't know why", 0);
X			sound_bell();
X			write_failed = 1;
X		}
X	}
X}
X
Xboolean
Xhas_been_touched(saved_time, mod_time)
Xstruct rogue_time *saved_time, *mod_time;
X{
X	if (saved_time->year < mod_time->year) {
X		return(1);
X	} else if (saved_time->year > mod_time->year) {
X		return(0);
X	}
X	if (saved_time->month < mod_time->month) {
X		return(1);
X	} else if (saved_time->month > mod_time->month) {
X		return(0);
X	}
X	if (saved_time->day < mod_time->day) {
X		return(1);
X	} else if (saved_time->day > mod_time->day) {
X		return(0);
X	}
X	if (saved_time->hour < mod_time->hour) {
X		return(1);
X	} else if (saved_time->hour > mod_time->hour) {
X		return(0);
X	}
X	if (saved_time->minute < mod_time->minute) {
X		return(1);
X	} else if (saved_time->minute > mod_time->minute) {
X		return(0);
X	}
X	if (saved_time->second < mod_time->second) {
X		return(1);
X	}
X	return(0);
X}
END_OF_save.c
if test 9632 -ne `wc -c <save.c`; then
    echo shar: \"save.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f score.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"score.c\"
else
echo shar: Extracting \"score.c\" \(10209 characters\)
sed "s/^X//" >score.c <<'END_OF_score.c'
X/*
X * score.c
X *
X * This source herein may be modified and/or distributed by anybody who
X * so desires, with the following restrictions:
X *    1.)  No portion of this notice shall be removed.
X *    2.)  Credit shall not be taken for the creation of this source.
X *    3.)  This code is not to be traded, sold, or used for personal
X *         gain or profit.
X *
X */
X
X#ifndef CURSES
X#include <curses.h>
X#endif CURSES
X#include <stdio.h>
X#include "rogue.h"
X
Xchar *score_file = "rogue.scores";
X
Xextern char login_name[];
Xextern char *m_names[];
Xextern short max_level;
Xextern boolean score_only, show_skull, msg_cleared;
Xextern char *byebye_string, *nick_name;
X
Xkilled_by(monster, other)
Xobject *monster;
Xshort other;
X{
X	char buf[80];
X
X	md_ignore_signals();
X
X	if (other != QUIT) {
X		rogue.gold = ((rogue.gold * 9) / 10);
X	}
X
X	if (other) {
X		switch(other) {
X		case HYPOTHERMIA:
X			(void) strcpy(buf, "died of hypothermia");
X			break;
X		case STARVATION:
X			(void) strcpy(buf, "died of starvation");
X			break;
X		case POISON_DART:
X			(void) strcpy(buf, "killed by a dart");
X			break;
X		case QUIT:
X			(void) strcpy(buf, "quit");
X			break;
X		}
X	} else {
X		(void) strcpy(buf, "Killed by ");
X		if (is_vowel(m_names[monster->m_char - 'A'][0])) {
X			(void) strcat(buf, "an ");
X		} else {
X			(void) strcat(buf, "a ");
X		}
X		(void) strcat(buf, m_names[monster->m_char - 'A']);
X	}
X	(void) strcat(buf, " with ");
X	sprintf(buf+strlen(buf), "%d gold", rogue.gold);
X	if ((!other) && show_skull) {
X		clear();
X		mvaddstr(4, 32, "__---------__");
X		mvaddstr(5, 30, "_~             ~_");
X		mvaddstr(6, 29, "/                 \\");
X		mvaddstr(7, 28, "~                   ~");
X		mvaddstr(8, 27, "/                     \\");
X		mvaddstr(9, 27, "|    XXXX     XXXX    |");
X		mvaddstr(10, 27, "|    XXXX     XXXX    |");
X		mvaddstr(11, 27, "|    XXX       XXX    |");
X		mvaddstr(12, 28, "\\         @         /");
X		mvaddstr(13, 29, "--\\     @@@     /--");
X		mvaddstr(14, 30, "| |    @@@    | |");
X		mvaddstr(15, 30, "| |           | |");
X		mvaddstr(16, 30, "| vvVvvvvvvvVvv |");
X		mvaddstr(17, 30, "|  ^^^^^^^^^^^  |");
X		mvaddstr(18, 31, "\\_           _/");
X		mvaddstr(19, 33, "~---------~");
X		center(21, (nick_name[0] ? nick_name : login_name));
X		center(22, buf);
X	} else {
X		message(buf, 0);
X	}
X	message("", 0);
X	put_scores(monster, other);
X}
X
Xwin()
X{
X	unwield(rogue.weapon);		/* disarm and relax */
X	unwear(rogue.armor);
X	un_put_on(rogue.left_ring);
X	un_put_on(rogue.right_ring);
X
X	clear();
X	mvaddstr(10, 11, "@   @  @@@   @   @      @  @  @   @@@   @   @   @");
X	mvaddstr(11, 11, " @ @  @   @  @   @      @  @  @  @   @  @@  @   @");
X	mvaddstr(12, 11, "  @   @   @  @   @      @  @  @  @   @  @ @ @   @");
X	mvaddstr(13, 11, "  @   @   @  @   @      @  @  @  @   @  @  @@");
X	mvaddstr(14, 11, "  @    @@@    @@@        @@ @@    @@@   @   @   @");
X	mvaddstr(17, 11, "Congratulations,  you have  been admitted  to  the");
X	mvaddstr(18, 11, "Fighters' Guild.   You return home,  sell all your");
X	mvaddstr(19, 11, "treasures at great profit and retire into comfort.");
X	message("", 0);
X	message("", 0);
X	id_all();
X	sell_pack();
X	put_scores((object *) 0, WIN);
X}
X
Xquit(from_intrpt)
Xboolean from_intrpt;
X{
X	char buf[128];
X	short i, orow, ocol;
X	boolean mc;
X
X	md_ignore_signals();
X
X	if (from_intrpt) {
X
X		orow = curscr->_cury;
X		ocol = curscr->_curx;
X		mc = msg_cleared;
X
X		for (i = 0; i < DCOLS; i++) {
X			buf[i] = mvinch(0, i);
X		}
X	}
X	check_message();
X	message("really quit?", 1);
X	if (rgetchar() != 'y') {
X		md_heed_signals();
X		check_message();
X		if (from_intrpt) {
X			for (i = 0; i < DCOLS; i++) {
X				mvaddch(0, i, buf[i]);
X			}
X			msg_cleared = mc;
X			move(orow, ocol);
X			refresh();
X		}
X		return;
X	}
X	if (from_intrpt) {
X		clean_up(byebye_string);
X	}
X	check_message();
X	killed_by((object *) 0, QUIT);
X}
X
Xput_scores(monster, other)
Xobject *monster;
Xshort other;
X{
X	short i, n, rank = 10, x, ne = 0, found_player = -1;
X	char scores[10][82];
X	char n_names[10][30];
X	char buf[100];
X	FILE *fp;
X	long s;
X	boolean failed = 0;
X	char *mode = "r+w";
X
X	while ((fp = fopen(score_file, mode)) == NULL) {
X		if (!failed) {
X			mode = "w";
X		} else {
X			message("cannot read/write/create score file", 0);
X			sf_error();
X		}
X		failed = 1;
X	}
X	(void) xxx(1);
X
X	for (i = 0; i < 10; i++) {
X		if (((n = fread(scores[i], sizeof(char), 80, fp)) < 80) && (n != 0)) {
X			sf_error();
X		} else if (n != 0) {
X			xxxx(scores[i], 80);
X			if ((n = fread(n_names[i], sizeof(char), 30, fp)) < 30) {
X				sf_error();
X			}
X			xxxx(n_names[i], 30);
X		} else {
X			break;
X		}
X		ne++;
X		if (!score_only) {
X			if (!name_cmp(scores[i]+15, login_name)) {
X				x = 5;
X				while (scores[i][x] == ' ') {
X					x++;
X				}
X				s = lget_number(scores[i] + x);
X				if (rogue.gold < s) {
X					score_only = 1;
X				} else {
X					found_player = i;
X				}
X			}
X		}
X	}
X	if (found_player != -1) {
X		ne--;
X		for (i = found_player; i < ne; i++) {
X			(void) strcpy(scores[i], scores[i+1]);
X			(void) strcpy(n_names[i], n_names[i+1]);
X		}
X	}
X	if (!score_only) {
X		for (i = 0; i < ne; i++) {
X			x = 5;
X			while (scores[i][x] == ' ') {
X				x++;
X			}
X			s = lget_number(scores[i] + x);
X
X			if (rogue.gold >= s) {
X				rank = i;
X				break;
X			}
X		}
X		if (ne == 0) {
X			rank = 0;
X		} else if ((ne < 10) && (rank == 10)) {
X			rank = ne;
X		}
X		if (rank < 10) {
X			insert_score(scores, n_names, nick_name, rank, ne, monster,
X				other);
X			if (ne < 10) {
X				ne++;
X			}
X		}
X		rewind(fp);
X	}
X
X	clear();
X	mvaddstr(3, 30, "Top  Ten  Rogueists");
X	mvaddstr(8, 0, "Rank   Score   Name");
X
X	md_ignore_signals();
X
X	(void) xxx(1);
X
X	for (i = 0; i < ne; i++) {
X		if (i == rank) {
X			standout();
X		}
X		if (i == 9) {
X			scores[i][0] = '1';
X			scores[i][1] = '0';
X		} else {
X			scores[i][0] = ' ';
X			scores[i][1] = i + '1';
X		}
X		nickize(buf, scores[i], n_names[i]);
X		mvaddstr(i+10, 0, buf);
X		if (rank < 10) {
X			xxxx(scores[i], 80);
X			fwrite(scores[i], sizeof(char), 80, fp);
X			xxxx(n_names[i], 30);
X			fwrite(n_names[i], sizeof(char), 30, fp);
X		}
X		if (i == rank) {
X			standend();
X		}
X	}
X	refresh();
X	fclose(fp);
X	message("", 0);
X	clean_up("");
X}
X
Xinsert_score(scores, n_names, n_name, rank, n, monster, other)
Xchar scores[][82];
Xchar n_names[][30];
Xchar *n_name;
Xshort rank, n;
Xobject *monster;
X{
X	short i;
X	char buf[82];
X
X	if (n > 0) {
X		for (i = n; i > rank; i--) {
X			if ((i < 10) && (i > 0)) {
X				(void) strcpy(scores[i], scores[i-1]);
X				(void) strcpy(n_names[i], n_names[i-1]);
X			}
X		}
X	}
X	sprintf(buf, "%2d    %6d   %s: ", rank+1, rogue.gold, login_name);
X
X	if (other) {
X		switch(other) {
X		case HYPOTHERMIA:
X			(void) strcat(buf, "died of hypothermia");
X			break;
X		case STARVATION:
X			(void) strcat(buf, "died of starvation");
X			break;
X		case POISON_DART:
X			(void) strcat(buf, "killed by a dart");
X			break;
X		case QUIT:
X			(void) strcat(buf, "quit");
X			break;
X		case WIN:
X			(void) strcat(buf, "a total winner");
X			break;
X		}
X	} else {
X		(void) strcat(buf, "killed by ");
X		if (is_vowel(m_names[monster->m_char - 'A'][0])) {
X			(void) strcat(buf, "an ");
X		} else {
X			(void) strcat(buf, "a ");
X		}
X		(void) strcat(buf, m_names[monster->m_char - 'A']);
X	}
X	sprintf(buf+strlen(buf), " on level %d ",  max_level);
X	if ((other != WIN) && has_amulet()) {
X		(void) strcat(buf, "with amulet");
X	}
X	for (i = strlen(buf); i < 79; i++) {
X		buf[i] = ' ';
X	}
X	buf[79] = 0;
X	(void) strcpy(scores[rank], buf);
X	(void) strcpy(n_names[rank], n_name);
X}
X
Xis_vowel(ch)
Xshort ch;
X{
X	return( (ch == 'a') ||
X		(ch == 'e') ||
X		(ch == 'i') ||
X		(ch == 'o') ||
X		(ch == 'u') );
X}
X
Xsell_pack()
X{
X	object *obj;
X	short row = 2, val;
X	char buf[80];
X
X	obj = rogue.pack.next_object;
X
X	clear();
X	mvaddstr(1, 0, "Value      Item");
X
X	while (obj) {
X		if (obj->what_is != FOOD) {
X			obj->identified = 1;
X			val = get_value(obj);
X			rogue.gold += val;
X
X			if (row < DROWS) {
X				sprintf(buf, "%5d      ", val);
X				get_desc(obj, buf+11);
X				mvaddstr(row++, 0, buf);
X			}
X		}
X		obj = obj->next_object;
X	}
X	refresh();
X	if (rogue.gold > MAX_GOLD) {
X		rogue.gold = MAX_GOLD;
X	}
X	message("", 0);
X}
X
Xget_value(obj)
Xobject *obj;
X{
X	short wc;
X	int val;
X
X	wc = obj->which_kind;
X
X	switch(obj->what_is) {
X	case WEAPON:
X		val = id_weapons[wc].value;
X		if ((wc == ARROW) || (wc == DAGGER) || (wc == SHURIKEN) ||
X			(wc == DART)) {
X			val *= obj->quantity;
X		}
X		val += (obj->d_enchant * 85);
X		val += (obj->hit_enchant * 85);
X		break;
X	case ARMOR:
X		val = id_armors[wc].value;
X		val += (obj->d_enchant * 75);
X		if (obj->is_protected) {
X			val += 200;
X		}
X		break;
X	case WAND:
X		val = id_wands[wc].value * (obj->class + 1);
X		break;
X	case SCROLL:
X		val = id_scrolls[wc].value * obj->quantity;
X		break;
X	case POTION:
X		val = id_potions[wc].value * obj->quantity;
X		break;
X	case AMULET:
X		val = 5000;
X		break;
X	}
X	if (val <= 0) {
X		val = 10;
X	}
X	return(val);
X}
X
Xid_all()
X{
X	short i;
X
X	for (i = 0; i < SCROLLS; i++) {
X		id_scrolls[i].id_status = IDENTIFIED;
X	}
X	for (i = 0; i < WEAPONS; i++) {
X		id_weapons[i].id_status = IDENTIFIED;
X	}
X	for (i = 0; i < ARMORS; i++) {
X		id_armors[i].id_status = IDENTIFIED;
X	}
X	for (i = 0; i < WANDS; i++) {
X		id_wands[i].id_status = IDENTIFIED;
X	}
X	for (i = 0; i < POTIONS; i++) {
X		id_potions[i].id_status = IDENTIFIED;
X	}
X}
X
Xname_cmp(s1, s2)
Xchar *s1, *s2;
X{
X	short i = 0;
X	int r;
X
X	while(s1[i] != ':') {
X		i++;
X	}
X	s1[i] = 0;
X	r = strcmp(s1, s2);
X	s1[i] = ':';
X	return(r);
X}
X
Xxxxx(buf, n)
Xchar *buf;
Xshort n;
X{
X	short i;
X	unsigned char c;
X
X	for (i = 0; i < n; i++) {
X
X		/* It does not matter if accuracy is lost during this assignment */
X		c = (unsigned char) xxx(0);
X
X		buf[i] ^= c;
X	}
X}
X
Xlong
Xxxx(st)
Xboolean st;
X{
X	static long f, s;
X	long r;
X
X	if (st) {
X		f = 37;
X		s = 7;
X		return(0L);
X	}
X	r = ((f * s) + 9337) % 8887;
X	f = s;
X	s = r;
X	return(r);
X}
X
Xnickize(buf, score, n_name)
Xchar *buf, *score, *n_name;
X{
X	short i = 15, j;
X
X	if (!n_name[0]) {
X		(void) strcpy(buf, score);
X		return;
X	}
X	(void) strncpy(buf, score, 16);
X
X	while (score[i] != ':') {
X		i++;
X	}
X
X	(void) strcpy(buf+15, n_name);
X	j = strlen(buf);
X
X	while (score[i]) {
X		buf[j++] = score[i++];
X	}
X	buf[j] = 0;
X	buf[79] = 0;
X}
X
Xcenter(row, buf)
Xshort row;
Xchar *buf;
X{
X	short margin;
X
X	margin = ((DCOLS - strlen(buf)) / 2);
X	mvaddstr(row, margin, buf);
X}
X
Xsf_error()
X{
X	message("", 1);
X	clean_up("sorry, score file is out of order");
X}
END_OF_score.c
if test 10209 -ne `wc -c <score.c`; then
    echo shar: \"score.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f spec_hit.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"spec_hit.c\"
else
echo shar: Extracting \"spec_hit.c\" \(9964 characters\)
sed "s/^X//" >spec_hit.c <<'END_OF_spec_hit.c'
X/*
X * special_hit.c
X *
X * This source herein may be modified and/or distributed by anybody who
X * so desires, with the following restrictions:
X *    1.)  No portion of this notice shall be removed.
X *    2.)  Credit shall not be taken for the creation of this source.
X *    3.)  This code is not to be traded, sold, or used for personal
X *         gain or profit.
X *
X */
X
X#ifndef CURSES
X#include <curses.h>
X#endif CURSES
X#include "rogue.h"
X
Xshort less_hp = 0;
Xchar *flame_name = "flame";
Xboolean being_held;
X
Xextern short cur_level, max_level, blind, levitate, ring_exp;
Xextern long level_points[];
Xextern boolean detect_monster, mon_disappeared;
Xextern boolean sustain_strength, maintain_armor;
Xextern char *you_can_move_again;
X
Xspecial_hit(monster)
Xobject *monster;
X{
X	if ((monster->m_flags & CONFUSED) && rand_percent(66)) {
X		return;
X	}
X	if (monster->m_flags & RUSTS) {
X		rust(monster);
X	}
X	if ((monster->m_flags & HOLDS) && !levitate) {
X		being_held = 1;
X	}
X	if (monster->m_flags & FREEZES) {
X		freeze(monster);
X	}
X	if (monster->m_flags & STINGS) {
X		sting(monster);
X	}
X	if (monster->m_flags & DRAINS_LIFE) {
X		drain_life();
X	}
X	if (monster->m_flags & DROPS_LEVEL) {
X		drop_level();
X	}
X	if (monster->m_flags & STEALS_GOLD) {
X		steal_gold(monster);
X	} else if (monster->m_flags & STEALS_ITEM) {
X		steal_item(monster);
X	}
X}
X
Xrust(monster)
Xobject *monster;
X{
X	if ((!rogue.armor) || (get_armor_class(rogue.armor) <= 1) ||
X		(rogue.armor->which_kind == LEATHER)) {
X		return;
X	}
X	if ((rogue.armor->is_protected) || maintain_armor) {
X		if (monster && (!(monster->m_flags & RUST_VANISHED))) {
X			message("the rust vanishes instantly", 0);
X			monster->m_flags |= RUST_VANISHED;
X		}
X	} else {
X		rogue.armor->d_enchant--;
X		message("your armor weakens", 0);
X		print_stats(STAT_ARMOR);
X	}
X}
X
Xfreeze(monster)
Xobject *monster;
X{
X	short freeze_percent = 99;
X	short i, n;
X
X	if (rand_percent(12)) {
X		return;
X	}
X	freeze_percent -= (rogue.str_current+(rogue.str_current / 2));
X	freeze_percent -= ((rogue.exp + ring_exp) * 4);
X	freeze_percent -= (get_armor_class(rogue.armor) * 5);
X	freeze_percent -= (rogue.hp_max / 3);
X
X	if (freeze_percent > 10) {
X		monster->m_flags |= FREEZING_ROGUE;
X		message("you are frozen", 1);
X
X		n = get_rand(4, 8);
X		for (i = 0; i < n; i++) {
X			mv_mons();
X		}
X		if (rand_percent(freeze_percent)) {
X			for (i = 0; i < 50; i++) {
X				mv_mons();
X			}
X			killed_by((object *)0, HYPOTHERMIA);
X		}
X		message(you_can_move_again, 1);
X		monster->m_flags &= (~FREEZING_ROGUE);
X	}
X}
X
Xsteal_gold(monster)
Xobject *monster;
X{
X	int amount;
X
X	if ((rogue.gold <= 0) || rand_percent(10)) {
X		return;
X	}
X
X	amount = get_rand((cur_level * 10), (cur_level * 30));
X
X	if (amount > rogue.gold) {
X		amount = rogue.gold;
X	}
X	rogue.gold -= amount;
X	message("your purse feels lighter", 0);
X	print_stats(STAT_GOLD);
X	disappear(monster);
X}
X
Xsteal_item(monster)
Xobject *monster;
X{
X	object *obj;
X	short i, n, t;
X	char desc[80];
X	boolean has_something = 0;
X
X	if (rand_percent(15)) {
X		return;
X	}
X	obj = rogue.pack.next_object;
X
X	if (!obj) {
X		goto DSPR;
X	}
X	while (obj) {
X		if (!(obj->in_use_flags & BEING_USED)) {
X			has_something = 1;
X			break;
X		}
X		obj = obj->next_object;
X	}
X	if (!has_something) {
X		goto DSPR;
X	}
X	n = get_rand(0, MAX_PACK_COUNT);
X	obj = rogue.pack.next_object;
X
X	for (i = 0; i <= n; i++) {
X		obj = obj->next_object;
X		while ((!obj) || (obj->in_use_flags & BEING_USED)) {
X			if (!obj) {
X				obj = rogue.pack.next_object;
X			} else {
X				obj = obj->next_object;
X			}
X		}
X	}
X	(void) strcpy(desc, "she stole ");
X	if (obj->what_is != WEAPON) {
X		t = obj->quantity;
X		obj->quantity = 1;
X	}
X	get_desc(obj, desc+10);
X	message(desc, 0);
X
X	obj->quantity = ((obj->what_is != WEAPON) ? t : 1);
X
X	vanish(obj, 0, &rogue.pack);
XDSPR:
X	disappear(monster);
X}
X
Xdisappear(monster)
Xobject *monster;
X{
X	short row, col;
X
X	row = monster->row;
X	col = monster->col;
X
X	dungeon[row][col] &= ~MONSTER;
X	if (rogue_can_see(row, col)) {
X		mvaddch(row, col, get_dungeon_char(row, col));
X	}
X	take_from_pack(monster, &level_monsters);
X	free_object(monster);
X	mon_disappeared = 1;
X}
X
Xcough_up(monster)
Xobject *monster;
X{
X	object *obj;
X	short row, col, i, n;
X
X	if (cur_level < max_level) {
X		return;
X	}
X
X	if (monster->m_flags & STEALS_GOLD) {
X		obj = alloc_object();
X		obj->what_is = GOLD;
X		obj->quantity = get_rand((cur_level * 15), (cur_level * 30));
X	} else {
X		if (!rand_percent((int) monster->drop_percent)) {
X			return;
X		}
X		obj = gr_object();
X	}
X	row = monster->row;
X	col = monster->col;
X
X	for (n = 0; n <= 5; n++) {
X		for (i = -n; i <= n; i++) {
X			if (try_to_cough(row+n, col+i, obj)) {
X				return;
X			}
X			if (try_to_cough(row-n, col+i, obj)) {
X				return;
X			}
X		}
X		for (i = -n; i <= n; i++) {
X			if (try_to_cough(row+i, col-n, obj)) {
X				return;
X			}
X			if (try_to_cough(row+i, col+n, obj)) {
X				return;
X			}
X		}
X	}
X	free_object(obj);
X}
X
Xtry_to_cough(row, col, obj)
Xshort row, col;
Xobject *obj;
X{
X	if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col>(DCOLS-1))) {
X		return(0);
X	}
X	if ((!(dungeon[row][col] & (OBJECT | STAIRS | TRAP))) &&
X		(dungeon[row][col] & (TUNNEL | FLOOR | DOOR))) {
X		place_at(obj, row, col);
X		if (((row != rogue.row) || (col != rogue.col)) &&
X			(!(dungeon[row][col] & MONSTER))) {
X			mvaddch(row, col, get_dungeon_char(row, col));
X		}
X		return(1);
X	}
X	return(0);
X}
X
Xseek_gold(monster)
Xobject *monster;
X{
X	short i, j, rn, s;
X
X	if ((rn = get_room_number(monster->row, monster->col)) < 0) {
X		return(0);
X	}
X	for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
X		for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
X			if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) {
X				monster->m_flags |= CAN_FLIT;
X				s = mon_can_go(monster, i, j);
X				monster->m_flags &= (~CAN_FLIT);
X				if (s) {
X					move_mon_to(monster, i, j);
X					monster->m_flags |= ASLEEP;
X					monster->m_flags &= (~(WAKENS | SEEKS_GOLD));
X					return(1);
X				}
X				monster->m_flags &= (~SEEKS_GOLD);
X				monster->m_flags |= CAN_FLIT;
X				mv_monster(monster, i, j);
X				monster->m_flags &= (~CAN_FLIT);
X				monster->m_flags |= SEEKS_GOLD;
X				return(1);
X			}
X		}
X	}
X	return(0);
X}
X
Xgold_at(row, col)
Xshort row, col;
X{
X	if (dungeon[row][col] & OBJECT) {
X		object *obj;
X
X		if ((obj = object_at(&level_objects, row, col)) &&
X				(obj->what_is == GOLD)) {
X			return(1);
X		}
X	}
X	return(0);
X}
X
Xcheck_gold_seeker(monster)
Xobject *monster;
X{
X	monster->m_flags &= (~SEEKS_GOLD);
X}
X
Xcheck_imitator(monster)
Xobject *monster;
X{
X	char msg[80];
X
X	if (monster->m_flags & IMITATES) {
X		wake_up(monster);
X		if (!blind) {
X			mvaddch(monster->row, monster->col,
X					get_dungeon_char(monster->row, monster->col));
X			check_message();
X			sprintf(msg, "wait, that's a %s!", mon_name(monster));
X			message(msg, 1);
X		}
X		return(1);
X	}
X	return(0);
X}
X
Ximitating(row, col)
Xregister short row, col;
X{
X	if (dungeon[row][col] & MONSTER) {
X		object *object_at(), *monster;
X
X		if (monster = object_at(&level_monsters, row, col)) {
X			if (monster->m_flags & IMITATES) {
X				return(1);
X			}
X		}
X	}
X	return(0);
X}
X
Xsting(monster)
Xobject *monster;
X{
X	short sting_chance = 35;
X	char msg[80];
X
X	if ((rogue.str_current <= 3) || sustain_strength) {
X		return;
X	}
X	sting_chance += (6 * (6 - get_armor_class(rogue.armor)));
X
X	if ((rogue.exp + ring_exp) > 8) {
X		sting_chance -= (6 * ((rogue.exp + ring_exp) - 8));
X	}
X	if (rand_percent(sting_chance)) {
X		sprintf(msg, "the %s's bite has weakened you",
X		mon_name(monster));
X		message(msg, 0);
X		rogue.str_current--;
X		print_stats(STAT_STRENGTH);
X	}
X}
X
Xdrop_level()
X{
X	int hp;
X
X	if (rand_percent(80) || (rogue.exp <= 5)) {
X		return;
X	}
X	rogue.exp_points = level_points[rogue.exp-2] - get_rand(9, 29);
X	rogue.exp -= 2;
X	hp = hp_raise();
X	if ((rogue.hp_current -= hp) <= 0) {
X		rogue.hp_current = 1;
X	}
X	if ((rogue.hp_max -= hp) <= 0) {
X		rogue.hp_max = 1;
X	}
X	add_exp(1, 0);
X}
X
Xdrain_life()
X{
X	short n;
X
X	if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) {
X		return;
X	}
X	n = get_rand(1, 3);		/* 1 Hp, 2 Str, 3 both */
X
X	if ((n != 2) || (!sustain_strength)) {
X		message("you feel weaker", 0);
X	}
X	if (n != 2) {
X		rogue.hp_max--;
X		rogue.hp_current--;
X		less_hp++;
X	}
X	if (n != 1) {
X		if ((rogue.str_current > 3) && (!sustain_strength)) {
X			rogue.str_current--;
X			if (coin_toss()) {
X				rogue.str_max--;
X			}
X		}
X	}
X	print_stats((STAT_STRENGTH | STAT_HP));
X}
X
Xm_confuse(monster)
Xobject *monster;
X{
X	char msg[80];
X
X	if (!rogue_can_see(monster->row, monster->col)) {
X		return(0);
X	}
X	if (rand_percent(45)) {
X		monster->m_flags &= (~CONFUSES);	/* will not confuse the rogue */
X		return(0);
X	}
X	if (rand_percent(55)) {
X		monster->m_flags &= (~CONFUSES);
X		sprintf(msg, "the gaze of the %s has confused you", mon_name(monster));
X		message(msg, 1);
X		confuse();
X		return(1);
X	}
X	return(0);
X}
X
Xflame_broil(monster)
Xobject *monster;
X{
X	short row, col;
X
X	if ((!mon_sees(monster, rogue.row, rogue.col)) || coin_toss()) {
X		return(0);
X	}
X	row = rogue.row - monster->row;
X	col = rogue.col - monster->col;
X	if (row < 0) {
X		row = -row;
X	}
X	if (col < 0) {
X		col = -col;
X	}
X	if (((row != 0) && (col != 0) && (row != col)) ||
X		((row > 7) || (col > 7))) {
X		return(0);
X	}
X	if ((!blind) && (!rogue_is_around(monster->row, monster->col))) {
X		row = monster->row;
X		col = monster->col;
X		get_closer(&row, &col, rogue.row, rogue.col);
X		standout();
X		do {
X			mvaddch(row, col, '~');
X			refresh();
X			get_closer(&row, &col, rogue.row, rogue.col);
X		} while ((row != rogue.row) || (col != rogue.col));
X		standend();
X		row = monster->row; col = monster->col;
X		get_closer(&row, &col, rogue.row, rogue.col);
X		do {
X			mvaddch(row, col, get_dungeon_char(row, col));
X			refresh();
X			get_closer(&row, &col, rogue.row, rogue.col);
X		} while ((row != rogue.row) || (col != rogue.col));
X	}
X	mon_hit(monster, flame_name, 1);
X	return(1);
X}
X
Xget_closer(row, col, trow, tcol)
Xshort *row, *col;
Xshort trow, tcol;
X{
X	if (*row < trow) {
X		(*row)++;
X	} else if (*row > trow) {
X		(*row)--;
X	}
X	if (*col < tcol) {
X		(*col)++;
X	} else if (*col > tcol) {
X		(*col)--;
X	}
X}
END_OF_spec_hit.c
if test 9964 -ne `wc -c <spec_hit.c`; then
    echo shar: \"spec_hit.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 5\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0