/* * domaze: * Draw the maze on this level. */ do_maze() { reg int least; reg struct room *rp; reg struct linked_list *item; reg struct object *obj; int cnt; bool treas; coord tp; for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) { rp->r_flags = ISGONE; /* kill all rooms */ rp->r_fires = NULL; /* no fires */ } rp = &rooms[0]; /* point to only room */ rp->r_flags = ISDARK; /* mazes always dark */ rp->r_pos.x = 0; /* room fills whole screen */ rp->r_pos.y = 1; rp->r_max.x = cols - 1; rp->r_max.y = lines - 3; draw_maze(); /* put maze into window */ /* * add some gold to make it worth looking for */ item = spec_item(GOLD, NULL, NULL, NULL); obj = OBJPTR(item); obj->o_count *= (rnd(5) + 5); /* add in one large hunk */ attach(lvl_obj, item); cnt = 0; do { rnd_pos(rp, &tp); } until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 5000); mvaddch(tp.y, tp.x, GOLD); obj->o_pos = tp; /* * add in some food to make sure he has enough */ item = spec_item(FOOD, NULL, NULL, NULL); obj = OBJPTR(item); attach(lvl_obj, item); do { rnd_pos(rp, &tp); } until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 5000); mvaddch(tp.y, tp.x, FOOD); obj->o_pos = tp; if (rnd(100) < 40) { /* treasure type maze */ treas = TRUE; least = 10; debug("treasure maze"); } else { /* normal maze level */ least = 5; treas = FALSE; } genmonsters(least, treas); }
/* * make_level: * Make the current level */ void make_level() { register int i; register COORD *cp; register int x; reset_count(); for (i = 1; i < Y_FIELDSIZE; i++) for (x = 1; x < X_FIELDSIZE; x++) if (Field[i][x] != 0) mvaddch(i, x, ' '); if (My_pos.y > 0) mvaddch(My_pos.y, My_pos.x, ' '); Waiting = FALSE; Wait_bonus = 0; leaveok(stdscr, FALSE); for (cp = Robots; cp < &Robots[MAXROBOTS]; cp++) cp->y = -1; My_pos.y = -1; bzero(Field, sizeof Field); Min.y = Y_FIELDSIZE; Min.x = X_FIELDSIZE; Max.y = 0; Max.x = 0; if ((i = Level * 10) > MAXROBOTS) i = MAXROBOTS; Num_robots = i; while (i-- > 0) { cp = rnd_pos(); Robots[i] = *cp; Field[cp->y][cp->x]++; if (cp->y < Min.y) Min.y = cp->y; if (cp->x < Min.x) Min.x = cp->x; if (cp->y > Max.y) Max.y = cp->y; if (cp->x > Max.x) Max.x = cp->x; } My_pos = *rnd_pos(); refresh(); }
/* * do_post: * Put a trading post room and stuff on the screen */ void do_post() { struct coord tp; int i; struct room *rp; struct object *op; struct linked_list *ll; free_list(lvl_obj); /* throw old items away */ for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) { rp->r_goldval = 0; /* no gold */ rp->r_nexits = 0; /* no exits */ rp->r_flags = ISGONE; /* kill all rooms */ } rp = &rooms[0]; /* point to only room */ rp->r_flags = 0; /* this room NOT gone */ rp->r_max.x = 40; rp->r_max.y = 10; /* 10 * 40 room */ rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */ rp->r_pos.y = 1; /* 2nd line */ draw_room(rp); /* draw the only room */ i = roll(4, 10); /* 10 to 40 items */ for (; i > 0; i--) { /* place all the items */ ll = new_thing(FALSE, ANYTHING); /* get something */ attach(lvl_obj, ll); op = OBJPTR(ll); setoflg(op, ISPOST); /* object in trading post */ tp = *rnd_pos(rp); op->o_pos = tp; mvaddch(tp.y, tp.x, op->o_type); } trader = 0; wmove(cw, 12, 0); waddstr(cw, "Welcome to Friendly Fiend's Flea Market\n\r"); waddstr(cw, "=======================================\n\r"); waddstr(cw, "$: Prices object that you stand upon.\n\r"); waddstr(cw, "#: Buys the object that you stand upon.\n\r"); waddstr(cw, "%: Trades in something in your pack for gold.\n\r"); trans_line(); }
void draw_maze(struct Room *room) { int y, x; int fy[MAXFRNT], fx[MAXFRNT]; int psgcnt; Coord spos; fr_y = fy; fr_x = fx; maxx = maxy = 0; topy = room->m_ul_corner.y; if (topy == 0) topy = ++room->m_ul_corner.y; topx = room->m_ul_corner.x; //Choose a random spot in the maze and initialize the frontier to be the immediate neighbors of this random spot. y = topy; x = topx; splat({ x,y }); new_frontier({ x,y }); //While there are new frontiers, connect them to the path and possibly expand the frontier even more. while (frcnt) { con_frnt(); new_frontier({ nx,ny }); } //According to the Grand Beeking, every maze should have a loop. Don't worry if you don't understand this. room->m_size.x = maxx - room->m_ul_corner.x + 1; room->m_size.y = maxy - room->m_ul_corner.y + 1; do { static Coord ld[4] = { -1, 0, 0, 1, 1, 0, 0, -1 }; Coord *cp; int sh; rnd_pos(room, &spos); for (psgcnt = 0, cp = ld, sh = 1; cp < &ld[4]; sh <<= 1, cp++) { y = cp->y + spos.y; x = cp->x + spos.x; if (!offmap({ x,y }) && game->level().get_tile({ x, y }) == PASSAGE) psgcnt += sh; } } while (game->level().get_tile(spos) == PASSAGE || psgcnt % 5); splat(spos); }
void wanderer(void) { int i, cnt = 0; struct room *hr = roomin(hero); struct linked_list *item; struct thing *tp; coord cp; char *loc; int which; /* Find a place for it -- avoid the player's room */ do { do { cnt++; i = rnd_room(); } while (!(hr != &rooms[i] || levtype == MAZELEV || levtype == THRONE || cnt > 5000)); rnd_pos(&rooms[i], &cp); } while(!step_ok(cp.y, cp.x, NOMONST, NULL)); /* Create a new wandering monster */ item = new_item(sizeof *tp); which = randmonster(TRUE, FALSE); new_monster(item, which, &cp, FALSE); tp = THINGPTR(item); tp->t_pos = cp; /* Assign the position to the monster */ chase_it(&tp->t_pos, &player); i = rnd(7); if (on(*tp, ISSWARM) && i < 5) cnt = roll(2, 4); else if (on(*tp, ISFLOCK) && i < 5) cnt = roll(1, 4); else cnt = 0; for (i = 1; i <= cnt; i++) { struct linked_list *ip = creat_mons(tp, which, NOMESSAGE); if (ip != NULL) { struct thing *mp = THINGPTR(ip); if (on(*tp, ISFRIENDLY)) turn_on(*mp, ISFRIENDLY); else turn_off(*mp, ISFRIENDLY); } } if (cnt > 0) { if (on(*tp, LOWCAST) || on(*tp, MEDCAST) || on(*tp, HIGHCAST)) turn_on(*tp, CANCAST); tp->t_stats.s_hpt += roll(2, 8); tp->t_stats.s_lvl += roll(2, 3); tp->t_stats.s_arm -= roll(1, 6); tp->t_stats.s_str += roll(2, 3); tp->t_stats.s_intel += roll(2, 3); tp->t_stats.s_exp += roll(2, 8) * monsters[which].m_add_exp; } i = DISTANCE(cp, hero); if (i < 20) loc = "very close to you"; else if (i < 400) loc = "nearby"; else loc = "in the distance"; if (wizard) msg("Started a wandering %s.", monsters[tp->t_index].m_name); else if (on(*tp, ISUNDEAD) && (player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN || is_wearing(R_PIETY))) msg("You sense a new ungodly monster %s.", loc); else if (on(player, CANHEAR) || (player.t_ctype == C_THIEF && rnd(20) == 0)) msg("You hear a new %s moving %s.", monsters[tp->t_index].m_name, loc); else if (on(player, CANSCENT) || (player.t_ctype == C_THIEF && rnd(20) == 0)) msg("You smell a new %s %s.", monsters[tp->t_index].m_name, loc); }
/* * get_move: * Get and execute a move from the player */ void get_move(void) { int c; #ifdef FANCY int lastmove; #endif if (Waiting) return; #ifdef FANCY if (Pattern_roll) { if (Next_move >= Move_list) lastmove = *Next_move; else lastmove = -1; /* flag for "first time in" */ } else lastmove = 0; /* Shut up gcc */ #endif for (;;) { if (Teleport && must_telep()) goto teleport; if (Running) c = Run_ch; else if (Count != 0) c = Cnt_move; #ifdef FANCY else if (Num_robots > 1 && Stand_still) c = '>'; else if (Num_robots > 1 && Pattern_roll) { if (*++Next_move == '\0') { if (lastmove < 0) goto over; Next_move = Move_list; } c = *Next_move; mvaddch(0, 0, c); if (c == lastmove) goto over; } #endif else { over: c = getchar(); if (isdigit(c)) { Count = (c - '0'); while (isdigit(c = getchar())) Count = Count * 10 + (c - '0'); if (c == ESC) goto over; Cnt_move = c; if (Count) leaveok(stdscr, true); } } switch (c) { case ' ': case '.': if (do_move(0, 0)) goto ret; break; case 'y': if (do_move(-1, -1)) goto ret; break; case 'k': if (do_move(-1, 0)) goto ret; break; case 'u': if (do_move(-1, 1)) goto ret; break; case 'h': if (do_move(0, -1)) goto ret; break; case 'l': if (do_move(0, 1)) goto ret; break; case 'b': if (do_move(1, -1)) goto ret; break; case 'j': if (do_move(1, 0)) goto ret; break; case 'n': if (do_move(1, 1)) goto ret; break; case 'Y': case 'U': case 'H': case 'J': case 'K': case 'L': case 'B': case 'N': case '>': Running = true; if (c == '>') Run_ch = ' '; else Run_ch = tolower(c); leaveok(stdscr, true); break; case 'q': case 'Q': if (query("Really quit?")) quit(); refresh(); break; case 'w': case 'W': Waiting = true; leaveok(stdscr, true); goto ret; case 't': case 'T': teleport: Running = false; mvaddch(My_pos.y, My_pos.x, ' '); My_pos = *rnd_pos(); mvaddch(My_pos.y, My_pos.x, PLAYER); leaveok(stdscr, false); refresh(); flush_in(); goto ret; case CTRL('L'): wrefresh(curscr); break; case EOF: break; default: putchar(CTRL('G')); reset_count(); fflush(stdout); break; } } ret: if (Count > 0) if (--Count == 0) leaveok(stdscr, false); }
void death(int monst) { char **dp = (char **) rip, *killer; struct tm *lt; time_t date; char buf[80]; int c; if (is_wearing(R_RESURRECT) || rnd(wizard ? 3 : 67) == 0) { int die = TRUE; if (resurrect-- == 0) msg("You've run out of lives."); else if (!save_resurrect(ring_value(R_RESURRECT))) msg("Your attempt to return from the grave fails."); else { struct linked_list *item; struct linked_list *next_item; struct object *obj; int rm, flags; coord pos; die = FALSE; msg("You feel a sudden warmth and then nothingness."); teleport(); if (ring_value(R_RESURRECT) > 1 && rnd(10)) { pstats.s_hpt = 2 * pstats.s_const; pstats.s_const = max(pstats.s_const - 1, 3); } else { for (item = pack; item != NULL; item = next_item) { obj = OBJPTR(item); if (obj->o_flags & ISOWNED || obj->o_flags & ISPROT) { next_item = next(item); continue; } flags = obj->o_flags; obj->o_flags &= ~ISCURSED; dropcheck(obj); obj->o_flags = flags; next_item = next(item); rem_pack(obj); if (obj->o_type == ARTIFACT) has_artifact &= ~(1 << obj->o_which); do { rm = rnd_room(); rnd_pos(&rooms[rm], &pos); } while(winat(pos.y, pos.x) != FLOOR); obj->o_pos = pos; add_obj(item, obj->o_pos.y, obj->o_pos.x); } pstats.s_hpt = pstats.s_const; pstats.s_const = max(pstats.s_const - roll(2, 2), 3); } chg_str(roll(1, 4), TRUE, FALSE); pstats.s_lvl = max(pstats.s_lvl, 1); no_command += 2 + rnd(4); if (on(player, ISHUH)) lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION); else light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER); turn_on(player, ISHUH); light(&hero); } if (die) { wmove(cw, mpos, 0); waddstr(cw, morestr); wrefresh(cw); wait_for(' '); } else return; } time(&date); lt = localtime(&date); clear(); wclear(cw); move(8, 0); while (*dp) printw("%s\n", *dp++); mvaddstr(14, 28 - ((int)(strlen(whoami) + 1) / 2), whoami); sprintf(buf, "%d+%ld Points", pstats.s_lvl, pstats.s_exp); mvaddstr(15, 28 - ((int)(strlen(buf) + 1) / 2), buf); killer = killname(monst,buf); mvaddstr(17, 28 - ((int)(strlen(killer) + 1) / 2), killer); mvaddstr(18, 28, (sprintf(prbuf, "%2d", lt->tm_year), prbuf)); move(LINES - 1, 0); mvaddstr(LINES - 1, 0, retstr); while ((c = readcharw(stdscr)) != '\n' && c != '\r') continue; idenpack(); wrefresh(cw); refresh(); score(pstats.s_exp, pstats.s_lvl, KILLED, monst); byebye(); }
new_level() { register int rm, i; register THING *tp; register char *sp; register THING **mp; register int index; coord stairs; player.t_flags &= ~ISHELD; /* unhold when you go down just in case */ if (level > max_level) max_level = level; /* * Clean things off from last level */ clear(); for (sp = _level; sp < &_level[MAXCOLS*MAXLINES]; ) *sp++ = ' '; for (sp = _flags; sp < &_flags[MAXCOLS*MAXLINES]; ) *sp++ = F_REAL; for (mp = _monst; mp < &_monst[MAXCOLS*MAXLINES]; ) *mp++ = NULL; clear(); /* * Free up the monsters on the last level */ for (tp = mlist; tp != NULL; tp = next(tp)) free_list(tp->t_pack); free_list(mlist); /* * Throw away stuff left on the previous level (if anything) */ free_list(lvl_obj); do_rooms(); /* Draw rooms */ do_passages(); /* Draw passages */ no_food++; put_things(); /* Place objects (if any) */ /* * Place the staircase down. */ i = 0; do { rm = rnd_room(); rnd_pos(&rooms[rm], &stairs); index = INDEX(stairs.y, stairs.x); if (i++ > 100) { i = 0; srand(getpid() + (int) time((time_t *) NULL)); } } until (_level[index] == FLOOR); _level[index] = STAIRS; /* * Place the traps */ if (rnd(10) < level) { ntraps = rnd(level / 4) + 1; if (ntraps > MAXTRAPS) ntraps = MAXTRAPS; i = ntraps; while (i--) { do { rm = rnd_room(); rnd_pos(&rooms[rm], &stairs); index = INDEX(stairs.y, stairs.x); } until (_level[index] == FLOOR && (_flags[index] & F_REAL)); sp = &_flags[index]; *sp &= ~(F_REAL | F_TMASK); *sp |= rnd(NTRAPS); } }
do_rooms() { register int i; register struct room *rp; register struct linked_list *item; register struct thing *tp; register int left_out; coord top; coord bsze; coord mp; /* * bsze is the maximum room size */ bsze.x = cols()/3; bsze.y = lines()/3; /* * Clear things for a new level */ for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) rp->r_goldval = rp->r_nexits = rp->r_flags = 0; /* * Put the gone rooms, if any, on the level */ left_out = rnd(4); for (i = 0; i < left_out; i++) rooms[rnd_room()].r_flags |= ISGONE; /* * dig and populate all the rooms on the level */ for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) { /* * Find upper left corner of box that this room goes in */ top.x = (i%3)*bsze.x + 1; top.y = i/3*bsze.y; if (rp->r_flags & ISGONE) { /* * Place a gone room. Make certain that there is a blank line * for passage drawing. */ do { rp->r_pos.x = top.x + rnd(bsze.x-2) + 1; rp->r_pos.y = top.y + rnd(bsze.y-2) + 1; rp->r_max.x = -cols(); rp->r_max.x = -lines(); } until(rp->r_pos.y > 0 && rp->r_pos.y < lines()-1); continue; } if (rnd(10) < level-1) rp->r_flags |= ISDARK; /* * Find a place and size for a random room */ do { rp->r_max.x = rnd(bsze.x - 4) + 4; rp->r_max.y = rnd(bsze.y - 4) + 4; rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x); rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y); } until (rp->r_pos.y != 0); /* * Put the gold in */ if (rnd(100) < 50 && (!amulet || level >= max_level)) { rp->r_goldval = GOLDCALC; rnd_pos(rp, &rp->r_gold); if (roomin(&rp->r_gold) != rp) endwin(), abort(); } draw_room(rp); /* * Put the monster in */ if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25)) { item = new_item(sizeof *tp); tp = (struct thing *) ldata(item); do { rnd_pos(rp, &mp); } until(mvwinch(stdscr, mp.y, mp.x) == FLOOR); new_monster(item, randmonster(FALSE), &mp); /* * See if we want to give it a treasure to carry around. */ if (rnd(100) < monsters[tp->t_type-'A'].m_carry) attach(tp->t_pack, new_thing()); } }
/* * do_rooms: * Create rooms and corridors with a connectivity graph */ do_rooms() { register int i; register struct room *rp; register THING *tp; register int left_out; coord top; coord bsze; coord mp; /* * bsze is the maximum room size */ bsze.x = COLS/3; bsze.y = LINES/3; /* * Clear things for a new level */ for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) rp->r_goldval = rp->r_nexits = rp->r_flags = 0; /* * Put the gone rooms, if any, on the level */ left_out = rnd(4); for (i = 0; i < left_out; i++) rooms[rnd_room()].r_flags |= ISGONE; /* * dig and populate all the rooms on the level */ for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) { /* * Find upper left corner of box that this room goes in */ top.x = (i%3)*bsze.x + 1; top.y = i/3*bsze.y; if (rp->r_flags & ISGONE) { /* * Place a gone room. Make certain that there is a blank line * for passage drawing. */ do { rp->r_pos.x = top.x + rnd(bsze.x-2) + 1; rp->r_pos.y = top.y + rnd(bsze.y-2) + 1; rp->r_max.x = -COLS; rp->r_max.x = -LINES; } until (rp->r_pos.y > 0 && rp->r_pos.y < LINES-1); continue; } if (rnd(10) < level - 1) rp->r_flags |= ISDARK; /* * Find a place and size for a random room */ do { rp->r_max.x = rnd(bsze.x - 4) + 4; rp->r_max.y = rnd(bsze.y - 4) + 4; rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x); rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y); } until (rp->r_pos.y != 0); /* * Put the gold in */ if (rnd(2) == 0 && (!amulet || level >= max_level)) { register THING *gold; gold = new_item(); gold->o_goldval = rp->r_goldval = GOLDCALC; rnd_pos(rp, &rp->r_gold); gold->o_pos = rp->r_gold; gold->o_flags = ISMANY; gold->o_group = GOLDGRP; gold->o_type = GOLD; attach(lvl_obj, gold); } draw_room(rp); /* * Put the monster in */ if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25)) { tp = new_item(); do { rnd_pos(rp, &mp); } until (winat(mp.y, mp.x) == FLOOR); new_monster(tp, randmonster(FALSE), &mp); give_pack(tp); } }
void teleport(void) { struct room *new_rp = NULL, *old_rp = roomin(hero); int rm, which; coord c; int is_lit = FALSE; /* For saving room light state */ int rand_position = TRUE; c = hero; mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x)); if (is_wearing(R_TELCONTROL)) { msg("Where do you wish to teleport to? (* for help)"); wmove(cw, hero.y, hero.x); wrefresh(cw); which = (short) (readchar() & 0177); while (which != (short) ESCAPE && which != (short) LINEFEED && which != (short) CARRIAGE_RETURN) { switch(which) { case 'h': c.x--; break; case 'j': c.y++; break; case 'k': c.y--; break; case 'l': c.x++; break; case 'y': c.x--; c.y--; break; case 'u': c.x++; c.y--; break; case 'b': c.x--; c.y++; break; case 'n': c.x++; c.y++; break; case '*': msg("Use h,j,k,l,y,u,b,n to position cursor, then hit" "return."); } c.y = max(c.y, 1); c.y = min(c.y, LINES - 3); c.x = max(c.x, 1); c.x = min(c.x, COLS - 1); wmove(cw, c.y, c.x); wrefresh(cw); which = (short) (readchar() & 0177); } which = winat(c.y, c.x); if ((which == FLOOR || which == PASSAGE || which == DOOR) && ((ring_value(R_TELCONTROL) == 0 && rnd(10) < 6) || (ring_value(R_TELCONTROL) > 0 && rnd(10) < 9))) { rand_position = FALSE; msg("You attempt succeeds."); hero = c; new_rp = roomin(hero); } else msg("Your attempt fails."); } if (rand_position) { do { rm = rnd_room(); rnd_pos(&rooms[rm], &hero); } while (winat(hero.y, hero.x) != FLOOR); new_rp = &rooms[rm]; } /* If hero gets moved, darken old room */ if (old_rp && old_rp != new_rp) { if (!(old_rp->r_flags & ISDARK)) is_lit = TRUE; old_rp->r_flags |= ISDARK; /* Fake darkness */ light(&c); if (is_lit) old_rp->r_flags &= ~ISDARK; /* Restore light state */ } light(&hero); mvwaddch(cw, hero.y, hero.x, PLAYER); /* turn off ISHELD in case teleportation was done while fighting */ if (on(player, ISHELD)) { struct linked_list *ip, *nip; struct thing *mp; turn_off(player, ISHELD); hold_count = 0; for (ip = mlist; ip; ip = nip) { mp = THINGPTR(ip); nip = next(ip); if (on(*mp, DIDHOLD)) { turn_off(*mp, DIDHOLD); turn_on(*mp, CANHOLD); } turn_off(*mp, DIDSUFFOCATE); } } extinguish_fuse(FUSE_SUFFOCATE); player.t_no_move = 0; /* not trapped anymore */ count = 0; running = FALSE; return; }
do_rooms() { int i; struct room *rp; struct linked_list *item; struct thing *tp; int left_out; coord top; coord bsze; coord mp; /* * bsze is the maximum room size */ bsze.x = COLS / 3; bsze.y = (LINES - 2) / 3; /* * Clear things for a new level */ for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) rp->r_nexits = rp->r_flags = rp->r_fires = 0; /* * Put the gone rooms, if any, on the level */ left_out = rnd(4); for (i = 0; i < left_out; i++) rooms[rnd_room()].r_flags |= ISGONE; /* * dig and populate all the rooms on the level */ for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) { bool has_gold = FALSE; /* * Find upper left corner of box that this room goes in */ top.x = (i % 3) * bsze.x; top.y = i / 3 * bsze.y + 1; if (rp->r_flags & ISGONE) { /* * Place a gone room. Make certain that there is a * blank line for passage drawing. */ do { rp->r_pos.x = top.x + rnd(bsze.x - 2) + 1; rp->r_pos.y = top.y + rnd(bsze.y - 2) + 1; rp->r_max.x = -COLS; rp->r_max.x = -LINES; } while (rp->r_pos.y < 1 || rp->r_pos.y > LINES - 3); continue; } if (rnd(80) < level - 15) rp->r_flags |= ISDARK; /* * Find a place and size for a random room */ do { rp->r_max.x = rnd(bsze.x - 4) + 4; rp->r_max.y = rnd(bsze.y - 4) + 4; rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x); rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y); } while (rp->r_pos.y == 0); /* Draw the room */ draw_room(rp); /* * Put the gold in */ if (rnd(100) < 50 && (!has_artifact || level >= max_level)) { struct linked_list *item; struct object *cur; coord tp; has_gold = TRUE; /* This room has gold in it */ item = spec_item(GOLD, NULL, NULL, NULL); cur = OBJPTR(item); /* Put it somewhere */ rnd_pos(rp, &tp); cur->o_pos = tp; /* Put the gold into the level list of items */ add_obj(item, tp.y, tp.x); if (roomin(&tp) != rp) { endwin(); abort(); } } /* * Put the monster in */ if (rnd(100) < (has_gold ? 80 : 40)) { short which; int i, count; item = new_item(sizeof *tp); tp = THINGPTR(item); do { rnd_pos(rp, &mp); } while (mvwinch(stdscr, mp.y, mp.x) != FLOOR); which = randmonster(NOWANDER, NOGRAB); new_monster(item, which, &mp, NOMAXSTATS); /* * See if we want to give it a treasure to carry * around. */ if (rnd(100) < monsters[tp->t_index].m_carry) attach(tp->t_pack, new_thing()); /* * If it has a fire, mark it */ if (on(*tp, HASFIRE)) { rp->r_flags |= HASFIRE; rp->r_fires++; } /* * If it carries gold, give it some */ if (on(*tp, CARRYGOLD)) { struct object *cur; item = spec_item(GOLD, NULL, NULL, NULL); cur = OBJPTR(item); cur->o_count = GOLDCALC + GOLDCALC + GOLDCALC; cur->o_pos = tp->t_pos; attach(tp->t_pack, item); } i = rnd(7); if (on(*tp, ISSWARM) && i < 5) count = roll(2, 4); else if (on(*tp, ISFLOCK) && i < 5) count = roll(1, 4); else count = 0; for (i = 1; i <= count; i++) { coord *mpos; if ((mpos = place_mons(mp.y, mp.x)) != NULL) { struct linked_list *nitem; nitem = new_item(sizeof(struct thing)); new_monster(nitem, which, mpos, NOMAXSTATS); /* * If the monster is on a trap, trap * it */ if (isatrap(mvinch(mpos->y, mpos->x))) be_trapped(THINGPTR(nitem), mp); if (on(*tp, ISFRIENDLY)) turn_on(*(THINGPTR(nitem)), ISFRIENDLY); else turn_off(*(THINGPTR(nitem)), ISFRIENDLY); } } if (count > 0) { int boost = rnd(3) + 1; if (on(*tp, LOWCAST) || on(*tp, MEDCAST) || on(*tp, HIGHCAST)) turn_on(*tp, CANCAST); tp->t_stats.s_hpt += 3 * boost; tp->t_stats.s_arm -= 2 * boost; tp->t_stats.s_lvl += 2 * boost; tp->t_stats.s_str += 2 * boost; tp->t_stats.s_intel += 2 * boost; tp->t_stats.s_exp += 4 * boost * monsters[which].m_add_exp; } } } }