Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!bellcore!decvax!decwrl!glacier!hplabs!tektronix!teklds!zeus!tims From: tims@zeus.UUCP (Tim Stoehr) Newsgroups: net.sources.games Subject: rogue clone, again(groan!), this time in small pieces, part 3 of 3. Message-ID: <57@zeus.UUCP> Date: Sun, 16-Mar-86 15:35:50 EST Article-I.D.: zeus.57 Posted: Sun Mar 16 15:35:50 1986 Date-Received: Wed, 19-Mar-86 04:15:40 EST Distribution: net Organization: Tektronix, Beaverton OR Lines: 2104 #!/bin/sh-----cut here-----cut here-----cut here-----cut here----- # shar: Shell Archiver # Run the following text with /bin/sh to create: # play.c # random.c # room.c # score.c # special_hit.c # throw.c # use.c # zap.c echo shar: extracting play.c cat - << \SHAR_EOF > play.c #include #include "object.h" #include "move.h" short interrupted = 0; extern short party_room, detect_monster; extern char hit_message[]; play_level() { short ch; int count = 0; for (;;) { interrupted = 0; if (hit_message[0]) { message(hit_message); hit_message[0] = 0; } move(rogue.row, rogue.col); refresh(); ch = getchar(); check_message(); CH: switch(ch) { case '.': rest((count > 0) ? count : 1); break; case 'i': inventory(&rogue.pack, IS_OBJECT); break; /*case 'p': inventory(&level_objects, IS_OBJECT); break;*/ case 'f': fight(0); break; case 'F': fight(1); break; case 'h': case 'j': case 'k': case 'l': case 'y': case 'u': case 'n': case 'b': single_move_rogue(ch, 1); break; case 'H': case 'J': case 'K': case 'L': case 'B': case 'Y': case 'U': case 'N': case '\010': case '\012': case '\013': case '\014': case '\031': case '\025': case '\016': case '\002': multiple_move_rogue(ch); break; case 'e': eat(); break; case 'q': quaff(); break; case 'r': read_scroll(); break; case 'm': move_onto(); break; case 'd': drop(); break; case '\020': remessage(); break; case '>': if (check_down()) { return; } break; case '<': if (check_up()) { return; } break; case 'I': single_inventory(); break; case '\022': wrefresh(curscr); break; case 'T': take_off(); break; case 'W': case 'P': wear(); break; case 'w': wield(); break; case 'c': call_it(); break; case 'z': zapp(); break; case 't': throw(); break; case '\032': tstp(); break; case '!': shell(); break; case 'v': message("i_rogue: Version 1.0. (stoehr was here)", 0); break; case 'Q': quit(); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': count = 0; do { count = (10 * count) + (ch - '0'); ch = getchar(); } while ((ch >= '0') && (ch <= '9')); goto CH; break; case ' ': break; default: message("unknown command"); break; } } } SHAR_EOF echo shar: extracting random.c cat - << \SHAR_EOF > random.c #include "macros.h" get_rand(x, y) int x, y; { long r, random(); int s; two_sort(x, y); r = random(); r = (r % ((y-x)+1)) + x; s = (int) r; return(s); } rand_percent(percentage) { return(get_rand(1, 100) <= percentage); } SHAR_EOF echo shar: extracting room.c cat - << \SHAR_EOF > room.c #include #include "room.h" #include "object.h" #include "move.h" short current_room; room rooms[MAXROOMS]; extern short detect_monster; extern short blind; light_up_room() { short i, j; if (blind) return; for (i = rooms[current_room].top_row; i <= rooms[current_room].bottom_row; i++) { for (j = rooms[current_room].left_col; j <= rooms[current_room].right_col; j++) { mvaddch(i, j, get_room_char(screen[i][j], i, j)); } } mvaddch(rogue.row, rogue.col, rogue.fchar); } light_passage(row, col) { short i, j, i_end, j_end; if (blind) return; i_end = (row < (LINES-2)) ? 1 : 0; j_end = (col < (COLS-1)) ? 1 : 0; for (i = ((row > MIN_ROW) ? -1 : 0); i <= i_end; i++) { for (j = ((col > 0) ? -1 : 0); j <= j_end; j++) { if (is_passable(row+i, col+j)) { mvaddch(row+i, col+j, get_room_char(screen[row+i][col+j], row+i, col+j)); } } } } darken_room(rn) short rn; { short i, j; if (blind) return; for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) { for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) { if (!is_object(i, j) && !(detect_monster && (screen[i][j] & MONSTER))) { if (!hiding_xeroc(i, j)) { mvaddch(i, j, ' '); } } } } } get_room_char(mask, row, col) register short mask; register short row, col; { if (mask & MONSTER) { return(get_monster_char_row_col(row, col)); } if (mask & SCROLL) { return('?'); } if (mask & POTION) { return('!'); } if (mask & FOOD) { return(':'); } if (mask & WAND) { return('/'); } if (mask & ARMOR) { return(']'); } if (mask & WEAPON) { return(')'); } if (mask & GOLD) { return('*'); } if (mask & TUNNEL) { return('#'); } if (mask & HORWALL) { return('-'); } if (mask & VERTWALL) { return('|'); } if (mask & AMULET) { return(','); } if (mask & FLOOR) { return('.'); } if (mask & DOOR) { return('+'); } if (mask & STAIRS) { return('%'); } return(' '); } get_rand_row_col(row, col, mask) short *row, *col; unsigned short mask; { short rn; AGAIN: do { *row = get_rand(MIN_ROW, SROWS-2); *col = get_rand(0, SCOLS-1); rn = get_room_number(*row, *col); } while (!(screen[*row][*col] & mask) || (rn == NO_ROOM)); if (screen[*row][*col] & (~mask)) goto AGAIN; } get_rand_room() { short i; do { i = get_rand(0, MAXROOMS-1); } while (!rooms[i].is_room); return(i); } fill_room_with_objects(rn) { short i; object *obj, *get_rand_object(); short n, N, row, col; N = ((rooms[rn].bottom_row - rooms[rn].top_row) - 1) * ((rooms[rn].right_col - rooms[rn].left_col) - 1); n = get_rand(5, 10); if (n > N) n = N - 2; for (i = 0; i < n; i++) { do { row = get_rand(rooms[rn].top_row+1, rooms[rn].bottom_row-1); col = get_rand(rooms[rn].left_col+1, rooms[rn].right_col-1); } while (screen[row][col] != FLOOR); obj = get_rand_object(); put_object_at(obj, row, col); } return(n); } get_room_number(row, col) { short i; for (i = 0; i < MAXROOMS; i++) { if ((row >= rooms[i].top_row)&&(row <= rooms[i].bottom_row) && (col >= rooms[i].left_col)&&(col <= rooms[i].right_col)) { return(i); } } return(NO_ROOM); } shell() { char *getenv(), *rindex(); char *sh; int status; move(LINES-1, 0); refresh(); stop_window(); putchar('\n'); if (!(sh = getenv("SHELL"))) { sh = "/bin/sh"; } if (!fork()) { if (setreuid(-1, getuid()) < 0) exit(1); execl(sh, rindex(sh, '/') + 1, 0); exit(0); } wait(&status); start_window(); wrefresh(curscr); } SHAR_EOF echo shar: extracting score.c cat - << \SHAR_EOF > score.c #include #include #include "object.h" #include "monster.h" #include "room.h" #include extern char *player_name; extern char *monster_names[]; extern short has_amulet, max_level; killed_by(monster, other) object *monster; short other; { char buf[80]; short i; signal(SIGINT, SIG_IGN); if (other != QUIT) { rogue.gold = ((rogue.gold * 9) / 10); } if (other) { switch(other) { case HYPOTHERMIA: strcpy(buf, "died of hypothermia"); break; case STARVATION: strcpy(buf, "died of starvation"); break; case QUIT: strcpy(buf, "quit"); break; } } else { strcpy(buf, "Killed by "); if (is_vowel(monster_names[monster->ichar - 'A'])) { strcat(buf, "an "); } else { strcat(buf, "a "); } strcat(buf, monster_names[monster->ichar - 'A']); } strcat(buf, " with "); sprintf(buf+strlen(buf), "%d gold", rogue.gold); message(buf, 0); message(""); score(monster, other); } win() { rogue.armor = 0; /* disarm and relax */ rogue.weapon = 0; clear(); mvaddstr(10, 11, "@ @ @@@ @ @ @ @ @ @@@ @ @ @"); mvaddstr(11, 11, " @ @ @ @ @ @ @ @ @ @ @ @@ @ @"); mvaddstr(12, 11, " @ @ @ @ @ @ @ @ @ @ @ @ @ @"); mvaddstr(13, 11, " @ @ @ @ @ @ @ @ @ @ @ @@"); mvaddstr(14, 11, " @ @@@ @@@ @@ @@ @@@ @ @ @"); mvaddstr(17, 11, "Congratulations, you have been admitted to the"); mvaddstr(18, 11, "Fighter's Guild. You return home, sell all your"); mvaddstr(19, 11, "treasures at great profit and retire into comfort."); message(""); message(""); id_all(); sell_pack(); score((object *) 0, WIN); } quit() { message("really quit?", 1); if (getchar() != 'y') { check_message(); return; } check_message(); killed_by(0, QUIT); } score(monster, other) object *monster; { int fd; while (access(SCOREFILE, W_OK) || access(SCOREFILE, R_OK)) { umask(0); if ((fd = creat(SCOREFILE, 0666)) < 0) { message("cannot find/read/write score file"); message(SCOREFILE); message("I'll wait, you go off and try to fix it"); message("hit space when finished fixing the problem"); wait_for_ack(0); } else { close(fd); } } put_scores(monster, other); } put_scores(monster, other) object *monster; { short i, j, n, rank = 10, x, dont_insert = 0; char scores[10][82]; int fd, s; fd = open(SCOREFILE, O_RDWR, 0); for (i = 0; i < 10; i++) { L: if (((n = read(fd, scores[i], 80)) < 80) && (n != 0)) { message("error in score file format"); message(""); clean_up("sorry, score file is out of order"); } else if (n == 0) { break; } if (!ncmp(scores[i]+16, player_name)) { x = 7; while (scores[i][x] == ' ') x++; s = get_number(scores[i] + x); if (s <= rogue.gold) { goto L; } else { dont_insert = 1; } } } if (dont_insert) goto DI; for (j = 0; j < i; j++) { if (rank > 9) { x = 7; while (scores[j][x] == ' ') x++; s = get_number(scores[j] + x); if (s <= rogue.gold) { rank = j; } } } if (i == 0) { rank = 0; } else if ((i < 10) && (rank > 9)) { rank = i; } if (rank <= 9) { insert_score(scores, rank, i, monster, other); if (i < 10) { i++; } } lseek(fd, 0, 0); DI: clear(); mvaddstr(3, 30, "Top Ten Rogueists"); mvaddstr(8, 0, "Rank\tScore\tName"); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGHUP, SIG_IGN); for (j = 0; j < i; j++) { if (j == rank) { standout(); } if (j == 9) { scores[j][0] = '1'; scores[j][1] = '0'; } else { scores[j][0] = ' '; scores[j][1] = j + '1'; } mvaddstr(j+10, 0, scores[j]); if (rank < 10) { write(fd, scores[j], 80); } if (j == rank) { standend(); } } refresh(); close(fd); clean_up(""); } insert_score(scores, rank, n, monster, other) char scores[][82]; short rank, n; object *monster; { short i, k; char buf[82]; for (i = (n - 1); i >= rank; i--) { if (i < 9) { strcpy(scores[i+1], scores[i]); } } sprintf(buf, "%2d %5d %s: ", rank+1, rogue.gold, player_name); if (other) { switch(other) { case HYPOTHERMIA: strcat(buf, "died of hypothermia"); break; case STARVATION: strcat(buf, "died of starvation"); break; case QUIT: strcat(buf, "quit"); break; case WIN: strcat(buf, "a total winner"); break; } } else { strcat(buf, "killed by "); if (is_vowel(monster_names[monster->ichar - 'A'])) { strcat(buf, "an "); } else { strcat(buf, "a "); } strcat(buf, monster_names[monster->ichar - 'A']); } sprintf(buf+strlen(buf), " on level %d ", max_level); if ((other != WIN) && has_amulet) { strcat(buf, "with amulet"); } for (i = strlen(buf); i < 79; i++) { buf[i] = ' '; } buf[79] = 0; strcpy(scores[rank], buf); } is_vowel(ch) short ch; { return( (ch == 'a') || (ch == 'e') || (ch == 'i') || (ch == 'o') || (ch == 'u') ); } sell_pack() { object *obj; short row = 2, val; char buf[80]; obj = rogue.pack.next_object; clear(); while (obj) { mvaddstr(1, 0, "Value Item"); if (obj->what_is == FOOD) { goto NEXT; } obj->identified = 1; val = get_value(obj); rogue.gold += val; if (row < SROWS) { sprintf(buf, "%5d ", val); get_description(obj, buf+11); mvaddstr(row++, 0, buf); } NEXT: obj = obj->next_object; } refresh(); message(""); } get_value(obj) object *obj; { short wc; int val; wc = obj->which_kind; switch(obj->what_is) { case WEAPON: val = id_weapons[wc].value; if ((wc == ARROW) || (wc == SHURIKEN)) { val *= obj->quantity; } val += (obj->damage_enchantment * 85); val += (obj->to_hit_enchantment * 85); break; case ARMOR: val = id_armors[wc].value; val += (obj->damage_enchantment * 75); if (obj->is_protected) { val += 200; } break; case WAND: val = id_wands[wc].value * obj->class; break; case SCROLL: val = id_scrolls[wc].value * obj->quantity; break; case POTION: val = id_potions[wc].value * obj->quantity; break; case AMULET: val = 5000; break; } if (val <= 0) { val = 10; } return(val); } id_all() { short i; for (i = 0; i < SCROLLS; i++) { id_scrolls[i].id_status = IDENTIFIED; } for (i = 0; i < WEAPONS; i++) { id_weapons[i].id_status = IDENTIFIED; } for (i = 0; i < ARMORS; i++) { id_armors[i].id_status = IDENTIFIED; } for (i = 0; i < WANDS; i++) { id_wands[i].id_status = IDENTIFIED; } for (i = 0; i < POTIONS; i++) { id_potions[i].id_status = IDENTIFIED; } } ncmp(s1, s2) char *s1, *s2; { short i = 0; int r; while(s1[i] != ':') i++; s1[i] = 0; r = strcmp(s1, s2); s1[i] = ':'; return(r); } SHAR_EOF echo shar: extracting special_hit.c cat - << \SHAR_EOF > special_hit.c #include #include "object.h" #include "move.h" #include "monster.h" short being_held; extern short current_level, max_level, has_amulet, detect_monster; extern int level_points[]; special_hit(monster) object *monster; { switch(monster->ichar) { case 'A': rust(monster); break; case 'F': being_held = 1; break; case 'I': freeze(monster); break; case 'L': steal_gold(monster); break; case 'N': steal_item(monster); break; case 'R': sting(monster); break; case 'V': drain_life(); break; case 'W': drain_level(); break; } } rust(monster) object *monster; { if (!rogue.armor || (get_armor_class(rogue.armor) <= 1) || (rogue.armor->which_kind == LEATHER)) { return; } if (rogue.armor->is_protected) { if (!monster->identified) { message("the rust vanishes instantly", 0); monster->identified = 1; } } else { rogue.armor->damage_enchantment--; message("your armor weakens", 0); print_stats(); } } freeze(monster) object *monster; { short freeze_percent = 99; short i, n; if (rand_percent(12)) return; freeze_percent -= (rogue.strength_current+(rogue.strength_current/2)); freeze_percent -= rogue.exp * 4; freeze_percent -= (get_armor_class(rogue.armor) * 5); freeze_percent -= (rogue.hp_max / 3); if (freeze_percent > 10) { monster->identified = 1; message("you are frozen", 1); n = get_rand(5, 9); for (i = 0; i < n; i++) { move_monsters(); } if (rand_percent(freeze_percent)) { for (i = 0; i < 50; i++) { move_monsters(); } killed_by((object *)0, HYPOTHERMIA); } message("you can move again", 1); monster->identified = 0; } } steal_gold(monster) object *monster; { int amount; if (rand_percent(15)) return; if (rogue.gold > 50) { amount = rogue.gold > 1000 ? get_rand(8, 15) : get_rand(2, 5); amount = rogue.gold / amount; } else { amount = rogue.gold/2; } amount += (get_rand(0, 2) - 1) * (rogue.exp + current_level); if ((amount <= 0) && (rogue.gold > 0)) { amount = rogue.gold; } if (amount > 0) { rogue.gold -= amount; message("your purse feels lighter", 0); print_stats(); } disappear(monster); } steal_item(monster) object *monster; { object *obj; short i, n, has_something = 0; char description[80]; if (rand_percent(15)) return; obj = rogue.pack.next_object; if (!obj) { goto DSPR; } while (obj) { if ((obj != rogue.armor) && (obj != rogue.weapon)) { has_something = 1; break; } obj = obj->next_object; } if (!has_something) goto DSPR; n = get_rand(0, MAX_PACK_COUNT); obj = rogue.pack.next_object; for (i = 0; i <= n; i++) { obj = obj->next_object; while (!obj || (obj == rogue.weapon) || (obj == rogue.armor)) { if (!obj) { obj = rogue.pack.next_object; } else { obj = obj->next_object; } } } strcpy(description, "she stole "); get_description(obj, description+10); message(description, 0); if (obj->what_is == AMULET) { has_amulet = 0; } vanish(obj, 0); DSPR: disappear(monster); } disappear(monster) object *monster; { short row, col; row = monster->row; col = monster->col; remove_mask(row, col, MONSTER); if (can_see(row, col)) { mvaddch(row, col, get_room_char(screen[row][col], row, col)); } remove_from_pack(monster, &level_monsters); free(monster); } cough_up(monster) object *monster; { object *obj, *get_an_object(),*get_rand_object(); short row, col, i, j, n; if (current_level < max_level) { return; } switch(monster->ichar) { case 'L': obj = get_an_object(); obj->what_is = GOLD; obj->quantity = get_rand(9, 599); break; default: if (rand_percent(monster->which_kind)) { obj = get_rand_object(); break; } return; } row = monster->row; col = monster->col; for (n = 0; n <= 5; n++) { for (i = -n; i <= n; i++) { if (try_to_cough(row+n, col+i, obj)) { return; } if (try_to_cough(row-n, col+i, obj)) { return; } } for (i = -n; i <= n; i++) { if (try_to_cough(row+i, col-n, obj)) { return; } if (try_to_cough(row+i, col+n, obj)) { return; } } } free(obj); } try_to_cough(row, col, obj) short row, col; object *obj; { if ((row(LINES-2))||(col<0)||(col>(COLS-1))) { return(0); } if ((!(screen[row][col] & IS_OBJECT)) && (screen[row][col] & (TUNNEL|FLOOR|DOOR)) && !(screen[row][col] & MONSTER)) { put_object_at(obj, row, col); mvaddch(row, col, get_room_char(screen[row][col], row, col)); refresh(); return(1); } return(0); } orc_gold(monster) object *monster; { short i, j, row, col, rn, s; if (monster->identified) { return(0); } if ((rn = get_room_number(monster->row, monster->col)) < 0) { return(0); } for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) { for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) { if ((screen[i][j] & GOLD) && !(screen[i][j] & MONSTER)) { monster->m_flags |= CAN_GO; s = monster_can_go(monster, i, j); monster->m_flags &= (~CAN_GO); if (s) { move_monster_to(monster, i, j); monster->m_flags |= IS_ASLEEP; monster->m_flags &= (~WAKENS); monster->identified = 1; return(1); } monster->identified = 1; monster->m_flags |= CAN_GO; mv_monster(monster, i, j); monster->m_flags &= (~CAN_GO); monster->identified = 0; return(1); } } } return(0); } check_orc(monster) object *monster; { if (monster->ichar == 'O') { monster->identified = 1; } } check_xeroc(monster) object *monster; { char *monster_name(); char msg[80]; if ((monster->ichar == 'X') && monster->identified) { wake_up(monster); monster->identified = 0; mvaddch(monster->row, monster->col, get_room_char(screen[monster->row][monster->col], monster->row, monster->col)); check_message(); sprintf(msg, "wait, that's a %s!", monster_name(monster)); message(msg, 1); return(1); } return(0); } hiding_xeroc(row, col) register short row, col; { object *object_at(), *monster; if ((current_level < XEROC1) || (current_level > XEROC2) || !(screen[row][col] & MONSTER)) { return(0); } monster = object_at(&level_monsters, row, col); if ((monster->ichar == 'X') && monster->identified) { return(1); } return(0); } sting(monster) object *monster; { short ac, sting_chance = 35; char msg[80], *monster_name(); if (rogue.strength_current < 5) return; ac = get_armor_class(rogue.armor); sting_chance += (6 * (6 - ac)); if (rogue.exp > 8) { sting_chance -= (6 * (rogue.exp - 8)); } if (sting_chance > 100) { sting_chance = 100; } else if (sting_chance <= 0) { sting_chance = 1; } if (rand_percent(sting_chance)) { sprintf(msg, "the %s's bite has weakened you", monster_name(monster)); message(msg, 0); rogue.strength_current--; print_stats(); } } drain_level() { if (!rand_percent(20) || (rogue.exp <= 7)) { return; } rogue.exp_points = level_points[rogue.exp-2] - get_rand(10, 50); rogue.exp -= 2; add_exp(1); } drain_life() { if (!rand_percent(25) || (rogue.hp_max<=30) || (rogue.hp_current<10)) { return; } message("you feel weaker", 0); rogue.hp_max--; rogue.hp_current--; if (rand_percent(50)) { if (rogue.strength_current >= 5) { rogue.strength_current--; if (rand_percent(50)) { rogue.strength_max--; } } } print_stats(); } m_confuse(monster) object *monster; { char msg[80]; char *monster_name(); if (monster->identified) { return(0); } if (!can_see(monster->row, monster->col)) { return(0); } if (rand_percent(45)) { monster->identified = 1; return(0); } if (rand_percent(55)) { monster->identified = 1; sprintf(msg, "the gaze of the %s has confused you", monster_name(monster)); message(msg, 1); confuse(); return(1); } return(0); } flame_broil(monster) object *monster; { short row, col; if (!can_see(monster->row, monster->col)) { return(0); } if (rand_percent(50)) { return(0); } if (!rogue_is_around(monster->row, monster->col)) { row = monster->row; col = monster->col; get_closer(&row, &col, rogue.row, rogue.col); standout(); do { mvaddch(row, col, '*'); refresh(); get_closer(&row, &col, rogue.row, rogue.col); } while ((row != rogue.row) || (col != rogue.col)); standend(); row = monster->row; col = monster->col; get_closer(&row, &col, rogue.row, rogue.col); do { mvaddch(row, col, get_room_char(screen[row][col], row, col)); refresh(); get_closer(&row, &col, rogue.row, rogue.col); } while ((row != rogue.row) || (col != rogue.col)); } monster_hit(monster, "flame"); return(1); } get_closer(row, col, trow, tcol) short *row, *col; short trow, tcol; { if (*row < trow) { (*row)++; } else if (*row > trow) { (*row)--; } if (*col < tcol) { (*col)++; } else if (*col > tcol) { (*col)--; } } SHAR_EOF echo shar: extracting throw.c cat - << \SHAR_EOF > throw.c #include #include "object.h" #include "move.h" #include "monster.h" extern short current_room; extern char *CURSE_MESSAGE; extern char hit_message[]; throw() { short wch; short first_miss = 1, f = 1; object *weapon, *get_letter_object(); short dir, row, col; object *monster, *get_thrown_at_monster(); while (!is_direction(dir = getchar())) { putchar(7); fflush(stdout); if (first_miss) { message("direction? ", 0); first_miss = 0; } } if (dir == CANCEL) { check_message(); return; } if ((wch = get_pack_letter("throw what?", WEAPON)) == CANCEL) { check_message(); return; } check_message(); if (!(weapon = get_letter_object(wch))) { message("no such item.", 0); return; } if (weapon->what_is != WEAPON) { wch = get_rand(0, 2); switch(wch) { case 0: message("if you don't want it, drop it!", 0); break; case 1: message("throwing that would do noone any good", 0); break; case 2: message("why would you want to throw that?", 0); break; } return; } if ((weapon == rogue.weapon) && (weapon->is_cursed)) { message(CURSE_MESSAGE, 0); return; } row = rogue.row; col = rogue.col; monster = get_thrown_at_monster(dir, &row, &col); mvaddch(rogue.row, rogue.col, rogue.fchar); refresh(); if (can_see(row, col) && ((row != rogue.row) || (col != rogue.col))) { mvaddch(row, col, get_room_char(screen[row][col], row, col)); } if (monster) { wake_up(monster); check_orc(monster); if (!throw_at_monster(monster, weapon)) { f = flop_weapon(weapon, row, col); } } else { f = flop_weapon(weapon, row, col); } vanish(weapon, 1); } throw_at_monster(monster, weapon) object *monster, *weapon; { short damage, hit_chance; char *name_of(); short t; hit_chance = get_hit_chance(weapon); t = weapon->quantity; weapon->quantity = 1; sprintf(hit_message, "the %s", name_of(weapon)); weapon->quantity = t; if (!rand_percent(hit_chance)) { strcat(hit_message, "misses "); return(0); } strcat(hit_message, "hit "); damage = get_weapon_damage(weapon); if (((weapon->which_kind == ARROW) && (rogue.weapon && (rogue.weapon->which_kind == BOW))) || ((weapon->which_kind == SHURIKEN) && (rogue.weapon == weapon))) { damage += get_weapon_damage(rogue.weapon); damage = ((damage * 2) / 3); } monster_damage(monster, damage); return(1); } object *get_thrown_at_monster(dir, row, col) short dir; short *row, *col; { object *object_at(); short orow, ocol; short i; orow = *row; ocol = *col; for (i = 0; i < 24; i++) { get_dir_rc(dir, row, col); if ((screen[*row][*col] == BLANK) || (screen[*row][*col] & (HORWALL | VERTWALL))) { *row = orow; *col = ocol; return(0); } if ((i != 0) && can_see(orow, ocol)) { mvaddch(orow, ocol, get_room_char(screen[orow][ocol], orow, ocol)); } if (can_see(*row, *col)) { if (!(screen[*row][*col] & MONSTER)) { mvaddch(*row, *col, ')'); } refresh(); } orow = *row; ocol = *col; if (screen[*row][*col] & MONSTER) { if (!hiding_xeroc(*row, *col)) { return(object_at(&level_monsters, *row, *col)); } } if (screen[*row][*col] & TUNNEL) { i += 2; } } return(0); } flop_weapon(weapon, row, col) object *weapon; short row, col; { object *new_weapon, *get_an_object(); short i, j, r, c, found = 0, inc1, inc2; char msg[80]; inc1 = get_rand(0, 1) ? 1 : -1; inc2 = get_rand(0, 1) ? 1 : -1; r = row; c = col; if ((screen[r][c] & ~(FLOOR | TUNNEL | DOOR)) || ((row == rogue.row) && (col == rogue.col))) { for (i = inc1; i != (2 * -inc1); i -= inc1) { for (j = inc2; j != (2 * -inc2); j -= inc2) { r = row + i; c = col + j; if ((r > (LINES-2)) || (r < MIN_ROW) || (c > (COLS-1)) || (c < 0)) { continue; } if (!screen[r][c]) continue; if ((screen[r][c] & ~(FLOOR|TUNNEL|DOOR)) || ((r == rogue.row) && (c == rogue.col))) { continue; } found = 1; goto FOUND; } } } else { found = 1; } FOUND: if (found) { new_weapon = get_an_object(); *new_weapon = *weapon; new_weapon->quantity = 1; new_weapon->row = r; new_weapon->col = c; add_mask(r, c, WEAPON); add_to_pack(new_weapon, &level_objects, 0); if (can_see(r, c)) { mvaddch(r, c, get_room_char(screen[r][c], r, c)); } } else { short t; t = weapon->quantity; weapon->quantity = 1; sprintf(msg, "the %svanishes as it hits the ground", name_of(weapon)); weapon->quantity = t; message(msg, 0); } return(found); } SHAR_EOF echo shar: extracting use.c cat - << \SHAR_EOF > use.c #include #include "object.h" #include "move.h" #include "monster.h" #include "room.h" short halluc = 0; short blind = 0; short confused = 0; short detect_monster = 0; extern short being_held; char *strange_feeling = "you have a strange feeling for a moment, then it passes"; extern char *hunger_str; extern short current_room; extern int level_points[]; quaff() { short ch, i; object *obj, *get_letter_object(); char msg[SCOLS]; ch = get_pack_letter("quaff what? ", POTION); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != POTION) { message("you can't drink that", 0); return; } switch(obj->which_kind) { case INCREASE_STRENGTH: message("you feel stronger now, what bulging muscles!", 0); rogue.strength_current++; if (rogue.strength_current > rogue.strength_max) { rogue.strength_max = rogue.strength_current; } break; case RESTORE_STRENGTH: rogue.strength_current = rogue.strength_max; message("this tastes great, you feel warm all over", 0); break; case HEALING: message("you begin to feel better", 0); potion_heal(0); break; case EXTRA_HEALING: message("you begin to feel much better", 0); potion_heal(1); break; case POISON: rogue.strength_current -= get_rand(1, 3); if (rogue.strength_current < 0) { rogue.strength_current = 0; } message("you feel very sick now", 0); if (halluc) { unhallucinate(); } break; case RAISE_LEVEL: add_exp((level_points[rogue.exp-1]-rogue.exp_points)+1); break; case BLINDNESS: go_blind(); break; case HALLUCINATION: message("oh wow, everything seems so cosmic", 0); halluc += get_rand(500, 800); break; case DETECT_MONSTER: if (level_monsters.next_object) { show_monsters(); } else { message(strange_feeling, 0); } detect_monster = 1; break; case DETECT_OBJECTS: if (level_objects.next_object) { if (!blind) { show_objects(); } } else { message(strange_feeling, 0); } break; case CONFUSION: message((halluc ? "what a trippy feeling" : "you feel confused"), 0); confuse(); break; } print_stats(); if (id_potions[obj->which_kind].id_status != CALLED) { id_potions[obj->which_kind].id_status = IDENTIFIED; } vanish(obj, 1); } read_scroll() { short ch; object *obj, *get_letter_object(); char msg[SCOLS]; char *get_ench_color(); ch = get_pack_letter("read what? ", SCROLL); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != SCROLL) { message("you can't read that", 0); return; } switch(obj->which_kind) { case SCARE_MONSTER: message("you hear a maniacal laughter in the distance", 0); break; case HOLD_MONSTER: hold_monster(); break; case ENCHANT_WEAPON: if (rogue.weapon) { sprintf(msg, "your %sglows %sfor a moment", id_weapons[rogue.weapon->which_kind].title, get_ench_color()); message(msg, 0); if (get_rand(0, 1) == 1) { rogue.weapon->to_hit_enchantment++; } else { rogue.weapon->damage_enchantment++; } rogue.weapon->is_cursed = 0; } else { message("your hands tingle", 0); } break; case ENCHANT_ARMOR: if (rogue.armor) { sprintf(msg, "your armor glows %sfor a moment", get_ench_color()); message(msg, 0); rogue.armor->damage_enchantment++; rogue.armor->is_cursed = 0; print_stats(); } else { message("your skin crawls", 0); } break; case IDENTIFY: message("this is a scroll of identify", 0); message("what would you like to identify?", 0); obj->identified = 1; id_scrolls[obj->which_kind].id_status = IDENTIFIED; identify(); break; case TELEPORT: teleport(); break; case SLEEP: sleep_scroll(); break; case PROTECT_ARMOR: if (rogue.armor) { message( "your armor is covered by a shimmering gold shield", 0); rogue.armor->is_protected = 1; } else { message("your acne seems to have disappeared", 0); } break; case REMOVE_CURSE: message( "you feel as though someone is watching over you", 0); if (rogue.armor) { rogue.armor->is_cursed = 0; } if (rogue.weapon) { rogue.weapon->is_cursed = 0; } break; case CREATE_MONSTER: create_monster(); break; case AGGRAVATE_MONSTER: aggravate(); break; } if (id_scrolls[obj->which_kind].id_status != CALLED) { id_scrolls[obj->which_kind].id_status = IDENTIFIED; } vanish(obj, 1); } vanish(obj, rm) object *obj; short rm; { if (obj->quantity > 1) { obj->quantity--; } else { remove_from_pack(obj, &rogue.pack); make_avail_ichar(obj->ichar); free(obj); } if (rm) { register_move(); } } potion_heal(extra) { float ratio; short add; ratio = ((float)rogue.hp_current) / rogue.hp_max; if (ratio >= 0.90) { rogue.hp_max += (extra + 1); rogue.hp_current = rogue.hp_max; } else { if (ratio < 30.00) { ratio = 30.00; } if (extra) { ratio += ratio; } add = (short)(ratio*((float)rogue.hp_max-rogue.hp_current)); rogue.hp_current += add; if (rogue.hp_current > rogue.hp_max) { rogue.hp_current = rogue.hp_max; } } if (blind) { unblind(); } if (confused && extra) { unconfuse(); } if (confused) { confused = ((confused - 9) / 2); if (confused <= 0) { unconfuse(); } } if (halluc && extra) { unhallucinate(); } else if (halluc) { halluc = (halluc/2) + 1; } } identify() { short ch; object *obj, *get_letter_object(); struct identify *id_table, *get_id_table(); char description[SCOLS]; AGAIN: ch = get_pack_letter("identify what? ", IS_OBJECT); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item, try again", 0); message("", 0); check_message(); goto AGAIN; } obj->identified = 1; if (obj->what_is & (SCROLL | POTION | WEAPON | ARMOR | WAND)) { id_table = get_id_table(obj); id_table[obj->which_kind].id_status = IDENTIFIED; } get_description(obj, description); message(description, 0); } eat() { short ch; short moves; object *obj, *get_letter_object(); char msg[SCOLS]; ch = get_pack_letter("eat what? ", FOOD); if (ch == CANCEL) { return; } if (!(obj = get_letter_object(ch))) { message("no such item.", 0); return; } if (obj->what_is != FOOD) { message("you can't eat that", 0); return; } moves = get_rand(800, 1000); if (moves >= 900) { message("yum, that tasted good", 0); } else { message("yuk, that food tasted awful", 0); add_exp(3); } rogue.moves_left /= 2; rogue.moves_left += moves; hunger_str = ""; print_stats(); vanish(obj, 1); } hold_monster() { short i, j; short mcount = 0; object *monster, *object_at(); short row, col; for (i = -2; i <= 2; i++) { for (j = -2; j <= 2; j++) { row = rogue.row + i; col = rogue.col + j; if ((row < MIN_ROW) || (row > (LINES-2)) || (col < 0) || (col > (COLS-1))) { continue; } if (screen[row][col] & MONSTER) { monster = object_at(&level_monsters, row, col); monster->m_flags |= IS_ASLEEP; monster->m_flags &= (~WAKENS); mcount++; } } } if (mcount == 0) { message("you feel a strange sense of loss", 0); } else if (mcount == 1) { message("the monster freezes", 0); } else { message("the monsters around you freeze", 0); } } teleport() { if (current_room >= 0) { darken_room(current_room); } else { mvaddch(rogue.row, rogue.col, get_room_char(screen[rogue.row][rogue.col], rogue.row, rogue.col)); } put_player(); light_up_room(); being_held = 0; } hallucinate() { object *obj; short ch; if (blind) return; obj = level_objects.next_object; while (obj) { ch = mvinch(obj->row, obj->col); if (((ch < 'A') || (ch > 'Z')) && ((obj->row != rogue.row) || (obj->col != rogue.col))) if ((ch != ' ')&&(ch != '.')&&(ch != '#')&&(ch != '+')) { addch(get_rand_obj_char()); } obj = obj->next_object; } obj = level_monsters.next_object; while (obj) { ch = mvinch(obj->row, obj->col); if ((ch >= 'A') && (ch <= 'Z')) { addch(get_rand('A', 'Z')); } obj = obj->next_object; } } unhallucinate() { halluc = 0; if (current_room == PASSAGE) { light_passage(rogue.row, rogue.col); } else { light_up_room(); } message("everything looks SO boring now", 0); } unblind() { blind = 0; message("the veil of darkness lifts", 0); if (current_room == PASSAGE) { light_passage(rogue.row, rogue.col); } else { light_up_room(); } blind = 0; if (detect_monster) { show_monsters(); } if (halluc) { hallucinate(); } } sleep_scroll() { short i; message("you fall asleep", 0); sleep(1); i = get_rand(4, 10); while (i--) { move_monsters(); } sleep(1); message("you can move again", 0); } go_blind() { short i, j; if (!blind) { message("a cloak of darkness falls around you", 0); } blind += get_rand(500, 800); if (current_room >= 0) { for (i = rooms[current_room].top_row + 1; i < rooms[current_room].bottom_row; i++) { for (j = rooms[current_room].left_col + 1; j < rooms[current_room].right_col; j++) { mvaddch(i, j, ' '); } } } mvaddch(rogue.row, rogue.col, rogue.fchar); refresh(); } char *get_ench_color() { if (halluc) { return(id_potions[get_rand(0, POTIONS-1)].title); } return("blue "); } confuse() { confused = get_rand(12, 22); } unconfuse() { char msg[80]; confused = 0; sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused")); message(msg, 0); } SHAR_EOF echo shar: extracting zap.c cat - << \SHAR_EOF > zap.c #include #include "object.h" #include "move.h" #include "monster.h" extern short current_room, being_held, current_level; zapp() { short wch; short first_miss = 1; object *wand, *get_letter_object(); short dir, row, col; object *monster, *get_zapped_monster(); while (!is_direction(dir = getchar())) { putchar(7); fflush(stdout); if (first_miss) { message("direction? ", 0); first_miss = 0; } } if (dir == CANCEL) { check_message(); return; } if ((wch = get_pack_letter("zap with what?", WAND)) == CANCEL) { check_message(); return; } check_message(); if (!(wand = get_letter_object(wch))) { message("no such item.", 0); return; } if (wand->what_is != WAND) { message("you can't zap with that", 0); return; } if (wand->class <= 0) { message("nothing happens", 0); goto RM; } else { wand->class--; } row = rogue.row; col = rogue.col; monster = get_zapped_monster(dir, &row, &col); if (monster != 0) { wake_up(monster); zap_monster(monster, wand->which_kind); } RM: register_move(); } object *get_zapped_monster(dir, row, col) short dir; short *row, *col; { object *object_at(); short orow, ocol; short i; for (;;) { orow = *row; ocol = *col; get_dir_rc(dir, row, col); if (((*row == orow) && (*col == ocol)) || (screen[*row][*col] & (HORWALL | VERTWALL)) || (screen[*row][*col] == BLANK)) { return(0); } if (screen[*row][*col] & MONSTER) { if (!hiding_xeroc(*row, *col)) { return(object_at(&level_monsters, *row, *col)); } } } } zap_monster(monster, kind) object *monster; short kind; { short row, col; struct object *nm; row = monster->row; col = monster->col; nm = monster->next_object; switch(kind) { case SLOW_MONSTER: if (monster->m_flags & HASTED) { monster->m_flags &= (~HASTED); } else { monster->quiver = 0; monster->m_flags |= SLOWED; } break; case HASTE_MONSTER: if (monster->m_flags & SLOWED) { monster->m_flags &= (~SLOWED); } else { monster->m_flags |= HASTED; } break; case TELEPORT_AWAY: teleport_away(monster); break; case KILL_MONSTER: rogue.exp_points -= monster->kill_exp; monster_damage(monster, monster->quantity); break; case INVISIBILITY: monster->m_flags |= IS_INVIS; mvaddch(row, col, get_monster_char(monster)); break; case POLYMORPH: if (monster->ichar == 'F') { being_held = 0; } MA: *monster = monster_tab[get_rand(0, MONSTERS-1)]; if ((monster->ichar == 'X') && ((current_level < XEROC1) || (current_level > XEROC2))) { goto MA; } monster->what_is = MONSTER; monster->row = row; monster->col = col; monster->next_object = nm; wake_up(monster); if (can_see(row, col)) { mvaddch(row, col, get_monster_char(monster)); } break; case PUT_TO_SLEEP: monster->m_flags |= IS_ASLEEP; monster->m_flags &= (~WAKENS); break; case DO_NOTHING: message("nothing happens", 0); break; } } teleport_away(monster) object *monster; { short row, col; if (monster->ichar == 'F') { being_held = 0; } get_rand_row_col(&row, &col, (FLOOR | TUNNEL | IS_OBJECT)); remove_mask(monster->row, monster->col, MONSTER); mvaddch(monster->row, monster->col, get_room_char(screen[monster->row][monster->col], monster->row, monster->col)); monster->row = row; monster->col = col; add_mask(row, col, MONSTER); if (can_see(row, col)) { mvaddch(row, col, get_monster_char(monster)); } } SHAR_EOF