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