tims@zeus.UUCP (Tim Stoehr) (11/26/86)
#!/bin/sh-----cut here-----cut here-----cut here-----cut here----- # shar: Shell Archiver # Run the following text with /bin/sh to create: # main.c # message.c # monster.c # monster.h # room.h # move.c # move.h # special_hit.c echo shar: extracting main.c cat - << \SHAR_EOF > main.c /* * main.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include "object.h" #include "room.h" extern short party_room; main(argc, argv) int argc; char *argv[]; { if (init(argc, argv)) { /* restored game */ goto PL; } for (;;) { clear_level(); make_level(); put_objects(); put_stairs(); add_traps(); put_monsters(); put_player(party_room); print_stats(STAT_ALL); PL: play_level(); free_stuff(&level_objects); free_stuff(&level_monsters); } } SHAR_EOF echo shar: extracting message.c cat - << \SHAR_EOF > message.c /* * message.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "object.h" #include "move.h" #include "room.h" char message_line[DCOLS] = ""; short message_col = 0; boolean message_cleared = 1; char hunger_str[8] = ""; extern boolean cant_int, did_int, interrupted, save_is_interactive; extern short add_strength; extern short current_level; message(msg, intrpt) char *msg; boolean intrpt; { if (!save_is_interactive) { return; } if (intrpt) { interrupted = 1; slurp(); } cant_int = 1; 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() { if (message_cleared) { return; } move(MIN_ROW-1, 0); clrtoeol(); refresh(); message_cleared = 1; } get_input_line(prompt, insert, buf, if_cancelled, add_blank, do_echo) char *prompt, *buf, *insert; char *if_cancelled; boolean add_blank; boolean do_echo; { short ch; short i = 0, n; message(prompt, 0); n = strlen(prompt); if (insert[0]) { mvaddstr(0, n + 1, insert); strcpy(buf, insert); i = strlen(insert); move(0, (n + i + 1)); refresh(); } while (((ch = rgetchar()) != '\r') && (ch != '\n') && (ch != CANCEL)) { if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) { if ((ch != ' ') || (i > 0)) { buf[i++] = ch; if (do_echo) { addch(ch); } } } if ((ch == '\b') && (i > 0)) { if (do_echo) { mvaddch(0, i + n, ' '); move(MIN_ROW-1, i+n); } i--; } refresh(); } check_message(); if (add_blank) { buf[i++] = ' '; } else { while ((i > 0) && (buf[i-1] == ' ')) { i--; } } buf[i] = 0; if ((ch == CANCEL) || (i == 0) || ((i == 1) && add_blank)) { if (if_cancelled) { message(if_cancelled, 0); } return(0); } return(i); } slurp() { long ln; short i, n; ioctl(0, FIONREAD, &ln); n = (short) (stdin->_cnt + ln); for (i = 0; i < n; i++) { getchar(); } } rgetchar() { register ch; for(;;) { ch = getchar(); switch(ch) { case '\022': wrefresh(curscr); break; case '\032': printf(CL); fflush(stdout); tstp(); break; case 'X': save_screen(); break; default: return(ch); } } } /* Level: 99 Gold: 999999 Hp: 999(999) Str: 99(99) Arm: 99 Exp: 21/10000000 Hungry 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 */ print_stats(stat_mask) register stat_mask; { char buf[16]; boolean label; int row = DROWS - 1; label = (stat_mask & STAT_LABEL) ? 1 : 0; if (stat_mask & STAT_LEVEL) { if (label) { mvaddstr(row, 0, "Level: "); } /* max level taken care of in make_level() */ sprintf(buf, "%d", current_level); mvaddstr(row, 7, buf); pad(buf, 2); } if (stat_mask & STAT_GOLD) { if (label) { if (rogue.gold > MAX_GOLD) { rogue.gold = MAX_GOLD; } mvaddstr(row, 10, "Gold: "); } sprintf(buf, "%d", rogue.gold); mvaddstr(row, 16, buf); pad(buf, 6); } if (stat_mask & STAT_HP) { if (label) { mvaddstr(row, 23, "Hp: "); if (rogue.hp_max > MAX_HP) { rogue.hp_current -= (rogue.hp_max - MAX_HP); rogue.hp_max = MAX_HP; } } sprintf(buf, "%d(%d)", rogue.hp_current, rogue.hp_max); mvaddstr(row, 27, buf); pad(buf, 8); } if (stat_mask & STAT_STRENGTH) { if (label) { mvaddstr(row, 36, "Str: "); } if (rogue.strength_max > MAX_STRENGTH) { rogue.strength_current -= (rogue.strength_max - MAX_STRENGTH); rogue.strength_max = MAX_STRENGTH; } sprintf(buf, "%d(%d)", (rogue.strength_current + add_strength), rogue.strength_max); mvaddstr(row, 41, buf); pad(buf, 6); } if (stat_mask & STAT_ARMOR) { if (label) { mvaddstr(row, 48, "Arm: "); } if (rogue.armor->damage_enchantment > MAX_ARMOR) { rogue.armor->damage_enchantment = MAX_ARMOR; } sprintf(buf, "%d", get_armor_class(rogue.armor)); mvaddstr(row, 53, buf); pad(buf, 2); } if (stat_mask & STAT_EXP) { if (label) { mvaddstr(row, 56, "Exp: "); } /* Max exp taken care of in add_exp() */ sprintf(buf, "%d/%D", rogue.exp, rogue.exp_points); mvaddstr(row, 61, buf); pad(buf, 11); } if (stat_mask & STAT_HUNGER) { mvaddstr(row, 73, hunger_str); clrtoeol(); } refresh(); } pad(s, n) char *s; short n; { short i; for (i = strlen(s); i < n; i++) { addch(' '); } } save_screen() { FILE *fp; short i, j, row, col; char buf[DCOLS+2]; boolean found_non_blank; row = curscr->_cury; col = curscr->_curx; if (fp = fopen("rogue.screen", "w")) { for (i = 0; i < DROWS; i++) { found_non_blank = 0; for (j = (DCOLS - 1); j >= 0; j--) { buf[j] = mvinch(i, j); if (!found_non_blank) { if ((buf[j] != ' ') || (j == 0)) { buf[j + ((j == 0) ? 0 : 1)] = 0; found_non_blank = 1; } } } fputs(buf, fp); putc('\n', fp); } fclose(fp); } else { sound_bell(); } move(row, col); refresh(); } sound_bell() { putchar(7); fflush(stdout); } SHAR_EOF echo shar: extracting monster.c cat - << \SHAR_EOF > monster.c /* * monster.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "monster.h" #include "object.h" #include "room.h" #include "move.h" object level_monsters; boolean monster_disappeared; char *monster_names[] = { "aquatar", "bat", "centaur", "dragon", "emu", "venus fly-trap", "griffin", "hobgoblin", "ice monster", "jabberwock", "kestrel", "leprechaun", "medusa", "nymph", "orc", "phantom", "quasit", "rattlesnake", "snake", "troll", "black unicorn", "vampire", "wraith", "xeroc", "yeti", "zombie" }; object monster_tab[MONSTERS] = { {(ASLEEP|WAKENS|WANDERS|RUSTS),"0d0",25,'A',20,9,18,100,0,0,0,0,0}, {(ASLEEP|WANDERS|FLITS),"1d3",10,'B',2,1,8,60,0,0,0,0,0}, {(ASLEEP|WANDERS),"3d3/2d5",32,'C',15,7,16,85,0,10,0,0,0}, {(ASLEEP|WAKENS|FLAMES),"4d6/4d9",145,'D',5000,21,126,100,0,90,0,0,0}, {(ASLEEP|WAKENS),"1d3",11,'E',2,1,7,65,0,0,0,0,0}, {(HOLDS|STATIONARY),"5d5",73,'F',91,12,126,80,0,0,0,0,0}, {(ASLEEP|WAKENS|WANDERS|FLIES),"5d5/5d5",115,'G', 2000,20,126,85,0,10,0,0,0}, {(ASLEEP|WAKENS|WANDERS),"1d3/1d2",15,'H',3,1,10,67,0,0,0,0,0}, {(ASLEEP|FREEZES),"0d0",15,'I',5,2,11,68,0,0,0,0,0}, {(ASLEEP|WANDERS),"3d10/4d5",132,'J',3000,21,126,100,0,0,0,0,0}, {(ASLEEP|WAKENS|WANDERS|FLIES),"1d4",10,'K',2,1,6,60,0,0,0,0,0}, {(ASLEEP|STEALS_GOLD),"0d0",25,'L',21,6,16,75,0,0,0,0,0}, {(ASLEEP|WAKENS|WANDERS|CONFUSES),"4d4/3d7",97,'M', 250,18,126,85,0,25,0,0,0}, {(ASLEEP|STEALS_ITEM),"0d0",25,'N',39,10,19,75,0,100,0,0,0}, {(ASLEEP|WANDERS|WAKENS|SEEKS_GOLD),"1d6",25,'O',5,4,13,70,0,10,0,0,0}, {(ASLEEP|INVISIBLE|WANDERS|FLITS),"5d4",76,'P',120,15,24,80,0,50,0,0,0}, {(ASLEEP|WAKENS|WANDERS),"3d5",30,'Q',20,8,17,78,0,20,0,0,0}, {(ASLEEP|WAKENS|WANDERS|STINGS),"2d5",19,'R',10,3,12,70,0,0,0,0,0}, {(ASLEEP|WAKENS|WANDERS),"1d3",8,'S',2,1,9,50,0,0,0,0,0}, {(ASLEEP|WAKENS|WANDERS),"4d6/1d4",75,'T',125,13,22,75,0,33,0,0,0}, {(ASLEEP|WAKENS|WANDERS),"4d10",90,'U', 200,17,26,85,0,33,0,0,0}, {(ASLEEP|WAKENS|WANDERS|DRAINS_LIFE),"1d14/1d4",55,'V', 350,19,126,85,0,18,0,0,0}, {(ASLEEP|WANDERS|DRAINS_LEVEL),"2d8",45,'W',55,14,23,75,0,0,0,0,0}, {(ASLEEP|IMITATES),"4d6",42,'X',110,16,25,75,0,0,0,0,0}, {(ASLEEP|WANDERS),"3d6",35,'Y',50,11,20,80,0,20,0,0,0}, {(ASLEEP|WAKENS|WANDERS),"1d7",21,'Z',8,5,14,69,0,0,0,0,0} }; extern short current_level; extern short current_room, party_room; extern short blind, halluc, haste_self; extern boolean detect_monster, see_invisible, r_see_invisible; extern short stealthy; put_monsters() { short i; short n; object *monster, *get_rand_monster(); short row, col; n = get_rand(4, 6); for (i = 0; i < n; i++) { monster = get_rand_monster((object *) 0, 0); if ((monster->m_flags & WANDERS) && coin_toss()) { wake_up(monster); } get_rand_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT)); put_monster_at(row, col, monster); } } object * get_rand_monster(monster, mn) register object *monster; register mn; { object *alloc_object(); if (!monster) { monster = alloc_object(); for (;;) { mn = get_rand(0, MONSTERS-1); if ((current_level >= monster_tab[mn].first_level) && (current_level <= monster_tab[mn].last_level)) { break; } } } *monster = monster_tab[mn]; if (monster->m_flags & IMITATES) { monster->disguise = get_rand_obj_char(); } if (current_level > (AMULET_LEVEL + 2)) { monster->m_flags |= HASTED; } monster->trow = NO_ROOM; return(monster); } move_monsters() { register object *monster, *next_monster; boolean flew; if (haste_self % 2) { return; } monster = level_monsters.next_monster; while (monster) { next_monster = monster->next_monster; if (monster->m_flags & HASTED) { monster_disappeared = 0; mv_monster(monster, rogue.row, rogue.col); if (monster_disappeared) { goto NM; } } else if (monster->m_flags & SLOWED) { monster->slowed_toggle = !monster->slowed_toggle; if (monster->slowed_toggle) { goto NM; } } if ((monster->m_flags & CONFUSED) && confused_move(monster)) { goto NM; } flew = 0; if ((monster->m_flags & FLIES) && !(monster->m_flags & NAPPING) && !monster_can_go(monster, rogue.row, rogue.col)) { flew = 1; mv_monster(monster, rogue.row, rogue.col); } if (!(flew && monster_can_go(monster, rogue.row, rogue.col))) { mv_monster(monster, rogue.row, rogue.col); } NM: monster = next_monster; } } fill_party_room_with_monsters(rn, n) int rn, n; { short i, j; short row, col; object *monster, *get_rand_monster(); boolean found; n += n; for (i = 0; i < MONSTERS; i++) { monster_tab[i].first_level -= (current_level % 3); } for (i = 0; i < n; i++) { if (no_room_for_monster(rn)) { break; } for (j = found = 0; ((!found) && (j < 250)); j++) { 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); if ((!(dungeon[row][col] & MONSTER)) && (dungeon[row][col] & (FLOOR | TUNNEL))) { found = 1; } } if (found) { monster = get_rand_monster((object *) 0, 0); if (!(monster->m_flags & IMITATES)) { monster->m_flags |= WAKENS; } put_monster_at(row, col, monster); } } for (i = 0; i < MONSTERS; i++) { monster_tab[i].first_level += (current_level % 3); } } get_monster_char_row_col(row, col) register row, col; { register object *monster; object *object_at(); short retval; if (monster = object_at(&level_monsters, row, col)) { if ((!(detect_monster || see_invisible || r_see_invisible) && (monster->m_flags & INVISIBLE)) || blind) { retval = monster->trail_char; return(retval); } if (monster->m_flags & IMITATES) { return(monster->disguise); } return(monster->m_char); } } get_monster_char(monster) object *monster; { if ((!(detect_monster || see_invisible || r_see_invisible) && (monster->m_flags & INVISIBLE)) || blind) { return(monster->trail_char); } if (monster->m_flags & IMITATES) { return(monster->disguise); } return(monster->m_char); } mv_monster(monster, row, col) register object *monster; short row, col; { short i, n; boolean tried[6]; short wake_percent; if (monster->m_flags & ASLEEP) { if (monster->m_flags & NAPPING) { if (--monster->nap_length <= 0) { monster->m_flags &= (~(NAPPING | ASLEEP)); } return; } if ((monster->m_flags & WAKENS) && rogue_is_around(monster->row, monster->col) && rand_percent(((stealthy > 0) ? (WAKE_PERCENT / (STEALTH_FACTOR + stealthy)) : WAKE_PERCENT))) { wake_up(monster); } return; } else if (monster->m_flags & ALREADY_MOVED) { monster->m_flags &= (~ALREADY_MOVED); return; } if ((monster->m_flags & FLITS) && flit(monster)) { return; } if ((monster->m_flags & STATIONARY) && (!monster_can_go(monster, rogue.row, rogue.col))) { return; } if (monster->m_flags & FREEZING_ROGUE) { return; } if ((monster->m_flags & CONFUSES) && m_confuse(monster)) { return; } if (monster_can_go(monster, rogue.row, rogue.col)) { monster_hit(monster, 0, 0); return; } if ((monster->m_flags & FLAMES) && flame_broil(monster)) { return; } if ((monster->m_flags & SEEKS_GOLD) && seek_gold(monster)) { return; } if ((monster->trow == monster->row) && (monster->tcol == monster->col)) { monster->trow = NO_ROOM; } else if (monster->trow != NO_ROOM) { row = monster->trow; col = monster->tcol; } if (monster->row > row) { row = monster->row - 1; } else if (monster->row < row) { row = monster->row + 1; } if ((dungeon[row][monster->col] & DOOR) && mtry(monster, row, monster->col)) { return; } if (monster->col > col) { col = monster->col - 1; } else if (monster->col < col) { col = monster->col + 1; } if ((dungeon[monster->row][col] & DOOR) && mtry(monster, monster->row, col)) { return; } if (mtry(monster, row, col)) { return; } for (i = 0; i <= 5; i++) tried[i] = 0; for (i = 0; i < 6; i++) { NEXT_TRY: n = get_rand(0, 5); switch(n) { case 0: if (!tried[n] && mtry(monster, row, monster->col-1)) { goto O; } break; case 1: if (!tried[n] && mtry(monster, row, monster->col)) { goto O; } break; case 2: if (!tried[n] && mtry(monster, row, monster->col+1)) { goto O; } break; case 3: if (!tried[n] && mtry(monster, monster->row-1, col)) { goto O; } break; case 4: if (!tried[n] && mtry(monster, monster->row, col)) { goto O; } break; case 5: if (!tried[n] && mtry(monster, monster->row+1, col)) { goto O; } break; } if (!tried[n]) { tried[n] = 1; } else { goto NEXT_TRY; } } O: if ((monster->row == monster->o_row) && (monster->col == monster->o_col)) { if (++(monster->o) > 4) { if ((monster->trow == NO_ROOM) && (!monster_can_see(monster, rogue.row, rogue.col))) { monster->trow = get_rand(1, (DROWS - 2)); monster->tcol = get_rand(0, (DCOLS - 1)); } else { monster->trow = NO_ROOM; monster->o = 0; } } } else { monster->o_row = monster->row; monster->o_col = monster->col; monster->o = 0; } } mtry(monster, row, col) register object *monster; register short row, col; { if (monster_can_go(monster, row, col)) { move_monster_to(monster, row, col); return(1); } return(0); } move_monster_to(monster, row, col) register object *monster; register short row, col; { short c; register mrow, mcol; mrow = monster->row; mcol = monster->col; dungeon[mrow][mcol] &= ~MONSTER; dungeon[row][col] |= MONSTER; c = mvinch(mrow, mcol); if ((c >= 'A') && (c <= 'Z')) { if (!detect_monster) { mvaddch(mrow, mcol, monster->trail_char); } else { if (rogue_can_see(mrow, mcol)) { mvaddch(mrow, mcol, monster->trail_char); } else { if (monster->trail_char == '.') { monster->trail_char = ' '; } mvaddch(mrow, mcol, monster->trail_char); } } } monster->trail_char = mvinch(row, col); if (!blind && (detect_monster || rogue_can_see(row, col))) { if ((!(monster->m_flags & INVISIBLE) || (detect_monster || see_invisible || r_see_invisible))) { mvaddch(row, col, get_monster_char(monster)); } } if ((dungeon[row][col] & DOOR) && (get_room_number(row, col) != current_room) && (dungeon[mrow][mcol] == FLOOR) && !blind) { mvaddch(mrow, mcol, ' '); } if (dungeon[row][col] & DOOR) { door_course(monster, (dungeon[mrow][mcol] & TUNNEL), row, col); } else { monster->row = row; monster->col = col; } } monster_can_go(monster, row, col) register object *monster; register short row, col; { object *obj, *object_at(); short dr, dc; dr = monster->row - row; /* check if move distance > 1 */ if ((dr >= 2) || (dr <= -2)) { return(0); } dc = monster->col - col; if ((dc >= 2) || (dc <= -2)) { return(0); } if ((!dungeon[monster->row][col]) || (!dungeon[row][monster->col])) { return(0); } if ((!is_passable(row, col)) || (dungeon[row][col] & MONSTER)) { return(0); } if ((monster->row!=row)&&(monster->col!=col)&&((dungeon[row][col]&DOOR) || (dungeon[monster->row][monster->col]&DOOR))) { return(0); } if (!(monster->m_flags & (FLITS | CONFUSED | CAN_FLIT)) && (monster->trow == NO_ROOM)) { if ((monster->row < rogue.row) && (row < monster->row)) return(0); if ((monster->row > rogue.row) && (row > monster->row)) return(0); if ((monster->col < rogue.col) && (col < monster->col)) return(0); if ((monster->col > rogue.col) && (col > monster->col)) return(0); } if (dungeon[row][col] & OBJECT) { obj = object_at(&level_objects, row, col); if ((obj->what_is == SCROLL) && (obj->which_kind == SCARE_MONSTER)) { return(0); } } return(1); } wake_up(monster) object *monster; { if (!(monster->m_flags & NAPPING)) { monster->m_flags &= (~(ASLEEP | IMITATES | WAKENS)); } } wake_room(rn, entering, row, col) short rn; boolean entering; short row, col; { object *monster; short wake_percent; boolean in_room; wake_percent = (rn == party_room) ? PARTY_WAKE_PERCENT : WAKE_PERCENT; if (stealthy > 0) { wake_percent /= (STEALTH_FACTOR + stealthy); } monster = level_monsters.next_monster; while (monster) { in_room = (rn == get_room_number(monster->row, monster->col)); if (in_room) { if (entering) { monster->trow = NO_ROOM; } else { monster->trow = row; monster->tcol = col; } } if ((monster->m_flags & WAKENS) && (rn == get_room_number(monster->row, monster->col))) { if (rand_percent(wake_percent)) { wake_up(monster); } } monster = monster->next_monster; } } char *monster_name(monster) object *monster; { short ch; if (blind || ((monster->m_flags & INVISIBLE) && !(detect_monster || see_invisible || r_see_invisible))) { return("something"); } if (halluc) { ch = get_rand('A', 'Z') - 'A'; return(monster_names[ch]); } ch = monster->m_char - 'A'; return(monster_names[ch]); } rogue_is_around(row, col) register row, col; { short rdif, cdif, retval; rdif = row - rogue.row; cdif = col - rogue.col; retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1); return(retval); } start_wanderer() { object *monster, *get_rand_monster(); short row, col, i; ANOTHER: monster = get_rand_monster((object *) 0, 0); if ((!(monster->m_flags & WAKENS)) && (!(monster->m_flags & WANDERS))) { free_object(monster); goto ANOTHER; } wake_up(monster); for (i = 0; i < 10; i++) { get_rand_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT)); if (!rogue_can_see(row, col)) { put_monster_at(row, col, monster); return; } } free_object(monster); } show_monsters() { object *monster; detect_monster = 1; if (blind) { return; } monster = level_monsters.next_monster; while (monster) { mvaddch(monster->row, monster->col, monster->m_char); if (monster->m_flags & IMITATES) { monster->m_flags &= (~IMITATES); monster->m_flags |= WAKENS; } monster = monster->next_monster; } } create_monster() { short row, col; short i, j; boolean found = 0; object *monster; row = rogue.row; col = rogue.col; for (i = 0; i < 9; i++) { rand_around(i, &row, &col); if (((row == rogue.row) && (col = rogue.col)) || (row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col > (DCOLS-1))) { continue; } if ((!(dungeon[row][col] & MONSTER)) && (dungeon[row][col] & (FLOOR|TUNNEL|STAIRS|DOOR))) { found = 1; break; } } if (found) { monster = get_rand_monster((object *) 0, 0); put_monster_at(row, col, monster); mvaddch(row, col, get_monster_char(monster)); if (monster->m_flags & (WANDERS | WAKENS)) { wake_up(monster); } } else { message("you hear a faint cry of anguish in the distance", 0); } } put_monster_at(row, col, monster) object *monster; { object *add_to_pack(); monster->row = row; monster->col = col; dungeon[row][col] |= MONSTER; monster->trail_char = mvinch(row, col); add_to_pack(monster, &level_monsters, 0); aim_monster(monster); } aim_monster(monster) object *monster; { short i, rn, d, r; rn = get_room_number(monster->row, monster->col); r = get_rand(0, 12); for (i = 0; i < 4; i++) { d = (r + i) % 4; if (rooms[rn].doors[d].other_room != NO_ROOM) { monster->trow = rooms[rn].doors[d].door_row; monster->tcol = rooms[rn].doors[d].door_col; break; } } } rogue_can_see(row, col) register row, col; { register retval; retval = !blind && (((get_room_number(row, col) == current_room) && !(rooms[current_room].is_room & R_MAZE)) || rogue_is_around(row, col)); return(retval); } confused_move(monster) object *monster; { short i, row, col; if (!(monster->m_flags & ASLEEP)) { if (--monster->moves_confused <= 0) { monster->m_flags &= (~CONFUSED); } if (monster->m_flags & STATIONARY) { return(coin_toss() ? 1 : 0); } else if (rand_percent(15)) { return(1); } row = monster->row; col = monster->col; for (i = 0; i < 9; i++) { rand_around(i, &row, &col); if ((row == rogue.row) && (col == rogue.col)) { return(0); } if (mtry(monster, row, col)) { return(1); } } } return(0); } flit(monster) object *monster; { short i, row, col; if (!rand_percent(FLIT_PERCENT)) { return(0); } if (rand_percent(10)) { return(1); } row = monster->row; col = monster->col; for (i = 0; i < 9; i++) { rand_around(i, &row, &col); if ((row == rogue.row) && (col == rogue.col)) { continue; } if (mtry(monster, row, col)) { return(1); } } return(1); } put_monster_rand_location(monster) object *monster; { short row, col; get_rand_row_col(&row, &col, (FLOOR | TUNNEL | STAIRS | OBJECT)); put_monster_at(row, col, MONSTER); } get_rand_obj_char() { short r; char *rs = "%!?]/):*"; r = get_rand(0, 7); return(rs[r]); } no_room_for_monster(rn) int rn; { short i, j; 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 (!(dungeon[i][j] & MONSTER)) { return(0); } } } return(1); } aggravate() { struct object *monster; message("you hear a high pitched humming noise", 0); monster = level_monsters.next_monster; while (monster) { wake_up(monster); monster->m_flags &= (~IMITATES); monster = monster->next_monster; if (rogue_can_see(monster->row, monster->col)) { mvaddch(monster->row, monster->col, monster->m_char); } } } monster_can_see(monster, row, col) object *monster; { short rn, rdif, cdif, retval; rn = get_room_number(row, col); if ( (rn != NO_ROOM) && (rn == get_room_number(monster->row, monster->col)) && !(rooms[rn].is_room & R_MAZE)) { return(1); } rdif = row - monster->row; cdif = col - monster->col; retval = (rdif >= -1) && (rdif <= 1) && (cdif >= -1) && (cdif <= 1); return(retval); } mv_aquatars() { object *monster; monster = level_monsters.next_monster; while (monster) { if ((monster->m_char == 'A') && monster_can_go(monster, rogue.row, rogue.col)) { mv_monster(monster, rogue.row, rogue.col); monster->m_flags |= ALREADY_MOVED; } monster = monster->next_monster; } } SHAR_EOF echo shar: extracting monster.h cat - << \SHAR_EOF > monster.h /* * monster.h * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #define MONSTERS 26 #define HASTED 01L #define SLOWED 02L #define INVISIBLE 04L #define ASLEEP 010L #define WAKENS 020L #define WANDERS 040L #define FLIES 0100L #define FLITS 0200L #define CAN_FLIT 0400L /* can, but usually doesn't, flit */ #define CONFUSED 01000L #define RUSTS 02000L #define HOLDS 04000L #define FREEZES 010000L #define STEALS_GOLD 020000L #define STEALS_ITEM 040000L #define STINGS 0100000L #define DRAINS_LIFE 0200000L #define DRAINS_LEVEL 0400000L #define SEEKS_GOLD 01000000L #define FREEZING_ROGUE 02000000L #define RUST_VANISHED 04000000L #define CONFUSES 010000000L #define IMITATES 020000000L #define FLAMES 040000000L #define STATIONARY 0100000000L /* damage will be 1,2,3,... */ #define NAPPING 0200000000L /* can't wake up for a while */ #define ALREADY_MOVED 0400000000L #define SPECIAL_HIT (RUSTS|HOLDS|FREEZES|STEALS_GOLD|STEALS_ITEM|STINGS|DRAINS_LIFE|DRAINS_LEVEL) #define WAKE_PERCENT 45 #define FLIT_PERCENT 33 #define PARTY_WAKE_PERCENT 75 #define HYPOTHERMIA 1 #define STARVATION 2 #define POISON_DART 3 #define QUIT 4 #define WIN 5 SHAR_EOF echo shar: extracting room.h cat - << \SHAR_EOF > room.h /* * room.h * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #define MAXROOMS 9 #define BIG_ROOM 10 #define NO_ROOM -1 #define PASSAGE -3 /* current_room value */ #define SCORE_FILE "SCORE_FILE" #define AMULET_LEVEL 26 #define R_NOTHING ((unsigned short) 01) #define R_ROOM ((unsigned short) 02) #define R_MAZE ((unsigned short) 04) #define R_DEADEND ((unsigned short) 010) #define R_CROSS ((unsigned short) 020) #define MAX_EXP_LEVEL 21 #define MAX_EXP 10000000L #define MAX_GOLD 900000 #define MAX_ARMOR 99 #define MAX_HP 800 #define MAX_STRENGTH 99 #define LAST_DUNGEON 99 #define STAT_LEVEL 01 #define STAT_GOLD 02 #define STAT_HP 04 #define STAT_STRENGTH 010 #define STAT_ARMOR 020 #define STAT_EXP 040 #define STAT_HUNGER 0100 #define STAT_LABEL 0200 #define STAT_ALL 0377 #define PARTY_TIME 10 /* one party somewhere in each 10 level span */ #define MAX_TRAPS 10 /* maximum traps per level */ #define HIDE_PERCENT 12 SHAR_EOF echo shar: extracting move.c cat - << \SHAR_EOF > move.c /* * move.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "object.h" #include "room.h" #include "move.h" #include "monster.h" short m_moves = 0; boolean jump = 1; char *you_can_move_again = "you can move again"; extern short current_room, halluc, blind, levitate; extern short current_level, max_level; extern short bear_trap, haste_self, confused; extern short e_rings, regeneration, auto_search; extern char hunger_str[]; extern boolean being_held, interrupted, r_teleport; single_move_rogue(dirch, pickup) short dirch, pickup; { short row, col; object *obj, *object_at(), *pick_up(); char description[DCOLS]; short n, status; row = rogue.row; col = rogue.col; if (confused) { dirch = get_rand_dir(); } get_dir_rc(dirch, &row, &col, 1); if (!can_move(rogue.row, rogue.col, row, col)) { return(MOVE_FAILED); } if (being_held || bear_trap) { if (!(dungeon[row][col] & MONSTER)) { if (being_held) { message("you are being held", 1); } else { message("you are still stuck in the bear trap", 0); register_move(); } return(MOVE_FAILED); } } if (r_teleport) { if (rand_percent(R_TELEPORT_PERCENT)) { teleport(); return(STOPPED_ON_SOMETHING); } } if (dungeon[row][col] & MONSTER) { rogue_hit(object_at(&level_monsters, row, col), 0); register_move(); return(MOVE_FAILED); } if (dungeon[row][col] & DOOR) { if (current_room == PASSAGE) { current_room = get_room_number(row, col); light_up_room(); wake_room(current_room, 1, row, col); } else { light_passage(row, col); } } else if ((dungeon[rogue.row][rogue.col] & DOOR) && (dungeon[row][col] & TUNNEL)) { light_passage(row, col); wake_room(current_room, 0, rogue.row, rogue.col); darken_room(current_room); current_room = PASSAGE; } else if (dungeon[row][col] & TUNNEL) { light_passage(row, col); } mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col)); mvaddch(row, col, rogue.fchar); if (!jump) { refresh(); } rogue.row = row; rogue.col = col; if (dungeon[row][col] & OBJECT) { if (levitate && pickup) { return(STOPPED_ON_SOMETHING); } if (pickup && !levitate) { if (obj = pick_up(row, col, &status)) { get_description(obj, description); if (obj->what_is == GOLD) { free_object(obj); goto NOT_IN_PACK; } } else if (!status) { goto MVED; } else { goto MOVE_ON; } } else { MOVE_ON: obj = object_at(&level_objects, row, col); strcpy(description, "moved onto "); get_description(obj, description+11); goto NOT_IN_PACK; } n = strlen(description); description[n] = '('; description[n+1] = obj->ichar; description[n+2] = ')'; description[n+3] = 0; NOT_IN_PACK: message(description, 1); register_move(); return(STOPPED_ON_SOMETHING); } if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) { if ((!levitate) && (dungeon[row][col] & TRAP)) { trap_rogue(row, col); } register_move(); return(STOPPED_ON_SOMETHING); } MVED: if (register_move()) { /* fainted from hunger */ return(STOPPED_ON_SOMETHING); } return((confused ? STOPPED_ON_SOMETHING : MOVED)); } multiple_move_rogue(dirch) { short row, col; short m; switch(dirch) { case '\010': case '\012': case '\013': case '\014': case '\031': case '\025': case '\016': case '\002': do { row = rogue.row; col = rogue.col; if (((m = single_move_rogue((dirch + 96), 1)) == MOVE_FAILED) || (m == STOPPED_ON_SOMETHING) || interrupted) { break; } } while (!next_to_something(row, col)); break; case 'H': case 'J': case 'K': case 'L': case 'B': case 'Y': case 'U': case 'N': while (!interrupted && single_move_rogue((dirch + 32), 1) == MOVED) ; break; } } is_passable(row, col) register row, col; { if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) || (col > (DCOLS-1))) { return(0); } if (dungeon[row][col] & HIDDEN) { return((dungeon[row][col] & TRAP) ? 1 : 0); } return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP)); } next_to_something(drow, dcol) register drow, dcol; { short i, j, i_end, j_end, row, col; short pass_count = 0; unsigned short s; if (confused) { return(1); } if (blind) { return(0); } i_end = (rogue.row < (DROWS-2)) ? 1 : 0; j_end = (rogue.col < (DCOLS-1)) ? 1 : 0; for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) { for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) { if ((i == 0) && (j == 0)) { continue; } if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) { continue; } row = rogue.row + i; col = rogue.col + j; s = dungeon[row][col]; if (s & HIDDEN) { continue; } /* If the rogue used to be right up, left, down, or right of * row,col, and now isn't, then don't stop */ if (s & (MONSTER | OBJECT | STAIRS)) { if (((row == drow) || (col == dcol)) && (!((row == rogue.row) || (col == rogue.col)))) { continue; } return(1); } if (s & TRAP) { if (!(s & HIDDEN)) { if (((row == drow) || (col == dcol)) && (!((row == rogue.row) || (col == rogue.col)))) { continue; } return(1); } } if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) { if (++pass_count > 1) { return(1); } } if ((s & DOOR) && ((i == 0) || (j == 0))) { return(1); } } } return(0); } can_move(row1, col1, row2, col2) { if (!is_passable(row2, col2)) { return(0); } if ((row1 != row2) && (col1 != col2)) { if ((dungeon[row1][col1]&DOOR)||(dungeon[row2][col2]&DOOR)) { return(0); } if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) { return(0); } } return(1); } move_onto() { short ch; boolean first_miss = 1; while (!is_direction(ch = rgetchar())) { sound_bell(); if (first_miss) { message("direction? ", 0); first_miss = 0; } } check_message(); if (ch != CANCEL) { single_move_rogue(ch, 0); } } is_direction(c) { return( (c == 'h') || (c == 'j') || (c == 'k') || (c == 'l') || (c == 'b') || (c == 'y') || (c == 'u') || (c == 'n') || (c == CANCEL) ); } boolean check_hunger(messages_only) boolean messages_only; { register short i, n; boolean fainted = 0; if (rogue.moves_left == HUNGRY) { strcpy(hunger_str, "hungry"); message(hunger_str, 0); print_stats(STAT_HUNGER); } if (rogue.moves_left == WEAK) { strcpy(hunger_str, "weak"); message(hunger_str, 1); print_stats(STAT_HUNGER); } if (rogue.moves_left <= FAINT) { if (rogue.moves_left == FAINT) { strcpy(hunger_str, "faint"); message(hunger_str, 1); print_stats(STAT_HUNGER); } n = get_rand(0, (FAINT - rogue.moves_left)); if (n > 0) { fainted = 1; if (rand_percent(40)) { rogue.moves_left++; } message("you faint", 1); for (i = 0; i < n; i++) { if (coin_toss()) { move_monsters(); } } message(you_can_move_again, 1); } } if (messages_only) { return(fainted); } if (rogue.moves_left <= STARVE) { killed_by(0, STARVATION); } switch(e_rings) { /*case -2: Subtract 0, i.e. do nothing. break;*/ case -1: rogue.moves_left -= (rogue.moves_left % 2); break; case 0: rogue.moves_left--; break; case 1: rogue.moves_left--; check_hunger(1); rogue.moves_left -= (rogue.moves_left % 2); break; case 2: rogue.moves_left--; check_hunger(1); rogue.moves_left--; break; } return(fainted); } register_move() { boolean fainted, check_hunger(); if ((rogue.moves_left <= HUNGRY) || (current_level >= max_level)) { fainted = check_hunger(0); } else { fainted = 0; } move_monsters(); if (++m_moves >= 120) { m_moves = 0; start_wanderer(); } if (halluc) { if (!(--halluc)) { unhallucinate(); } else { hallucinate(); } } if (blind) { if (!(--blind)) { unblind(); } } if (confused) { if (!(--confused)) { unconfuse(); } } if (bear_trap) { bear_trap--; } if (levitate) { if (!(--levitate)) { message("you float gently to the ground", 1); if (dungeon[rogue.row][rogue.col] & TRAP) { trap_rogue(rogue.row, rogue.col); } } } if (haste_self) { if (!(--haste_self)) { message("you feel yourself slowing down", 0); } } heal(); if (auto_search > 0) { search(auto_search, auto_search); } return(fainted); } rest(count) { int i; interrupted = 0; for (i = 0; i < count; i++) { if (interrupted) { break; } register_move(); } } get_rand_dir() { short d; d = get_rand(1, 8); switch(d) { case 1: return('j'); case 2: return('k'); case 3: return('l'); case 4: return('h'); case 5: return('y'); case 6: return('u'); case 7: return('b'); case 8: return('n'); } } heal() { static short heal_exp = -1, n, c = 0; static boolean alt; if (rogue.hp_current == rogue.hp_max) { c = 0; return; } if (rogue.exp != heal_exp) { heal_exp = rogue.exp; switch(heal_exp) { case 1: n = 20; break; case 2: n = 18; break; case 3: n = 17; break; case 4: n = 14; break; case 5: n = 13; break; case 6: n = 10; break; case 7: n = 9; break; case 8: n = 8; break; case 9: n = 7; break; case 10: n = 4; break; case 11: n = 3; break; case 12: default: n = 2; } } if (++c >= n) { c = 0; rogue.hp_current++; if (alt = !alt) { rogue.hp_current++; } if ((rogue.hp_current += regeneration) > rogue.hp_max) { rogue.hp_current = rogue.hp_max; } print_stats(STAT_HP); } } SHAR_EOF echo shar: extracting move.h cat - << \SHAR_EOF > move.h /* * move.h * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #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 DIRS 8 #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 150 #define FAINT 20 #define STARVE 0 #define MIN_ROW 1 SHAR_EOF echo shar: extracting special_hit.c cat - << \SHAR_EOF > special_hit.c /* * special_hit.c * * This source herein may be modified and/or distributed by anybody who * so desires, with the following restrictions: * 1.) This notice shall not be removed. * 2.) Credit shall not be taken for the creation of this source. * 3.) This code is not to be traded, sold, or used for personal * gain or profit. * */ #include <curses.h> #include "object.h" #include "move.h" #include "monster.h" #include "room.h" short being_held, less_hp = 0; char *flame_name = "flame"; extern short current_level, max_level, blind, levitate, ring_exp; extern long level_points[]; extern boolean detect_monster, monster_disappeared; extern boolean sustain_strength, maintain_armor; extern char *you_can_move_again; special_hit(monster) object *monster; { if ((monster->m_flags & CONFUSED) && rand_percent(66)) { return; } if (monster->m_flags & RUSTS) { rust(monster); } if ((monster->m_flags & HOLDS) && !levitate) { being_held = 1; } if (monster->m_flags & FREEZES) { freeze(monster); } if (monster->m_flags & STINGS) { sting(monster); } if (monster->m_flags & DRAINS_LIFE) { drain_life(); } if (monster->m_flags & DRAINS_LEVEL) { drain_level(); } if (monster->m_flags & STEALS_GOLD) { steal_gold(monster); } else if (monster->m_flags & STEALS_ITEM) { steal_item(monster); } } rust(monster) object *monster; { if ((!rogue.armor) || (get_armor_class(rogue.armor) <= 1) || (rogue.armor->which_kind == LEATHER)) { return; } if ((rogue.armor->is_protected) || maintain_armor) { if (monster && (!(monster->m_flags & RUST_VANISHED))) { message("the rust vanishes instantly", 0); monster->m_flags |= RUST_VANISHED; } } else { rogue.armor->damage_enchantment--; message("your armor weakens", 0); print_stats(STAT_ARMOR); } } 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 + ring_exp) * 4); freeze_percent -= (get_armor_class(rogue.armor) * 5); freeze_percent -= (rogue.hp_max / 3); if (freeze_percent > 10) { monster->m_flags |= FREEZING_ROGUE; message("you are frozen", 1); n = get_rand(4, 8); 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->m_flags &= (~FREEZING_ROGUE); } } steal_gold(monster) object *monster; { int amount; if ((rogue.gold <= 0) || rand_percent(10)) { return; } amount = get_rand((current_level * 10), (current_level * 30)); if (amount > rogue.gold) { amount = rogue.gold; } rogue.gold -= amount; message("your purse feels lighter", 0); print_stats(STAT_GOLD); disappear(monster); } steal_item(monster) object *monster; { object *obj; short i, n, t; char description[80]; boolean has_something = 0; if (rand_percent(15)) { return; } obj = rogue.pack.next_object; if (!obj) { goto DSPR; } while (obj) { if (!(obj->in_use_flags & BEING_USED)) { 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->in_use_flags & BEING_USED)) { if (!obj) { obj = rogue.pack.next_object; } else { obj = obj->next_object; } } } strcpy(description, "she stole "); if (obj->what_is != WEAPON) { t = obj->quantity; obj->quantity = 1; } get_description(obj, description+10); message(description, 0); obj->quantity = ((obj->what_is != WEAPON) ? t : 1); vanish(obj, 0, &rogue.pack); DSPR: disappear(monster); } disappear(monster) object *monster; { short row, col; object *obj, *object_at(); row = monster->row; col = monster->col; dungeon[row][col] &= ~MONSTER; if (rogue_can_see(row, col)) { mvaddch(row, col, get_dungeon_char(row, col)); } remove_from_pack(monster, &level_monsters); free_object(monster); monster_disappeared = 1; } cough_up(monster) object *monster; { object *obj, *alloc_object(),*get_rand_object(); short row, col, i, n; if (current_level < max_level) { return; } if (monster->m_flags & STEALS_GOLD) { obj = alloc_object(); obj->what_is = GOLD; obj->quantity = get_rand((current_level * 15), (current_level * 30)); } else { if (!rand_percent(monster->drop_percent)) { return; } obj = get_rand_object(); } 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_object(obj); } try_to_cough(row, col, obj) short row, col; object *obj; { if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col>(DCOLS-1))) { return(0); } if ((!(dungeon[row][col] & (OBJECT | STAIRS | TRAP))) && (dungeon[row][col] & (TUNNEL | FLOOR | DOOR))) { put_object_at(obj, row, col); if (((row != rogue.row) || (col != rogue.col)) && (!(dungeon[row][col] & MONSTER))) { mvaddch(row, col, get_dungeon_char(row, col)); } return(1); } return(0); } seek_gold(monster) object *monster; { short i, j, rn, s; 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 ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) { monster->m_flags |= CAN_FLIT; s = monster_can_go(monster, i, j); monster->m_flags &= (~CAN_FLIT); if (s) { move_monster_to(monster, i, j); monster->m_flags |= ASLEEP; monster->m_flags &= (~(WAKENS | SEEKS_GOLD)); return(1); } monster->m_flags &= (~SEEKS_GOLD); monster->m_flags |= CAN_FLIT; mv_monster(monster, i, j); monster->m_flags &= (~CAN_FLIT); monster->m_flags |= SEEKS_GOLD; return(1); } } } return(0); } gold_at(row, col) short row, col; { if (dungeon[row][col] & OBJECT) { struct object *obj; if ((obj = object_at(&level_objects, row, col)) && (obj->what_is == GOLD)) { return(1); } } return(0); } check_gold_seeker(monster) object *monster; { monster->m_flags &= (~SEEKS_GOLD); } check_imitator(monster) object *monster; { char *monster_name(); char msg[80]; if (monster->m_flags & IMITATES) { wake_up(monster); if (!blind) { mvaddch(monster->row, monster->col, get_dungeon_char(monster->row, monster->col)); check_message(); sprintf(msg, "wait, that's a %s!", monster_name(monster)); message(msg, 1); } return(1); } return(0); } imitating(row, col) register short row, col; { object *object_at(), *monster; if (!(dungeon[row][col] & MONSTER)) { return(0); } monster = object_at(&level_monsters, row, col); if (monster->m_flags & IMITATES) { return(1); } return(0); } sting(monster) object *monster; { short sting_chance = 35; char msg[80], *monster_name(); if ((rogue.strength_current <= 3) || sustain_strength) { return; } sting_chance += (6 * (6 - get_armor_class(rogue.armor))); if ((rogue.exp + ring_exp) > 8) { sting_chance -= (6 * ((rogue.exp + ring_exp) - 8)); } 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(STAT_STRENGTH); } } drain_level() { int hp; if (rand_percent(80) || (rogue.exp <= 5)) { return; } rogue.exp_points = level_points[rogue.exp-2] - get_rand(9, 29); rogue.exp -= 2; hp = get_rand_hp_raise(); if ((rogue.hp_current -= hp) <= 0) { rogue.hp_current = 1; } if ((rogue.hp_max -= hp) <= 0) { rogue.hp_max = 1; } add_exp(1, 0); } drain_life() { short n; if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) { return; } n = get_rand(1, 3); /* 1 Hp, 2 Str, 3 both */ if ((n != 2) || (!sustain_strength)) { message("you feel weaker", 0); } if (n != 2) { rogue.hp_max--; rogue.hp_current--; less_hp++; } if (n != 1) { if ((rogue.strength_current > 3) && (!sustain_strength)) { rogue.strength_current--; if (coin_toss()) { rogue.strength_max--; } } } print_stats((STAT_STRENGTH | STAT_HP)); } m_confuse(monster) object *monster; { char msg[80]; char *monster_name(); if (!rogue_can_see(monster->row, monster->col)) { return(0); } if (rand_percent(45)) { monster->m_flags &= (~CONFUSES); /* will not confuse the rogue */ return(0); } if (rand_percent(55)) { monster->m_flags &= (~CONFUSES); 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, t; if ((!monster_can_see(monster, rogue.row, rogue.col)) || coin_toss()) { return(0); } row = rogue.row - monster->row; col = rogue.col - monster->col; if (row < 0) { row = -row; } if (col < 0) { col = -col; } if (((row != 0) && (col != 0) && (row != col)) || ((row > 7) || (col > 7))) { return(0); } if ((!blind) && (!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_dungeon_char(row, col)); refresh(); get_closer(&row, &col, rogue.row, rogue.col); } while ((row != rogue.row) || (col != rogue.col)); } monster_hit(monster, flame_name, 1); 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