rich@sdcsvax.UUCP (rich) (08/04/86)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # macros.h # main.c # make.com # message.c # monster.c # monster.h # move.c # move.h # This archive created: Mon Aug 4 11:41:45 1986 # By: rich ( lack of) export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'macros.h' then echo shar: "will not over-write existing file 'macros.h'" else cat << \SHAR_EOF > 'macros.h' #define swap(x,y) {int t; t = x; x = y; y = t;} #define two_sort(x,y) if (x > y) {int t; t = x; x = y; y = t;} #define swap_string(x,y) {char *t; t = x; x = y; y = t;} SHAR_EOF fi if test -f 'main.c' then echo shar: "will not over-write existing file 'main.c'" else cat << \SHAR_EOF > 'main.c' #include curses.h #include "object.h" short chan; main() { init(); for (;;) { clear_level(); make_level(); put_objects(); put_stairs(); put_monsters(); put_player(); light_up_room(); print_stats(); play_level(); free_stuff(&level_objects); free_stuff(&level_monsters); clear(); } } SHAR_EOF fi if test -f 'make.com' then echo shar: "will not over-write existing file 'make.com'" else cat << \SHAR_EOF > 'make.com' $set noon $define lnk$library sys$library:vaxccurse $define lnk$library_1 sys$library:vaxcrtl $cc DOORCOU.C $cc help.c $cc HIT.C $cc INIT.C $cc INVENTOR.C $cc IO.C $cc LEVEL.C $cc MESSAGE.C $cc MONSTER.C $cc MOVE.C $cc OBJECT.C $cc PACK.C $cc PLAY.C $cc RANDOM.C $cc ROOM.C $cc SCORE.C $cc SPECIAL.C $cc THROW.C $cc USE.C $cc ZAP.C $library/create rogue HIT $library/replace rogue help $library/replace rogue INIT $library/replace rogue INVENTOR $library/replace rogue doorcou $library/replace rogue IO $library/replace rogue LEVEL $library/replace rogue MESSAGE $library/replace rogue MONSTER $library/replace rogue MOVE $library/replace rogue OBJECT $library/replace rogue PACK $library/replace rogue PLAY $library/replace rogue RANDOM $library/replace rogue ROOM $library/replace rogue SCORE $library/replace rogue SPECIAL $library/replace rogue THROW $library/replace rogue USE $library/replace rogue ZAP $cc MAIN $link main,rogue/lib SHAR_EOF fi if test -f 'message.c' then echo shar: "will not over-write existing file 'message.c'" else cat << \SHAR_EOF > 'message.c' #include curses.h #include "object.h" #include "move.h" char message_cleared = 1; char message_line[SCOLS] = ""; short message_col; extern short cant_int, did_int; extern short interrupted; message(msg, intrpt) char *msg; short intrpt; { if (intrpt) { interrupted = 1; } cant_int = 1; /* slurp(); */ if (!message_cleared) { mvaddstr(MIN_ROW-1, message_col, MORE); refresh_vms(); wait_for_ack(0); check_message(); } strcpy(message_line, msg); mvaddstr(MIN_ROW-1, 0, msg); addch(' '); refresh_vms(); message_cleared = 0; message_col = strlen(msg); if (did_int) { /* onintr(); */ } cant_int = 0; } remessage() { if (message_line[0]) { message(message_line, 0); } } check_message() { register i; if (message_cleared) { return; } move(MIN_ROW-1, 0); clrtoeol(); move(rogue.row, rogue.col); refresh_vms(); message_cleared = 1; } get_input_line(buf, if_cancelled) char *buf; char *if_cancelled; { short ch; short i = 0; message("call it:", 0); while (((ch = getchar()) != '\n') && (ch != CANCEL)) { if ((ch >= ' ') && (ch <= '~') && (i < MAX_TITLE_LENGTH-2)) { buf[i++] = ch; addch(ch); } if ((ch == '\b') && (i > 0)) { mvaddch(0, --i + 9, ' '); move(MIN_ROW-1, i+9); } refresh_vms(); } check_message(); if (ch == CANCEL) { if (if_cancelled) { message(if_cancelled, 0); } return(0); } buf[i++] = ' '; buf[i] = 0; return(1); } /* slurp() { long ln; short i, n; do { ioctl(0, FIONREAD, &ln); n = stdin->_cnt + ln; for (i = 0; i < ln; i++) getchar(); } while (ln > 0L); } */ SHAR_EOF fi if test -f 'monster.c' then echo shar: "will not over-write existing file 'monster.c'" else cat << \SHAR_EOF > 'monster.c' #include curses.h #include ctype.h #include "monster.h" #include "object.h" #include "room.h" #include "move.h" #define TROLLMAX 64 extern short AMULET_LEVEL; extern short current_level; extern short current_room, party_room; extern short detect_monster; extern short blind, halluc; char *monster_names[] = { "ant lion", "aquatar", "bat", "blood hawk", "centaur", "cloud giant", "baby dragon", "dragon", "emu", "ettin", "venus fly-trap", "frost giant", "griffin", "ghost", "grimlock", "hill giant", "hobgoblin", "ice monster", "imp", "jabberwock", "jackal", "kestrel", "kobold", "leopard", "leprechaun", "meazel", "medusa", "nightmare", "nymph", "orc", "ogre", "phantom", "pheonix", "quaggoth", "quasit", "ram", "rattlesnake", "snake", "spider", "storm giant", "titan", "troll", "umber hulk", "black unicorn", "vampire", "vilstrak", "wolf", "wraith", "xeroc", "xvart", "yeth hound", "yeti", "zombie" }; object monster_tab[MONSTERS] = { /* antlion*/ {(WANDERS),"5d4",64,'a',60,11,22,75,0,45}, /* aquatar*/ {(IS_ASLEEP|WAKENS|WANDERS),"1d5",25,'A',20,AQUATAR1,AQUATAR2,100,0,0}, /* bat */ {(IS_ASLEEP|WANDERS|FLITS),"1d3",10,'B',2,1,8,60,0,0}, /* b. hawk*/ {(FLIES),"3d4/1d6",25,'b',15,6,17,85,0,25}, /* centaur*/ {(IS_ASLEEP|WANDERS),"3d4/2d6",30,'C',30,7,16,85,0,10}, /* c giant*/ {(IS_ASLEEP|WAKENS|WANDERS),"4d6/3d10",120,'c',900,15,126,85,0,80}, /* b.dragn*/ {(IS_ASLEEP|WAKENS|FLIES),"3d5/2d9",90,'d',2000,19,126,90,0,60}, /* dragon */ {(IS_ASLEEP|WAKENS),"4d5/3d9",128,'D',5000,21,126,100,0,90}, /* emu */ {(IS_ASLEEP|WAKENS),"1d3",11,'E',2,1,7,65,0,0}, /* ettin */ {(WANDERS),"2d8/3d6",80,'e',500,14,126,75,0,60}, /* fly trp*/ {(0),"1d3",32,'F',31,FLYTRAP1,FLYTRAP2,80,0,0}, /* f giant*/ {(IS_ASLEEP|WAKENS),"4d6/2d10",100,'f',700,14,126,85,0,60}, /* griffin*/ {(IS_ASLEEP|WAKENS|WANDERS|FLIES),"5d4/4d5",92,'G',2000,20,126,85,0,10}, /* ghost */ {(0),"1d10",70,'.',75,12,126,85,0,50}, /* grimlck*/ {(WANDERS|FLIES),"3d10/6d3",105,'g',2000,15,126,100,0,70}, /* h giant*/ {(IS_ASLEEP|WANDERS),"2d8/2d8",80,'h',500,12,126,75,0,60}, /* hgoblin*/ {(IS_ASLEEP|WAKENS|WANDERS),"1d3/1d3",17,'H',3,1,10,67,0,0}, /* icemstr*/ {(IS_ASLEEP),"0d0",15,'I',5,ICEMSTR1,ICEMSTR2,68,0,0}, /* imp */ {(WANDERS),"1d4",28,'i',3,1,7,50,0,0}, /* jabrwck*/ {(IS_ASLEEP|WANDERS),"3d10/3d4",125,'J',3000,21,126,100,0,0}, /* jackal */ {(WANDERS),"1d2",4,'j',2,1,4,50,0,0}, /* kestrel*/ {(IS_ASLEEP|WAKENS|WANDERS|FLIES),"1d4",10,'K',2,1,6,60,0,0}, /* kobold */ {(IS_ASLEEP|WAKENS|WANDERS),"2d4",8,'k',2,1,4,50,0,20}, /* leopard*/ {(WANDERS),"4d3/2d4",26,'l',20,8,17,75,0,20}, /* lepchan*/ {(IS_ASLEEP),"0d0",25,'L',18,LEPCHAN1,LEPCHAN2,75,0,0}, /* meazel */ {(IS_ASLEEP|WAKENS|WANDERS),"3d6",50,'m',50,7,20,75,0,10}, /* medusa */ {(IS_ASLEEP|WAKENS|WANDERS),"4d4/3d7",92,'M',250,18,126,85,0,25}, /* n. mare*/ {(WANDERS|FLIES),"2d4/3d4",54,'n',50,10,22,80,0,0}, /* nymph */ {(IS_ASLEEP),"0d0",25,'N',37,NYMPH1,NYMPH2,75,0,100}, /* orc */ {(IS_ASLEEP|WANDERS|WAKENS),"1d6",25,'O',10,4,13,70,0,10}, /* ogre */ {(IS_ASLEEP|WANDERS|WAKENS),"2d5",41,'o',25,7,16,85,0,35}, /* phantom*/ {(IS_ASLEEP|IS_INVIS|WANDERS|FLITS),"5d4",76,'P',120,15,23,80,0,50}, /* pheonix*/ {(FLIES),"2d12/3d8",160,'p',2500,26,126,100,0,95}, /* quagoth*/ {(WANDERS),"2d10/3d4",100,'q',1000,14,126,100,0,60}, /* quasit */ {(IS_ASLEEP|WAKENS|WANDERS),"3d5",30,'Q',20,8,17,78,0,20}, /* ram */ {(IS_ASLEEP|WAKENS),"2d6",25,'r',10,4,12,65,0,0}, /* r snake*/ {(IS_ASLEEP|WAKENS|WANDERS),"2d5",19,'R',10,RSNAKE1,RSNAKE2,70,0,0}, /* snake */ {(IS_ASLEEP|WAKENS|WANDERS),"1d3",8,'S',2,1,9,50,0,0}, /* spider */ {(IS_ASLEEP|WAKENS|FLITS),"1d2",9,'s',3,SPIDER1,SPIDER2,75,0,0}, /* s giant*/ {(WANDERS),"6d6/2d12",140,'s',1000,20,126,95,0,70}, /* titan */ {(IS_ASLEEP|WAKENS|WANDERS),"6d10",150,'t',2500,24,126,97,0,80}, /* troll */ {(IS_ASLEEP|WAKENS|WANDERS),"4d6",TROLLMAX,'T',300,13,126,75,0,33}, /* u hulk */ {(IS_ASLEEP|WAKENS),"3d4/2d5",64,'u',60,12,30,60,0,70}, /* unicorn*/ {(IS_ASLEEP|WAKENS|WANDERS),"4d9",88,'U',200,17,26,85,0,33}, /* vampire*/ {(IS_ASLEEP|WAKENS|WANDERS),"1d14",60,'V',350,VAMPIRE1,VAMPIRE2,85,0,18}, /* vilstrk*/ {(WANDERS),"2d5",15,'v',4,1,9,65,0,20}, /* wolf */ {(IS_ASLEEP|WAKENS|WANDERS|FLIES),"1d4/2d3",16,'w',5,1,11,80,0,0}, /* wraith */ {(IS_ASLEEP|WANDERS),"2d7",42,'W',75,WRAITH1,WRAITH2,75,0,0}, /* xeroc */ {(IS_ASLEEP),"4d6",42,'X',110,XEROC1,XEROC2,75,0,0}, /* xvart */ {(IS_ASLEEP|WANDERS|FLITS),"1d8",20,'x',3,1,11,69,0,10}, /* yeth h.*/ {(WANDERS|FLIES),"2d8",27,'y',40,9,18,80,0,10}, /* yeti */ {(IS_ASLEEP|WANDERS),"3d6",33,'Y',50,11,20,80,0,20}, /* zombie */ {(IS_ASLEEP|WAKENS|WANDERS),"1d7",20,'Z',8,5,14,69,0,0} }; object level_monsters; identify_monst(monst) char monst;{ int i; for(i=0;i!=MONSTERS;i++) if(monster_tab[i].ichar==monst && current_level >= monster_tab[i].is_protected && current_level <= monster_tab[i].is_cursed ){ message(monster_names[i],1); return; } } put_monsters() { short i; short n; object *monster, *get_rand_monster(); n = get_rand(3, 7); for (i = 0; i < n; i++) { monster = get_rand_monster(); if ((monster->m_flags & WANDERS) && rand_percent(50)) { wake_up(monster); } put_monster_rand_location(monster); add_to_pack(monster, &level_monsters, 0); } } object *get_rand_monster() { object *monster, *get_an_object(); short mn; monster = get_an_object(); for (;;) { mn = get_rand(0, MAXMONSTER-1); if ((current_level >= monster_tab[mn].is_protected) && (current_level <= monster_tab[mn].is_cursed)) { break; } } *monster = monster_tab[mn]; monster->what_is = MONSTER; if (monster->ichar == 'X') { monster->identified = get_rand_obj_char(); } if (monster->ichar == 'D'|| monster->ichar=='d') { monster->to_hit_enchantment= rand()%6; } if (current_level > (AMULET_LEVEL + 2)) { monster->m_flags |= HASTED; } monster->trow = -1; return(monster); } move_monsters() { object *monster; short flew; monster = level_monsters.next_object; while (monster) { if (monster->m_flags & HASTED) { mv_monster(monster, rogue.row, rogue.col); } else if (monster->m_flags & SLOWED) { monster->quiver = !monster->quiver; if (monster->quiver) { goto NM; } } flew = 0; if ((monster->m_flags & FLIES) && !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 = monster->next_object; } } fill_room_with_monsters(rn, n) { short i; short row, col; object *monster, *get_rand_monster(); n += n/2; for (i = 0; i < n; i++) { if (no_room_for_monster(rn)) break; 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] & MONSTER); monster = get_rand_monster(); put_monster_at(row, col, monster); } } get_monster_char_row_col(row, col) { object *monster, *object_at(); short retval; monster = object_at(&level_monsters, row, col); if ((!detect_monster && (monster->m_flags & IS_INVIS)) || blind) { retval = get_room_char((screen[row][col] & ~MONSTER),row,col); return(retval); } if ((monster->ichar == 'X') && monster->identified) { return(monster->identified); } return(monster->ichar); } get_monster_char(monster) object *monster; { short retval; if ((!detect_monster && (monster->m_flags & IS_INVIS)) || blind) { retval = get_room_char((screen[monster->row][monster->col] & ~MONSTER), monster->row, monster->col); return(retval); } if ((monster->ichar == 'X') && monster->identified) { return(monster->identified); } return(monster->ichar); } mv_monster(monster, row, col) register object *monster; short row, col; { short i, n; char tried[6]; if (monster->m_flags & IS_ASLEEP) { if ((monster->m_flags & WAKENS) && rogue_is_around(monster->row, monster->col) && rand_percent(WAKE_PERCENT)) { wake_up(monster); } return; } if ((monster->m_flags & FLITS) && flit(monster)) { return; } if (((current_level >= FLYTRAP1) && (current_level <= FLYTRAP2) && (monster->ichar == 'F')) && !monster_can_go(monster, rogue.row, rogue.col)) { return; } if (((current_level >= ICEMSTR1) && (current_level <= ICEMSTR2) && (monster->ichar == 'I')) && monster->identified) { return; } if ((monster->ichar == 'M') && paralyze(monster)) { return; } if (monster->ichar =='T') { monster->quantity+= 10; if (monster->quantity > TROLLMAX) monster->quantity = TROLLMAX; } if ((monster->ichar == 'u') && m_confuse(monster)) { return; } if (monster_can_go(monster, rogue.row, rogue.col)) { monster_hit(monster, 0); return; } if (((monster->ichar == 'd') || (monster->ichar == 'D')) && breath(monster,monster->to_hit_enchantment)) { return; } if ((monster->ichar == 'O') && orc_gold(monster)) { return; } if ((monster->trow == monster->row) && (monster->tcol == monster->col)) { monster->trow = -1; } else if (monster->trow != -1) { row = monster->trow; col = monster->tcol; } if (monster->row > row) { row = monster->row - 1; } else if (monster->row < row) { row = monster->row + 1; } if ((screen[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 ((screen[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)) { return; } break; case 1: if (!tried[n] && mtry(monster, row, monster->col)) { return; } break; case 2: if (!tried[n] && mtry(monster, row, monster->col+1)) { return; } break; case 3: if (!tried[n] && mtry(monster, monster->row-1, col)) { return; } break; case 4: if (!tried[n] && mtry(monster, monster->row, col)) { return; } break; case 5: if (!tried[n] && mtry(monster, monster->row+1, col)) { return; } break; } if (!tried[n]) { tried[n] = 1; } else { goto NEXT_TRY; } } } 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; add_mask(row, col, MONSTER); remove_mask(monster->row, monster->col, MONSTER); c = mvinch(monster->row, monster->col); if (isupper(c)||islower(c)) { mvaddch(monster->row, monster->col, get_room_char(screen[monster->row][monster->col], monster->row, monster->col)); } if (!blind && (detect_monster || can_see(row, col))) { if ((!(monster->m_flags & IS_INVIS) || detect_monster)) { mvaddch(row, col, get_monster_char(monster)); } } if ((screen[row][col] & DOOR) && (get_room_number(row, col) != current_room) && (screen[monster->row][monster->col] == FLOOR)) { if (!blind) mvaddch(monster->row, monster->col, ' '); } if (screen[row][col] & DOOR) { door_course(monster, (screen[monster->row][monster->col] & 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 ((!screen[monster->row][col]) || (!screen[row][monster->col])) { return(0); } if ((!is_passable(row, col)) || (screen[row][col] & MONSTER)) { return(0); } if ((monster->row!=row)&&(monster->col!=col)&&((screen[row][col]&DOOR) || (screen[monster->row][monster->col]&DOOR))) { return(0); } if (!(monster->m_flags & FLITS) && !(monster->m_flags & CAN_GO) && (monster->trow == -1)) { 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 (screen[row][col] & SCROLL) { obj = object_at(&level_objects, row, col); if (obj->which_kind == SCARE_MONSTER) { return(0); } } return(1); } wake_up(monster) object *monster; { monster->m_flags &= (~IS_ASLEEP); } wake_room(rn, entering, row, col) { object *monster; short wake_percent; wake_percent = (rn == party_room) ? PARTY_WAKE_PERCENT : WAKE_PERCENT; monster = level_monsters.next_object; while (monster) { if (((monster->m_flags & WAKENS) || (rn == party_room)) && (rn == get_room_number(monster->row, monster->col))) { if ((monster->ichar != 'X') && (rn == party_room)) { monster->m_flags |= WAKENS; } if (entering) { monster->trow = -1; } else { monster->trow = row; monster->tcol = col; } if (rand_percent(wake_percent) && (monster->m_flags & WAKENS)) { if (monster->ichar != 'X') { wake_up(monster); } } } monster = monster->next_object; } } char *monster_name(monster) object *monster; { int i; if (blind || ((monster->m_flags & IS_INVIS) && !detect_monster)) { return("something"); } if (halluc) { i=rand()%MONSTERS; return(monster_names[i]); } for(i=0;i!=MONSTERS;i++) if(monster_tab[i].ichar==monster->ichar && current_level >= monster_tab[i].is_protected && current_level <= monster_tab[i].is_cursed ) return(monster_names[i]); /* for(i=0;i!=MONSTERS;i++) if(monster_tab[i].ichar==monster->ichar) return(monster_names[i]); */ } rogue_is_around(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(); if ((!(monster->m_flags & WAKENS)) && (!(monster->m_flags & WANDERS))) { free(monster); goto ANOTHER; } wake_up(monster); for (i = 0; i < 12; i++) { get_rand_row_col(&row, &col, (FLOOR | TUNNEL | IS_OBJECT)); if (!can_see(row, col)) { put_monster_at(row, col, monster); return; } } } show_monsters() { object *monster; if (blind) return; monster = level_monsters.next_object; while (monster) { mvaddch(monster->row, monster->col, monster->ichar); if (monster->ichar == 'X') { monster->identified = 0; } monster = monster->next_object; } } create_monster() { short row, col; short i, j, inc1, inc2; short found = 0; object *monster; inc1 = get_rand(0, 1) ? 1 : -1; inc2 = get_rand(0, 1) ? 1 : -1; for (i = inc1; i != (2 * -inc1); i -= inc1) { for (j = inc2; j != (2 * -inc2); j -= inc2) { if (!i && !j) continue; 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)) && (screen[row][col] & (FLOOR|TUNNEL|STAIRS))) { found = 1; goto FOUND; } } } FOUND: if (found) { monster = get_rand_monster(); put_monster_at(row, col, monster); mvaddch(row, col, get_monster_char(monster)); if (monster->m_flags & WANDERS) { wake_up(monster); } } else { message("you hear a faint cry of anguish in the distance",0); } } put_monster_at(row, col, monster) object *monster; { monster->row = row; monster->col = col; add_mask(row, col, MONSTER); add_to_pack(monster, &level_monsters, 0); } can_see(row, col) { short retval; retval = !blind && ((get_room_number(row, col) == current_room) || (rogue_is_around(row, col))); return(retval); } flit(monster) object *monster; { short inc1, inc2; short i, j, row, col; if (!rand_percent(FLIT_PERCENT)) { return(0); } inc1 = get_rand(0, 1) ? 1 : -1; inc2 = get_rand(0, 1) ? 1 : -1; if (rand_percent(10)) { return(1); } for (i = inc1; i != (2*(0-inc1)); i+=(0-inc1)) { for (j = inc2; j != (2*(0-inc2)); j+=(0-inc2)) { row = monster->row + i; col = monster->col + j; 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 | IS_OBJECT)); add_mask(row, col, MONSTER); monster->row = row; monster->col = col; } get_rand_obj_char() { short r; char *rs = "%!?]/):*"; r = get_rand(0, 7); return(rs[r]); } no_room_for_monster(rn) { short i, j; for (i = rooms[rn].left_col+1; i < rooms[rn].right_col; i++) { for (j = rooms[rn].top_row+1; j < rooms[rn].bottom_row; j++) { if (!(screen[i][j] & MONSTER)) { return(0); } } } return(1); } aggravate() { struct object *monster; message("you hear a high pitched humming noise"); monster = level_monsters.next_object; while (monster) { wake_up(monster); if (monster->ichar == 'X') { monster->identified = 0; } monster = monster->next_object; } } 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))) { 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_object; while (monster) { if (monster->ichar == 'A') { mv_monster(monster, rogue.row, rogue.col); } monster = monster->next_object; } } SHAR_EOF fi if test -f 'monster.h' then echo shar: "will not over-write existing file 'monster.h'" else cat << \SHAR_EOF > 'monster.h' #define MONSTERS 53 #define HASTED ((unsigned short)001) #define SLOWED ((unsigned short)002) #define IS_INVIS ((unsigned short)004) #define IS_ASLEEP ((unsigned short)010) #define WAKENS ((unsigned short)020) #define WANDERS ((unsigned short)040) #define FLIES ((unsigned short)0100) #define FLITS ((unsigned short)0200) #define CAN_GO ((unsigned short)0400) #define MAXMONSTER 53 #define WAKE_PERCENT 45 #define FLIT_PERCENT 33 #define PARTY_WAKE_PERCENT 75 #define AQUATAR1 7 /* levels in which the aquatar appears */ #define AQUATAR2 18 #define FLYTRAP1 14 /* levels in which the venus fly trap appears */ #define FLYTRAP2 126 #define ICEMSTR1 2 /* levels in which the ice monster appears */ #define ICEMSTR2 11 #define LEPCHAN1 6 /* levels in which the leprechan appears */ #define LEPCHAN2 16 #define NYMPH1 8 /* levels in which the nymph appears */ #define NYMPH2 19 #define RSNAKE1 3 /* levels in which the rattlesnake appears */ #define RSNAKE2 12 #define SPIDER1 1 /* levels in which the spider appears */ #define SPIDER2 11 #define VAMPIRE1 19 /* levels in which the vampire appears */ #define VAMPIRE2 126 #define WRAITH1 14 /* levels in which the wraith appears */ #define WRAITH2 28 #define XEROC1 16 /* levels in which the xeroc appears */ #define XEROC2 25 #define HYPOTHERMIA 1 #define STARVATION 2 #define QUIT 3 #define WIN 4 #define MAX_ODORS 6 #define B_FLAME 0 #define B_LIGHTNING 1 #define B_COLD 2 #define B_ACID 3 #define B_SLEEP 4 #define B_CONFUSION 5 SHAR_EOF fi if test -f 'move.c' then echo shar: "will not over-write existing file 'move.c'" else cat << \SHAR_EOF > 'move.c' #include curses.h #include "object.h" #include "room.h" #include "move.h" #include "monster.h" extern short current_room, halluc, detect_monster, blind, being_held; extern short confused, interrupted, has_amulet; extern char *hunger_str; single_move_rogue(dirch, pickup) { short row, col; object *obj, *object_at(), *pick_up(); char description[SCOLS]; short n, status; row = rogue.row; col = rogue.col; if (being_held) { get_dir_rc(dirch, &row, &col); if (!(screen[row][col] & MONSTER)) { message("you are being held", 1); return(MOVE_FAILED); } } row = rogue.row; col = rogue.col; if (confused) { dirch = get_rand_dir(); } switch(dirch) { case 'h': col--; break; case 'j': row++; break; case 'k': row--; break; case 'l': col++; break; case 'b': col--; row++; break; case 'y': col--; row--; break; case 'u': col++; row--; break; case 'n': col++; row++; break; } if (screen[row][col] & MONSTER) { rogue_hit(object_at(&level_monsters, row, col)); register_move(); return(MOVE_FAILED); } if (!can_move(rogue.row, rogue.col, row, col)) { return(MOVE_FAILED); } if (screen[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 ((screen[rogue.row][rogue.col] & DOOR) && (screen[row][col] & TUNNEL)) { light_passage(row, col); wake_room(current_room, 0, row, col); darken_room(current_room); current_room = PASSAGE; } else if (screen[row][col] & TUNNEL) { light_passage(row, col); } mvaddch(rogue.row, rogue.col, get_room_char(screen[rogue.row][rogue.col], rogue.row, rogue.col)); mvaddch(row, col, rogue.fchar); rogue.row = row; rogue.col = col; if (screen[row][col] & CAN_PICK_UP) { if (pickup) { if (obj = pick_up(row, col, &status)) { get_description(obj, description); if (obj->what_is == GOLD) { free(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 ((screen[row][col] & DOOR) || (screen[row][col] & STAIRS)) { 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 '': case '\012': case '': case '': 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) { if ((row < MIN_ROW) || (row > (LINES - 2)) || (col < 0) || (col > (COLS-1))) { return(0); } return(screen[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS)); } next_to_something(drow, dcol) { short i, j, i_end, j_end, row, col; short pass_count = 0; if (confused) { return(1); } if (blind) { return(0); } i_end = (rogue.row < (LINES-2)) ? 1 : 0; j_end = (rogue.col < (COLS-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; } if(screen[rogue.row+i][rogue.col+j]&(MONSTER|IS_OBJECT))return(1); if ((((i - j) == 1) || ((i - j) == -1)) && (screen[rogue.row+i][rogue.col+j] & TUNNEL)) { if (++pass_count > 1) { return(1); } } row = rogue.row+i; col = rogue.col+j; if ((screen[row][col] & DOOR)||(is_object(row,col))) { if (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 ((screen[row1][col1]&DOOR)||(screen[row2][col2]&DOOR)) { return(0); } if ((!screen[row1][col2]) || (!screen[row2][col1])) { return(0); } } return(1); } is_object(row, col) { return(screen[row][col] & IS_OBJECT); } move_onto() { short ch; short first_miss = 1; char getchartt(); while (!is_direction(ch = getchartt())) { putchar(7); fflush(stdout); 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) ); } is_pack_letter(c) { return(((c >= 'a') && (c <= 'z')) || (c == CANCEL) || (c == LIST)); } check_hunger() { short i, n; short fainted = 0; if (rogue.moves_left == HUNGRY) { hunger_str = "hungry"; message(hunger_str, 0); print_stats(); } if (rogue.moves_left == WEAK) { hunger_str = "weak"; message(hunger_str, 0); print_stats(); } if ((rogue.moves_left) <= FAINT) { if (rogue.moves_left == FAINT) { hunger_str = "faint"; message(hunger_str, 1); print_stats(); } 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 (rand_percent(50)) { move_monsters(); } } message("you can move again", 1); } } if (rogue.moves_left <= STARVE) { killed_by(0, STARVATION); } rogue.moves_left--; return(fainted); } register_move() { static short moves = 0; short fainted; if ((rogue.moves_left <= HUNGRY) || !has_amulet) { fainted = check_hunger(); } else { fainted = 0; } move_monsters(); if (++moves >= 80) { moves = 0; start_wanderer(); } if (halluc) { if (!(--halluc)) { unhallucinate(); } else { hallucinate(); } } if (blind) { if (!(--blind)) { unblind(); } } if (confused) { if (!(--confused)) { unconfuse(); } } heal(); return(fainted); } rest(count) { int i; 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 exp = -1, n, c = 0; if (rogue.exp != exp) { exp = rogue.exp; switch(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 (rogue.hp_current == rogue.hp_max) { c = 0; return; } if (++c >= n) { c = 0; rogue.hp_current++; if (rogue.hp_current < rogue.hp_max) { if (rand_percent(50)) { rogue.hp_current++; } } print_stats(); } } SHAR_EOF fi if test -f 'move.h' then echo shar: "will not over-write existing file 'move.h'" else cat << \SHAR_EOF > 'move.h' #define UP 0 #define UPRIGHT 1 #define RIGHT 2 #define RIGHTDOWN 3 #define DOWN 4 #define DOWNLEFT 5 #define LEFT 6 #define LEFTUP 7 #define ROW1 7 #define ROW2 15 #define COL1 26 #define COL2 52 #define MOVED 0 #define MOVE_FAILED -1 #define STOPPED_ON_SOMETHING -2 #define CANCEL '\033' #define LIST '*' #define HUNGRY 300 #define WEAK 120 #define FAINT 20 #define STARVE 0 #define MIN_ROW 1 SHAR_EOF fi exit 0 # End of shell archive -- ihnp4--\ decvax--\ akgua----\ dcdwest---\ somewhere--\ ucbvax-------- sdcsvax -- rich