#!/bin/sh-----cut here-----cut here-----cut here-----cut here-----
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# Makefile # macros.h # monster.h # move.h # object.h # room.h # door_course.c # hit.c # init.c # inventory.c # level.c # main.c # message.c
echo shar: extracting Makefile
cat - << \SHAR_EOF > Makefile
ROGUE_OBJS = door_course.o hit.o init.o inventory.o level.o main.o \
message.o monster.o move.o object.o pack.o play.o random.o \
room.o score.o special_hit.o throw.o use.o zap.o
CC = cc
CFLAGS = -c -O
rogue: $(ROGUE_OBJS)
$(CC) $(ROGUE_OBJS) -lcurses -ltermlib -o rogue
door_course.o: door_course.c object.h monster.h room.h move.h
$(CC) $(CFLAGS) door_course.c
hit.o: hit.c object.h move.h monster.h
$(CC) $(CFLAGS) hit.c
init.o: init.c object.h room.h
$(CC) $(CFLAGS) init.c
inventory.o: inventory.c object.h macros.h move.h
$(CC) $(CFLAGS) inventory.c
level.o: level.c move.h object.h room.h macros.h
$(CC) $(CFLAGS) level.c
main.o: main.c object.h
$(CC) $(CFLAGS) main.c
message.o: message.c object.h move.h
$(CC) $(CFLAGS) message.c
monster.o: monster.c monster.h object.h room.h move.h
$(CC) $(CFLAGS) monster.c
move.o: move.c object.h room.h move.h monster.h
$(CC) $(CFLAGS) move.c
object.o: object.c object.h room.h
$(CC) $(CFLAGS) object.c
pack.o: pack.c move.h object.h
$(CC) $(CFLAGS) pack.c
play.o: play.c object.h move.h
$(CC) $(CFLAGS) play.c
random.o: random.c macros.h
$(CC) $(CFLAGS) random.c
room.o: room.c room.h object.h move.h
$(CC) $(CFLAGS) room.c
score.o: score.c object.h monster.h room.h
$(CC) $(CFLAGS) score.c
special_hit.o: special_hit.c object.h move.h monster.h
$(CC) $(CFLAGS) special_hit.c
throw.o: throw.c object.h move.h monster.h
$(CC) $(CFLAGS) throw.c
use.o: use.c object.h move.h monster.h room.h
$(CC) $(CFLAGS) use.c
zap.o: zap.c object.h move.h monster.h
$(CC) $(CFLAGS) zap.c
SHAR_EOF
echo shar: extracting macros.h
cat - << \SHAR_EOF > macros.h
#define swap(x,y) {int t; t = x; x = y; y = t;}
#define two_sort(x,y) if (x > y) {int t; t = x; x = y; y = t;}
#define swap_string(x,y) {char *t; t = x; x = y; y = t;}
SHAR_EOF
echo shar: extracting monster.h
cat - << \SHAR_EOF > monster.h
#define MONSTERS 26
#define HASTED ((unsigned short)001)
#define SLOWED ((unsigned short)002)
#define IS_INVIS ((unsigned short)004)
#define IS_ASLEEP ((unsigned short)010)
#define WAKENS ((unsigned short)020)
#define WANDERS ((unsigned short)040)
#define FLIES ((unsigned short)0100)
#define FLITS ((unsigned short)0200)
#define CAN_GO ((unsigned short)0400)
#define MAXMONSTER 26
#define WAKE_PERCENT 45
#define FLIT_PERCENT 33
#define PARTY_WAKE_PERCENT 75
#define XEROC1 16 /* levels xeroc appears at */
#define XEROC2 25
#define HYPOTHERMIA 1
#define STARVATION 2
#define QUIT 3
#define WIN 4
SHAR_EOF
echo shar: extracting move.h
cat - << \SHAR_EOF > move.h
#define UP 0
#define UPRIGHT 1
#define RIGHT 2
#define RIGHTDOWN 3
#define DOWN 4
#define DOWNLEFT 5
#define LEFT 6
#define LEFTUP 7
#define ROW1 7
#define ROW2 15
#define COL1 26
#define COL2 52
#define MOVED 0
#define MOVE_FAILED -1
#define STOPPED_ON_SOMETHING -2
#define CANCEL '\033'
#define LIST '*'
#define HUNGRY 300
#define WEAK 120
#define FAINT 20
#define STARVE 0
#define MIN_ROW 1
SHAR_EOF
echo shar: extracting object.h
cat - << \SHAR_EOF > object.h
#define BLANK ((unsigned short) 0)
#define ARMOR ((unsigned short) 01)
#define WEAPON ((unsigned short) 02)
#define SCROLL ((unsigned short) 04)
#define POTION ((unsigned short) 010)
#define GOLD ((unsigned short) 020)
#define FOOD ((unsigned short) 040)
#define WAND ((unsigned short) 0100)
#define STAIRS ((unsigned short) 0200)
#define AMULET ((unsigned short) 0400)
#define MONSTER ((unsigned short) 01000)
#define HORWALL ((unsigned short) 02000)
#define VERTWALL ((unsigned short) 04000)
#define DOOR ((unsigned short) 010000)
#define FLOOR ((unsigned short) 020000)
#define TUNNEL ((unsigned short) 040000)
#define UNUSED ((unsigned short) 0100000)
#define IS_OBJECT ((unsigned short) 0777) /* all object masks or'd together */
#define CAN_PICK_UP ((unsigned short) 0577)
#define LEATHER 0
#define RING 1
#define SCALE 2
#define CHAIN 3
#define BANDED 4
#define SPLINT 5
#define PLATE 6
#define ARMORS 7
#define BOW 0
#define ARROW 1
#define SHURIKEN 2
#define MACE 3
#define LONG_SWORD 4
#define TWO_HANDED_SWORD 5
#define WEAPONS 6
#define MAX_PACK_COUNT 24
#define PROTECT_ARMOR 0
#define HOLD_MONSTER 1
#define ENCHANT_WEAPON 2
#define ENCHANT_ARMOR 3
#define IDENTIFY 4
#define TELEPORT 5
#define SLEEP 6
#define SCARE_MONSTER 7
#define REMOVE_CURSE 8
#define CREATE_MONSTER 9
#define AGGRAVATE_MONSTER 10
#define SCROLLS 11
#define INCREASE_STRENGTH 0
#define RESTORE_STRENGTH 1
#define HEALING 2
#define EXTRA_HEALING 3
#define POISON 4
#define RAISE_LEVEL 5
#define BLINDNESS 6
#define HALLUCINATION 7
#define DETECT_MONSTER 8
#define DETECT_OBJECTS 9
#define CONFUSION 10
#define POTIONS 11
#define TELEPORT_AWAY 0
#define SLOW_MONSTER 1
#define KILL_MONSTER 2
#define INVISIBILITY 3
#define POLYMORPH 4
#define HASTE_MONSTER 5
#define PUT_TO_SLEEP 6
#define DO_NOTHING 7
#define WANDS 8
#define UNIDENTIFIED ((unsigned char) 0) /* MUST BE ZERO! */
#define IDENTIFIED ((unsigned char) 01)
#define CALLED ((unsigned char) 02)
#define SROWS 24
#define SCOLS 80
#define MAX_TITLE_LENGTH 30
#define MORE "-more-"
#define MAXSYLLABLES 40
#define MAXMETALS 15
#define GOLD_PERCENT 46
struct identify {
short value;
char *title;
char *real;
unsigned char id_status;
};
struct object { /* comment is monster meaning */
unsigned short m_flags; /* monster flags */
char *damage; /* damage it does */
short quantity; /* hit points to kill */
char ichar; /* 'A' is for aquatar */
short kill_exp; /* exp for killing it */
char is_protected; /* level starts */
char is_cursed; /* level ends */
char class; /* chance of hitting you */
char identified; /* F%d/Arwarn/Og/If/Mc/Xc */
unsigned char which_kind; /* item carry/drop % */
char row, col; /* current row,col */
char damage_enchantment; /* fly-trap,medusa,etc */
char quiver; /* monster slowed toggle */
char trow, tcol; /* target row, col */
char to_hit_enchantment;
unsigned short what_is;
char picked_up;
struct object *next_object; /* next monster */
};
typedef struct object object;
struct fighter {
object *armor;
object *weapon;
short hp_current;
short hp_max;
char strength_current;
char strength_max;
object pack;
int gold;
char exp;
int exp_points;
short row, col;
char fchar;
short moves_left;
};
typedef struct fighter fighter;
struct door {
char other_room;
char other_row,
other_col;
};
typedef struct door door;
struct room {
char bottom_row, right_col, left_col, top_row;
char width, height;
door doors[4];
char is_room;
};
typedef struct room room;
extern fighter rogue;
extern room rooms[];
unsigned extern short screen[SROWS][SCOLS];
extern object level_objects;
extern struct identify id_scrolls[];
extern struct identify id_potions[];
extern struct identify id_wands[];
extern struct identify id_weapons[];
extern struct identify id_armors[];
extern object monster_tab[];
extern object level_monsters;
SHAR_EOF
echo shar: extracting room.h
cat - << \SHAR_EOF > room.h
#define MAXROOMS 9
#define NO_ROOM -1 /* these two only for doors[] */
#define DEAD_END -2
#define PASSAGE -3 /* current_room value */
#define SCOREFILE "/usr1/tims/SCORE_FILE"
#define AMULET_LEVEL 26
SHAR_EOF
echo shar: extracting door_course.c
cat - << \SHAR_EOF > door_course.c
#include "object.h"
#include "monster.h"
#include "room.h"
#include "move.h"
door_course(monster, entering, row, col)
object *monster;
short entering, row, col;
{
short trow, tcol, i, j, rn;
short rrow, ccol;
monster->row = row;
monster->col = col;
if (monster_can_see(monster, rogue.row, rogue.col)) {
monster->trow = -1;
return;
}
rn = get_room_number(row, col);
if (entering) { /* entering room */
for (i = 0; i < MAXROOMS; i++) {
if (!rooms[i].is_room || (i == rn)) continue;
for (j = 0; j < 4; j++) {
if (rooms[i].doors[j].other_room == rn) {
monster->trow = rooms[i].doors[j].other_row;
monster->tcol = rooms[i].doors[j].other_col;
if ((monster->trow == row) &&
(monster->tcol == col)) {
continue;
}
return;
}
}
}
} else { /* exiting room */
rrow = row;
ccol = col;
if (get_other_room(rn, &rrow, &ccol)) {
monster->trow = rrow;
monster->tcol = ccol;
} else {
monster->trow = -1;
}
}
}
get_other_room(rn, row, col)
short rn, *row, *col;
{
short d = -1;
if ((screen[*row][(*col)-1]&HORWALL)&&(screen[*row][(*col)+1]&HORWALL)){
if (screen[(*row)+1][*col] & FLOOR) {
d = UP/2;
} else {
d = DOWN/2;
}
} else {
if (screen[*row][(*col)+1] & FLOOR) {
d = LEFT/2;
} else {
d = RIGHT/2;
}
}
if ((d != -1) && (rooms[rn].doors[d].other_room > 0)) {
*row = rooms[rn].doors[d].other_row;
*col = rooms[rn].doors[d].other_col;
return(1);
}
return(0);
}
SHAR_EOF
echo shar: extracting hit.c
cat - << \SHAR_EOF > hit.c
#include <curses.h>
#include "object.h"
#include "move.h"
#include "monster.h"
object *fight_monster = 0;
short detect_monster;
char hit_message[80] = "";
extern short halluc, blind, being_held, interrupted;
monster_hit(monster, other)
register object *monster;
char *other;
{
short damage, hit_chance;
char *mn, *monster_name();
float minus;
if (fight_monster && (monster != fight_monster)) {
fight_monster = 0;
}
monster->trow = -1;
hit_chance = monster->class;
hit_chance -= (rogue.exp + rogue.exp);
if (hit_chance < 0) hit_chance = 0;
if (!fight_monster) {
interrupted = 1;
}
mn = monster_name(monster);
if (!rand_percent(hit_chance)) {
if (!fight_monster) {
sprintf(hit_message + strlen(hit_message),
"the %s misses", (other ? other : mn));
message(hit_message, 0);
hit_message[0] = 0;
}
return;
}
if (!fight_monster) {
sprintf(hit_message + strlen(hit_message), "the %s hit", (other ? other : mn));
message(hit_message, 0);
hit_message[0] = 0;
}
if (monster->ichar != 'F') {
damage = get_damage(monster->damage, 1);
minus = (float) get_armor_class(rogue.armor) * 3.00;
minus = minus/100.00 * (float) damage;
damage -= (short) minus;
} else {
damage = monster->identified++;
}
if (damage > 0) {
rogue_damage(damage, monster);
}
special_hit(monster);
}
rogue_hit(monster)
register object *monster;
{
short damage, hit_chance;
char mbuf[80], *monster_name();
float minus;
short cx;
if (check_xeroc(monster)) {
return;
}
hit_chance = get_hit_chance(rogue.weapon);
if (!rand_percent(hit_chance)) {
if (!fight_monster) {
strcpy(hit_message, "you miss ");
}
goto RET;
}
damage = get_weapon_damage(rogue.weapon);
if (monster_damage(monster, damage)) { /* still alive? */
if (!fight_monster) {
strcpy(hit_message, "you hit ");
}
}
RET: check_orc(monster);
wake_up(monster);
}
rogue_damage(d, monster)
short d;
object *monster;
{
if (d >= rogue.hp_current) {
rogue.hp_current = 0;
print_stats();
killed_by(monster, 0);
}
rogue.hp_current -= d;
print_stats();
}
get_damage(ds, r)
char *ds;
{
register short i = 0, j, n, d, total = 0;
while (ds[i]) {
n = get_number(ds+i);
while (ds[i++] != 'd') ;
d = get_number(ds+i);
while ((ds[i] != '/') && ds[i]) i++;
for (j = 0; j < n; j++) {
if (r) {
total += get_rand(1, d);
} else {
total += d;
}
}
if (ds[i] == '/') {
i++;
}
}
return(total);
}
get_w_damage(obj)
object *obj;
{
char new_damage[12];
register short to_hit, damage;
register short i = 0;
if (!obj) {
return(-1);
}
to_hit = get_number(obj->damage) + obj->to_hit_enchantment;
while (obj->damage[i++] != 'd') ;
damage = get_number(obj->damage + i) + obj->damage_enchantment;
sprintf(new_damage, "%dd%d", to_hit, damage);
return(get_damage(new_damage, 1));
}
get_number(s)
register char *s;
{
register short i = 0;
register short total = 0;
while ((s[i] >= '0') && (s[i] <= '9')) {
total = (10 * total) + (s[i] - '0');
i++;
}
return(total);
}
to_hit(obj)
object *obj;
{
short tohit = 0;
short i = 0;
if (!obj) {
return(1);
}
return(get_number(obj->damage) + obj->to_hit_enchantment);
}
damage_for_strength(s)
{
if (s <= 6) {
return(s-5);
}
if (s <= 14) {
return(1);
}
if (s <= 17) {
return(3);
}
if (s <= 18) {
return(4);
}
if (s <= 20) {
return(5);
}
if (s <= 21) {
return(6);
}
if (s <= 30) {
return(7);
}
return(8);
}
monster_damage(monster, damage)
object *monster;
{
char *mn, *monster_name();
short row, col;
monster->quantity -= damage;
if (monster->quantity <= 0) {
row = monster->row;
col = monster->col;
remove_mask(row, col, MONSTER);
mvaddch(row, col, get_room_char(screen[row][col]));
refresh();
fight_monster = 0;
cough_up(monster);
mn = monster_name(monster);
sprintf(hit_message+strlen(hit_message), "defeated the %s", mn);
message(hit_message, 1);
hit_message[0] = 0;
add_exp(monster->kill_exp);
print_stats();
remove_from_pack(monster, &level_monsters);
if (monster->ichar == 'F') {
being_held = 0;
}
free(monster);
return(0);
}
return(1);
}
fight(to_the_death)
short to_the_death;
{
short ch;
short row, col;
short first_miss = 1;
short possible_damage;
object *object_at();
while (!is_direction(ch = getchar())) {
putchar(7);
fflush(stdout);
if (first_miss) {
message("direction?", 0);
first_miss = 0;
}
}
check_message();
if (ch == CANCEL) {
return;
}
row = rogue.row; col = rogue.col;
get_dir_rc(ch, &row, &col);
if (!(screen[row][col] & MONSTER) || blind || hiding_xeroc(row, col)) {
NM: message("I see no monster there", 0);
return;
}
fight_monster = object_at(&level_monsters, row, col);
if ((fight_monster->m_flags & IS_INVIS) && !detect_monster) {
goto NM;
}
possible_damage = ((get_damage(fight_monster->damage, 0) * 2) / 3);
while (fight_monster) {
single_move_rogue(ch, 0);
if (!to_the_death && rogue.hp_current <= possible_damage) {
fight_monster = 0;
}
if (!(screen[row][col] & MONSTER) || interrupted) {
fight_monster = 0;
}
}
}
get_dir_rc(dir, row, col)
short dir;
short *row, *col;
{
switch(dir) {
case 'h':
if (*col > 0) {
(*col)--;
}
break;
case 'j':
if (*row < (LINES-2)) {
(*row)++;
}
break;
case 'k':
if (*row > MIN_ROW) {
(*row)--;
}
break;
case 'l':
if (*col < (COLS-1)) {
(*col)++;
}
break;
case 'y':
if ((*row > MIN_ROW) && (*col > 0)) {
(*row)--;
(*col)--;
}
break;
case 'u':
if ((*row > MIN_ROW) && (*col < (COLS-1))) {
(*row)--;
(*col)++;
}
break;
case 'n':
if ((*row < (LINES-2)) && (*col < (COLS-1))) {
(*row)++;
(*col)++;
}
break;
case 'b':
if ((*row < (LINES-2)) && (*col > 0)) {
(*row)++;
(*col)--;
}
break;
}
}
get_hit_chance(weapon)
object *weapon;
{
short hit_chance;
hit_chance = 40;
hit_chance += 3 * to_hit(weapon);
hit_chance += (rogue.exp + rogue.exp);
if (hit_chance > 100) hit_chance = 100;
return(hit_chance);
}
get_weapon_damage(weapon)
object *weapon;
{
short damage;
damage = get_w_damage(weapon);
damage += damage_for_strength(rogue.strength_current);
damage += ((rogue.exp + 1) / 2);
return(damage);
}
SHAR_EOF
echo shar: extracting init.c
cat - << \SHAR_EOF > init.c
#include <curses.h>
#include "object.h"
#include "room.h"
#include <sgtty.h>
#include <signal.h>
char *player_name;
short cant_int = 0, did_int = 0;
extern char ichars[];
extern short party_room;
init()
{
char *getlogin();
short i;
int tstp(), byebye(), onintr();
if (!(player_name = getlogin())) {
fprintf(stderr, "Hey! Who are you?");
exit(1);
}
printf("Hello %s, just a moment while I dig the dungeon...",
player_name);
fflush(stdout);
initscr();
for (i = 0; i < 26; i++) {
ichars[i] = 0;
}
start_window();
signal(SIGTSTP, tstp);
signal(SIGINT, onintr);
signal(SIGQUIT, byebye);
if ((LINES < 24) || (COLS < 80)) {
clean_up("must be played on 24 x 80 screen");
}
LINES = SROWS;
srandom(getpid());
shuffle_colors();
mix_metals();
make_scroll_titles();
level_objects.next_object = 0;
level_monsters.next_object = 0;
player_init();
}
player_init()
{
object *get_an_object(), *obj;
rogue.pack.next_object = 0;
obj = get_an_object();
get_food(obj);
add_to_pack(obj, &rogue.pack, 1);
obj = get_an_object(); /* initial armor */
obj->what_is = ARMOR;
obj->which_kind = RING;
obj->class = RING+2;
obj->is_cursed = obj->is_protected = 0;
obj->damage_enchantment = 1;
obj->identified = 1;
add_to_pack(obj, &rogue.pack, 1);
rogue.armor = obj;
obj = get_an_object(); /* initial weapons */
obj->what_is = WEAPON;
obj->which_kind = MACE;
get_weapon_thd(obj);
obj->is_cursed = 0;
obj->damage = "2d3";
obj->to_hit_enchantment = obj->damage_enchantment = 1;
obj->identified = 1;
add_to_pack(obj, &rogue.pack, 1);
rogue.weapon = obj;
obj = get_an_object();
obj->what_is = WEAPON;
obj->which_kind = BOW;
get_weapon_thd(obj);
obj->is_cursed = 0;
obj->damage = "1d2";
obj->to_hit_enchantment = 1;
obj->damage_enchantment = 0;
obj->identified = 1;
add_to_pack(obj, &rogue.pack, 1);
obj = get_an_object();
obj->what_is = WEAPON;
obj->which_kind = ARROW;
obj->quantity = get_rand(25, 35);
get_weapon_thd(obj);
obj->is_cursed = 0;
obj->damage = "1d2";
obj->to_hit_enchantment = 0;
obj->damage_enchantment = 0;
obj->identified = 1;
add_to_pack(obj, &rogue.pack, 1);
}
clean_up(estr)
char *estr;
{
move(LINES-1, 0);
refresh();
stop_window();
printf("\n%s\n", estr);
exit(0);
}
start_window()
{
crmode();
noecho();
nonl();
edchars(0);
}
stop_window()
{
endwin();
edchars(1);
}
byebye()
{
clean_up("Okay, bye bye!");
}
onintr()
{
if (cant_int) {
did_int = 1;
} else {
signal(SIGINT, SIG_IGN);
check_message();
message("interrupt", 1);
signal(SIGINT, onintr);
}
}
edchars(mode)
short mode;
{
static short called_before = 0;
static struct ltchars ltc_orig;
static struct tchars tc_orig;
struct ltchars ltc_temp;
struct tchars tc_temp;
if (!called_before) {
called_before = 1;
ioctl(0, TIOCGETC, &tc_orig);
ioctl(0, TIOCGLTC, <c_orig);
}
ltc_temp = ltc_orig;
tc_temp = tc_orig;
if (!mode) {
ltc_temp.t_suspc = ltc_temp.t_dsuspc = ltc_temp.t_rprntc =
ltc_temp.t_flushc = ltc_temp.t_werasc = ltc_temp.t_lnextc = -1;
}
ioctl(0, TIOCSETC, &tc_temp);
ioctl(0, TIOCSLTC, <c_temp);
}
SHAR_EOF
echo shar: extracting inventory.c
cat - << \SHAR_EOF > inventory.c
#include <curses.h>
#include "object.h"
#include "macros.h"
#include "move.h"
char *metals[MAXMETALS] = {
"steel ",
"bronze ",
"gold ",
"silver ",
"copper ",
"nickel ",
"cobalt ",
"tin ",
"iron ",
"magnesium ",
"chrome ",
"carbon ",
"platinum ",
"silicon ",
"titanium "
};
char *syllables[MAXSYLLABLES] = {
"blech ",
"foo ",
"barf ",
"rech ",
"bar ",
"blech ",
"quo ",
"bloto ",
"woh ",
"caca ",
"blorp ",
"erp ",
"festr ",
"rot ",
"slie ",
"snorf ",
"iky ",
"yuky ",
"ooze ",
"ah ",
"bahl ",
"zep ",
"druhl ",
"flem ",
"behil ",
"arek ",
"mep ",
"zihr ",
"grit ",
"kona ",
"kini ",
"ichi ",
"niah ",
"ogr ",
"ooh ",
"ighr ",
"coph ",
"swerr ",
"mihln ",
"poxi "
};
inventory(pack, mask)
object *pack;
unsigned short mask;
{
object *obj;
short i = 0, j, maxlen = 0, n;
char descriptions[MAX_PACK_COUNT+1][SCOLS];
short row, col;
obj = pack->next_object;
while (obj) {
if (obj->what_is & mask) {
descriptions[i][0] = ' ';
descriptions[i][1] = obj->ichar;
descriptions[i][2] = ')';
descriptions[i][3] = ' ';
get_description(obj, descriptions[i]+4);
if ((n = strlen(descriptions[i])) > maxlen) {
maxlen = n;
}
i++;
}
obj = obj->next_object;
}
strcpy(descriptions[i++], " --press space to continue--");
if (maxlen < 27) maxlen = 27;
col = COLS - (maxlen + 2);
for (row = 0; ((row < i) && (row < SROWS)); row++) {
if (row > 0) {
for (j = col; j < COLS; j++) {
descriptions[row-1][j-col] = mvinch(row, j);
}
descriptions[row-1][j-col] = 0;
}
mvaddstr(row, col, descriptions[row]);
clrtoeol();
}
refresh();
wait_for_ack(0);
move(0, 0);
clrtoeol();
for (j = 1; j < i; j++) {
mvaddstr(j, col, descriptions[j-1]);
}
}
shuffle_colors()
{
short i, j, k;
for (i = 0; i <= POTIONS; i++) {
j = get_rand(0, (POTIONS - 1));
k = get_rand(0, (POTIONS - 1));
swap_string(id_potions[j].title, id_potions[k].title);
}
}
make_scroll_titles()
{
short i, j, n;
short sylls, s;
for (i = 0; i < SCROLLS; i++) {
sylls = get_rand(2, 5);
strcpy(id_scrolls[i].title, "'");
for (j = 0; j < sylls; j++) {
s = get_rand(1, (MAXSYLLABLES-1));
strcat(id_scrolls[i].title, syllables[s]);
}
n = strlen(id_scrolls[i].title);
strcpy(id_scrolls[i].title+(n-1), "' ");
}
}
get_description(obj, description)
object *obj;
char *description;
{
char *name_of(), *item_name;
struct identify *id_table, *get_id_table();
char more_info[32];
if (obj->what_is == AMULET) {
strcpy(description, "the amulet of Yendor ");
return;
}
item_name = name_of(obj);
if (obj->what_is == GOLD) {
sprintf(description, "%d pieces of gold", obj->quantity);
return;
}
if (obj->what_is != ARMOR) {
if (obj->quantity == 1) {
strcpy(description, "a ");
} else {
sprintf(description, "%d ", obj->quantity);
}
}
if (obj->what_is == FOOD) {
strcat(description, item_name);
strcat(description, "of food ");
return;
}
id_table = get_id_table(obj);
if (obj->what_is & (WEAPON | ARMOR | WAND)) goto CHECK;
switch(id_table[obj->which_kind].id_status) {
case UNIDENTIFIED:
CHECK: switch(obj->what_is) {
case SCROLL:
strcat(description, item_name);
strcat(description, "entitled: ");
strcat(description, id_table[obj->which_kind].title);
break;
case POTION:
strcat(description, id_table[obj->which_kind].title);
strcat(description, item_name);
break;
case WAND:
if (obj->identified ||
(id_table[obj->which_kind].id_status == IDENTIFIED)) {
goto ID;
}
if (id_table[obj->which_kind].id_status == CALLED) {
goto CALL;
}
strcat(description, id_table[obj->which_kind].title);
strcat(description, item_name);
break;
case ARMOR:
if (obj->identified) {
goto ID;
}
strcpy(description, id_table[obj->which_kind].title);
break;
case WEAPON:
if (obj->identified) {
goto ID;
}
strcat(description, name_of(obj));
if (obj == rogue.weapon) {
strcat(description, "in hand");
}
break;
}
break;
case CALLED:
CALL: switch(obj->what_is) {
case SCROLL:
case POTION:
case WAND:
strcat(description, item_name);
strcat(description, "called ");
strcat(description, id_table[obj->which_kind].title);
goto MI;
break;
}
break;
case IDENTIFIED:
ID: switch(obj->what_is) {
case SCROLL:
case POTION:
strcat(description, item_name);
strcat(description, id_table[obj->which_kind].real);
break;
case WAND:
strcat(description, item_name);
strcat(description, id_table[obj->which_kind].real);
MI: if (obj->identified) {
sprintf(more_info, "[%d]", obj->class);
strcat(description, more_info);
}
break;
case ARMOR:
sprintf(description, "%s%d ",
((obj->damage_enchantment >= 0) ? "+" : ""),
obj->damage_enchantment);
strcat(description, id_table[obj->which_kind].title);
sprintf(more_info, "[%d] ", get_armor_class(obj));
strcat(description, more_info);
if (obj == rogue.armor) {
strcat(description, "being worn");
}
break;
case WEAPON:
sprintf(description+strlen(description), "%s%d,%s%d ",
((obj->to_hit_enchantment >= 0) ? "+" : ""),
obj->to_hit_enchantment,
((obj->damage_enchantment >= 0) ? "+" : ""),
obj->damage_enchantment);
strcat(description, name_of(obj));
if (obj == rogue.weapon) {
strcat(description, "in hand");
}
break;
}
break;
}
}
mix_metals()
{
short i, j, k;
for (i = 0; i <= MAXMETALS; i++) {
j = get_rand(0, MAXMETALS-1);
k = get_rand(0, MAXMETALS-1);
swap_string(metals[j], metals[k]);
}
for (i = 0; i < WANDS; i++) {
strcpy(id_wands[i].title, metals[i]);
}
}
single_inventory()
{
short ch;
char description[SCOLS];
object *obj, *get_letter_object();
ch = get_pack_letter("inventory what? ", IS_OBJECT);
if (ch == CANCEL) {
return;
}
if (!(obj = get_letter_object(ch))) {
message("No such item.", 0);
return;
}
strcpy(description, "x) ");
description[0] = ch;
get_description(obj, description+3);
message(description, 0);
}
struct identify *get_id_table(obj)
object *obj;
{
switch(obj->what_is) {
case SCROLL:
return(id_scrolls);
break;
case POTION:
return(id_potions);
break;
case WAND:
return(id_wands);
break;
case WEAPON:
return(id_weapons);
break;
case ARMOR:
return(id_armors);
break;
}
}
SHAR_EOF
echo shar: extracting level.c
cat - << \SHAR_EOF > level.c
#include <curses.h>
#include "move.h"
#include "object.h"
#include "room.h"
#include "macros.h"
short current_level = 0, max_level = 1;
extern short current_room;
char *hunger_str = "";
short party_room;
extern short being_held;
extern short detect_monster, has_amulet;
int level_points[] = {
10,
20,
40,
80,
160,
320,
640,
1300,
2600,
5200,
10000,
20000,
40000,
80000,
160000,
320000,
1000000,
10000000
};
make_level()
{
short i;
short must_exist1, must_exist2;
party_room = -1;
if (current_level < 126) {
current_level++;
}
if (current_level > max_level) max_level = current_level;
if (rand_percent(50)) {
must_exist1 = 1;
must_exist2 = 7;
} else {
must_exist1 = 3;
must_exist2 = 5;
}
for (i = 0; i < MAXROOMS; i++) {
make_room(i, must_exist1, must_exist2, 4);
}
try_rooms(0, 1, 2);
try_rooms(0, 3, 6);
try_rooms(2, 5, 8);
try_rooms(6, 7, 8);
for (i = 0; i < (MAXROOMS); i++) {
connect_rooms(i, i+1, must_exist1, must_exist2, 4);
if (i < (MAXROOMS-3)) {
connect_rooms(i, i+3, must_exist1, must_exist2, 4);
}
}
add_dead_ends();
if (!has_amulet && (current_level >= AMULET_LEVEL)) {
put_amulet();
}
}
make_room(n, r1, r2, r3)
{
short left_col, right_col, top_row, bottom_row;
short width, height;
short row_offset, col_offset;
short i, j;
short ch;
switch(n) {
case 0:
left_col = 0;
right_col = COL1-1;
top_row = MIN_ROW;
bottom_row = ROW1-1;
break;
case 1:
left_col = COL1+1;
right_col = COL2-1;
top_row = MIN_ROW;
bottom_row = ROW1-1;
break;
case 2:
left_col = COL2+1;
right_col = COLS-1;
top_row = MIN_ROW;
bottom_row = ROW1-1;
break;
case 3:
left_col = 0;
right_col = COL1-1;
top_row = ROW1+1;
bottom_row = ROW2-1;
break;
case 4:
left_col = COL1+1;
right_col = COL2-1;
top_row = ROW1+1;
bottom_row = ROW2-1;
break;
case 5:
left_col = COL2+1;
right_col = COLS-1;
top_row = ROW1+1;
bottom_row = ROW2-1;
break;
case 6:
left_col = 0;
right_col = COL1-1;
top_row = ROW2+1;
bottom_row = LINES - 2;
break;
case 7:
left_col = COL1+1;
right_col = COL2-1;
top_row = ROW2+1;
bottom_row = LINES - 2;
break;
case 8:
left_col = COL2+1;
right_col = COLS-1;
top_row = ROW2+1;
bottom_row = LINES - 2;
break;
}
if ((n != r1) && (n != r2) && (n != r3) && rand_percent(45)) {
goto END;
}
height = get_rand(4, (bottom_row-top_row+1));
width = get_rand(7, (right_col-left_col-2));
row_offset = get_rand(0, ((bottom_row-top_row)-height+1));
col_offset = get_rand(0, ((right_col-left_col)-width+1));
top_row += row_offset;
bottom_row = top_row + height - 1;
left_col += col_offset;
right_col = left_col + width - 1;
rooms[n].is_room = 1;
for (i = top_row; i <= bottom_row; i++) {
for (j = left_col; j <= right_col; j++) {
if ((i == top_row) || (i == bottom_row)) {
ch = HORWALL;
} else if (((i != top_row) && (i != bottom_row)) &&
((j == left_col) || (j == right_col))) {
ch = VERTWALL;
} else {
ch = FLOOR;
}
add_mask(i, j, ch);
}
}
END: rooms[n].top_row = top_row;
rooms[n].bottom_row = bottom_row;
rooms[n].left_col = left_col;
rooms[n].right_col = right_col;
rooms[n].height = height;
rooms[n].width = width;
}
connect_rooms(room1, room2, m1, m2, m3)
{
if ((room1 != m1) && (room1 != m2) && (room1 != m3) && (room2 != m1) &&
(room2 != m2) && (room2 != m3)) {
if (rand_percent(80)) {
return;
}
}
if (adjascent(room1, room2)) {
do_connect(room1, room2);
}
}
do_connect(room1, room2)
{
short row1, col1, row2, col2, dir;
if ((rooms[room1].left_col > rooms[room2].right_col) &&
(on_same_row(room1, room2))) {
put_door(room1, LEFT, &row1, &col1);
put_door(room2, RIGHT, &row2, &col2);
dir = LEFT;
} else if ((rooms[room2].left_col > rooms[room1].right_col) &&
(on_same_row(room1, room2))) {
put_door(room1, RIGHT, &row1, &col1);
put_door(room2, LEFT, &row2, &col2);
dir = RIGHT;
} else if ((rooms[room1].top_row > rooms[room2].bottom_row) &&
(on_same_col(room1, room2))) {
put_door(room1, UP, &row1, &col1);
put_door(room2, DOWN, &row2, &col2);
dir = UP;
} else if ((rooms[room2].top_row > rooms[room1].bottom_row) &&
(on_same_col(room1, room2))) {
put_door(room1, DOWN, &row1, &col1);
put_door(room2, UP, &row2, &col2);
dir = DOWN;
} else {
return;
}
draw_simple_passage(row1, col1, row2, col2, dir);
if (rand_percent(10)) {
draw_simple_passage(row1, col1, row2, col2, dir);
}
rooms[room1].doors[dir/2].other_room = room2;
rooms[room1].doors[dir/2].other_row = row2;
rooms[room1].doors[dir/2].other_col = col2;
rooms[room2].doors[(((dir+4)%8)/2)].other_room = room1;
rooms[room2].doors[(((dir+4)%8)/2)].other_row = row1;
rooms[room2].doors[(((dir+4)%8)/2)].other_col = col1;
}
clear_level()
{
int i, j;
for (i = 0; i < MAXROOMS; i++) {
rooms[i].is_room = 0;
for (j = 0; j < 4; j++) {
rooms[i].doors[j].other_room = NO_ROOM;
}
}
for (i = 0; i < SROWS; i++) {
for (j = 0; j < SCOLS; j++) {
screen[i][j] = BLANK;
}
}
detect_monster = 0;
being_held = 0;
}
print_stats()
{
char mbuf[100];
sprintf(mbuf, "Level: %d Gold: %3d Hp: %2d(%d) Str: %2d(%d) Arm: %2d Exp: %d/%d %s", current_level, rogue.gold, rogue.hp_current, rogue.hp_max, rogue.strength_current, rogue.strength_max, get_armor_class(rogue.armor), rogue.exp, rogue.exp_points, hunger_str);
mvaddstr(LINES-1, 0, mbuf);
clrtoeol();
refresh();
}
add_mask(row, col, mask)
int row, col;
unsigned short mask;
{
if (mask == DOOR) {
remove_mask(row, col, HORWALL);
remove_mask(row, col, VERTWALL);
}
screen[row][col] |= mask;
/*switch(mask) {
case FLOOR:
mvaddch(row, col, '.');
break;
case STAIRS:
mvaddch(row, col, '%');
break;
case DOOR:
mvaddch(row, col, '+');
break;
case VERTWALL:
mvaddch(row, col, '|');
break;
case HORWALL:
mvaddch(row, col, '-');
break;
case TUNNEL:
mvaddch(row, col, '#');
break;
}*/
}
remove_mask(row, col, mask)
{
screen[row][col] &= (~mask);
}
adjascent(room1, room2)
{
if ((!rooms[room1].is_room) || (!rooms[room2].is_room)) {
return(0);
}
two_sort(room1, room2);
return((on_same_col(room1,room2) || on_same_row(room1, room2))
&& (((room2 - room1) == 1) || (((room2 - room1) == 3))));
}
put_door(rn, dir, row, col)
short *row, *col;
{
switch(dir) {
case UP:
case DOWN:
*row = ((dir == UP) ? rooms[rn].top_row :
rooms[rn].bottom_row);
*col = get_rand(rooms[rn].left_col+1,
rooms[rn].right_col-1);
break;
case RIGHT:
case LEFT:
*row = get_rand(rooms[rn].top_row+1,
rooms[rn].bottom_row-1);
*col = (dir == LEFT) ? rooms[rn].left_col :
rooms[rn].right_col;
break;
}
add_mask(*row, *col, DOOR);
}
draw_simple_passage(row1, col1, row2, col2, dir)
{
short i, middle;
if ((dir == LEFT) || (dir == RIGHT)) {
if (col2 < col1) {
swap(row1, row2);
swap(col1, col2);
}
middle = get_rand(col1+1, col2-1);
for (i = col1+1; i != middle; i++) {
add_mask(row1, i, TUNNEL);
}
for (i = row1; i != row2; i += (row1 > row2) ? -1 : 1) {
add_mask(i, middle, TUNNEL);
}
for (i = middle; i != col2; i++) {
add_mask(row2, i, TUNNEL);
}
} else {
if (row2 < row1) {
swap(row1, row2);
swap(col1, col2);
}
middle = get_rand(row1+1, row2-1);
for (i = row1+1; i != middle; i++) {
add_mask(i, col1, TUNNEL);
}
for (i = col1; i != col2; i += (col1 > col2) ? -1 : 1) {
add_mask(middle, i, TUNNEL);
}
for (i = middle; i != row2; i++) {
add_mask(i, col2, TUNNEL);
}
}
}
on_same_row(room1, room2)
{
return((room1 / 3) == (room2 / 3));
}
on_same_col(room1, room2)
{
return((room1 % 3) == (room2 % 3));
}
add_dead_ends()
{
short i, j;
short start;
short row, col, distance, dir;
short found;
short dead_end_percent;
if (current_level <= 2) return;
start = get_rand(0, (MAXROOMS-1));
dead_end_percent = 12 + current_level + current_level;
for (i = 0; i < MAXROOMS; i++) {
j = ((start + i) % MAXROOMS);
if (rooms[j].is_room) continue;
if (!rand_percent(dead_end_percent)) continue;
row = rooms[j].top_row + get_rand(0, 6);
col = rooms[j].left_col + get_rand(0, 19);
found = 0;
while (!found) {
distance = get_rand(8, 20);
dir = get_rand(0, 3) * 2;
for (j = 0; (j < distance) && !found; j++) {
switch(dir) {
case UP:
if ((row - 1) >= MIN_ROW) {
--row;
}
break;
case RIGHT:
if ((col + 1) < (COLS-1)) {
++col;
}
break;
case DOWN:
if ((row + 1) < (LINES-2)) {
++row;
}
break;
case LEFT:
if ((col - 1) > 0) {
--col;
}
break;
}
if ((screen[row][col] & VERTWALL) ||
(screen[row][col] & HORWALL) ||
(screen[row][col] & DOOR)) {
break_in(row, col, screen[row][col],
dir);
found = 1;
} else {
add_mask(row, col, TUNNEL);
}
}
}
}
}
break_in(row, col, ch, dir)
{
short rn;
short i, drow, dcol;
if (ch == DOOR) {
return;
}
rn = get_room_number(row, col);
if (ch == VERTWALL) {
if (col == rooms[rn].left_col) {
if (rooms[rn].doors[LEFT/2].other_room != NO_ROOM) {
drow = door_row(rn, LEFT);
for (i = row; i != drow;
i += (drow < row) ? -1 : 1) {
add_mask(i, col-1, TUNNEL);
}
} else {
rooms[rn].doors[LEFT/2].other_room = DEAD_END;
add_mask(row, col, DOOR);
}
} else {
if (rooms[rn].doors[RIGHT/2].other_room != NO_ROOM) {
drow = door_row(rn, RIGHT);
for (i = row; i != drow;
i += (drow < row) ? -1 : 1) {
add_mask(i, col+1, TUNNEL);
}
} else {
rooms[rn].doors[RIGHT/2].other_room = DEAD_END;
add_mask(row, col, DOOR);
}
}
} else { /* break in througt top or bottom --- */
if (col == rooms[rn].left_col) {
if (row == MIN_ROW) {
add_mask(row+1, col-1, TUNNEL);
break_in(row+1, col, VERTWALL, RIGHT);
} else if (row == (LINES-2)) {
add_mask(row-1, col-1, TUNNEL);
break_in(row-1, col, VERTWALL, RIGHT);
} else {
if (row == rooms[rn].top_row) {
if (dir == RIGHT) {
add_mask(row-1, col-1, TUNNEL);
add_mask(row-1, col, TUNNEL);
}
add_mask(row-1, col+1, TUNNEL);
break_in(row, col+1, HORWALL, DOWN);
} else {
if (dir == RIGHT) {
add_mask(row+1, col-1, TUNNEL);
add_mask(row+1, col, TUNNEL);
}
add_mask(row+1, col+1, TUNNEL);
break_in(row, col+1, HORWALL, UP);
}
}
return;
} else if (col == rooms[rn].right_col) {
if (row == MIN_ROW) {
add_mask(row+1, col+1, TUNNEL);
break_in(row+1, col, VERTWALL, LEFT);
} else if (row == (LINES-2)) {
add_mask(row-1, col+1, TUNNEL);
break_in(row-1, col, VERTWALL, LEFT);
} else {
if (row == rooms[rn].top_row) {
if (dir == DOWN) {
add_mask(row-1, col+1, TUNNEL);
add_mask(row, col+1, TUNNEL);
}
add_mask(row+1, col+1, TUNNEL);
break_in(row+1, col, VERTWALL, LEFT);
} else {
if (dir == UP) {
add_mask(row+1, col+1, TUNNEL);
add_mask(row, col+1, TUNNEL);
}
add_mask(row-1, col+1, TUNNEL);
break_in(row-1, col, VERTWALL, LEFT);
}
}
return;
}
if (row == rooms[rn].top_row) {
if (rooms[rn].doors[UP/2].other_room != NO_ROOM) {
dcol = door_col(rn, UP);
for (i = col; i != dcol;
i += (dcol < col) ? -1 : 1) {
add_mask(row-1, i, TUNNEL);
}
} else {
rooms[rn].doors[UP/2].other_room = DEAD_END;
add_mask(row, col, DOOR);
}
} else {
if (rooms[rn].doors[DOWN/2].other_room != NO_ROOM) {
dcol = door_col(rn, DOWN);
for (i = col; i != dcol;
i += (dcol < col) ? -1 : 1) {
add_mask(row+1, i, TUNNEL);
}
} else {
rooms[rn].doors[DOWN/2].other_room = DEAD_END;
add_mask(row, col, DOOR);
}
}
}
}
door_row(rn, dir)
{
short i, col, row;
if (rooms[rn].doors[dir/2].other_room == NO_ROOM) {
return(-1);
}
row = rooms[rn].top_row;
switch(dir) {
case LEFT:
col = rooms[rn].left_col;
for (i = row; !(screen[i][col] & DOOR); i++) ;
break;
case RIGHT:
col = rooms[rn].right_col;
for (i = row; !(screen[i][col] & DOOR); i++) ;
break;
}
return(i);
}
door_col(rn, dir)
{
short i, col, row;
if (rooms[rn].doors[dir/2].other_room == NO_ROOM) {
return(-1);
}
col = rooms[rn].left_col;
switch(dir) {
case UP:
row = rooms[rn].top_row;
for (i = col; !(screen[row][i] & DOOR); i++) ;
break;
case DOWN:
row = rooms[rn].bottom_row;
for (i = col; !(screen[row][i] & DOOR); i++) ;
break;
}
return(i);
}
put_player()
{
for (;;) {
get_rand_row_col(&rogue.row, &rogue.col, (FLOOR | IS_OBJECT));
current_room = get_room_number(rogue.row, rogue.col);
if (current_room != party_room) {
break;
}
}
}
check_down()
{
if (screen[rogue.row][rogue.col] & STAIRS) {
return(1);
}
message("I see no way down", 0);
return(0);
}
check_up()
{
if (!(screen[rogue.row][rogue.col] & STAIRS)) {
message("I see no way up", 0);
return(0);
}
if (!has_amulet) {
message("your way is magically blocked", 0);
return(0);
}
if (current_level == 1) {
win();
} else {
current_level -= 2;
return(1);
}
}
add_exp(e)
{
char mbuf[40];
short new_exp;
short i, hp;
rogue.exp_points += e;
if (rogue.exp_points >= level_points[rogue.exp-1]) {
new_exp = get_exp_level(rogue.exp_points);
for (i = rogue.exp+1; i <= new_exp; i++) {
sprintf(mbuf, "welcome to level %d", i);
message(mbuf, 0);
hp = get_rand(3, 10);
rogue.hp_current += hp;
rogue.hp_max += hp;
print_stats();
}
rogue.exp = new_exp;
}
print_stats();
}
get_exp_level(e)
{
short i;
for (i = 0; i < 50; i++) {
if (level_points[i] > e) {
break;
}
}
return(i+1);
}
try_rooms(r1, r2, r3)
{
if (rooms[r1].is_room && !rooms[r2].is_room && rooms[r3].is_room) {
if (rand_percent(75)) {
do_connect(r1, r3);
}
}
}
SHAR_EOF
echo shar: extracting main.c
cat - << \SHAR_EOF > main.c
#include <curses.h>
#include "object.h"
main()
{
init();
for (;;) {
clear_level();
make_level();
put_objects();
put_stairs();
put_monsters();
put_player();
light_up_room();
print_stats();
play_level();
free_stuff(&level_objects);
free_stuff(&level_monsters);
clear();
}
}
SHAR_EOF
echo shar: extracting message.c
cat - << \SHAR_EOF > message.c
#include <curses.h>
#include "object.h"
#include "move.h"
char message_cleared = 1;
char message_line[SCOLS] = "";
short message_col;
extern short cant_int, did_int;
extern short interrupted;
message(msg, intrpt)
char *msg;
short intrpt;
{
if (intrpt) {
interrupted = 1;
}
cant_int = 1;
slurp();
if (!message_cleared) {
mvaddstr(MIN_ROW-1, message_col, MORE);
refresh();
wait_for_ack(0);
check_message();
}
strcpy(message_line, msg);
mvaddstr(MIN_ROW-1, 0, msg);
addch(' ');
refresh();
message_cleared = 0;
message_col = strlen(msg);
if (did_int) {
onintr();
}
cant_int = 0;
}
remessage()
{
if (message_line[0]) {
message(message_line, 0);
}
}
check_message()
{
register i;
if (message_cleared) {
return;
}
move(MIN_ROW-1, 0);
clrtoeol();
move(rogue.row, rogue.col);
refresh();
message_cleared = 1;
}
get_input_line(buf, if_cancelled)
char *buf;
char *if_cancelled;
{
short ch;
short i = 0;
message("call it:", 0);
while (((ch = getchar()) != '\r') && (ch != '\n') && (ch != CANCEL)) {
if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) {
buf[i++] = ch;
addch(ch);
}
if ((ch == '\b') && (i > 0)) {
mvaddch(0, --i + 9, ' ');
move(MIN_ROW-1, i+9);
}
refresh();
}
check_message();
if (ch == CANCEL) {
if (if_cancelled) {
message(if_cancelled, 0);
}
return(0);
}
buf[i++] = ' ';
buf[i] = 0;
return(1);
}
slurp()
{
long ln;
short i, n;
do {
ioctl(0, FIONREAD, &ln);
n = stdin->_cnt + ln;
for (i = 0; i < ln; i++) getchar();
} while (ln > 0L);
}
SHAR_EOF