Mercurial > hg > early-roguelike
comparison rogue5/new_level.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Mon, 24 May 2010 20:10:59 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 32:2dcd75e6a736 | 33:f502bf60e6e4 |
|---|---|
| 1 /* | |
| 2 * new_level: | |
| 3 * Dig and draw a new level | |
| 4 * | |
| 5 * @(#)new_level.c 4.38 (Berkeley) 02/05/99 | |
| 6 * | |
| 7 * Rogue: Exploring the Dungeons of Doom | |
| 8 * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman | |
| 9 * All rights reserved. | |
| 10 * | |
| 11 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 12 */ | |
| 13 | |
| 14 #include <curses.h> | |
| 15 #include <string.h> | |
| 16 #include "rogue.h" | |
| 17 | |
| 18 #define TREAS_ROOM 20 /* one chance in TREAS_ROOM for a treasure room */ | |
| 19 #define MAXTREAS 10 /* maximum number of treasures in a treasure room */ | |
| 20 #define MINTREAS 2 /* minimum number of treasures in a treasure room */ | |
| 21 | |
| 22 void | |
| 23 new_level(void) | |
| 24 { | |
| 25 THING *tp; | |
| 26 PLACE *pp; | |
| 27 int *sp; | |
| 28 int i; | |
| 29 | |
| 30 player.t_flags &= ~ISHELD; /* unhold when you go down just in case */ | |
| 31 if (level > max_level) | |
| 32 max_level = level; | |
| 33 /* | |
| 34 * Clean things off from last level | |
| 35 */ | |
| 36 for (pp = places; pp < &places[MAXCOLS*MAXLINES]; pp++) | |
| 37 { | |
| 38 pp->p_ch = ' '; | |
| 39 pp->p_flags = F_REAL; | |
| 40 pp->p_monst = NULL; | |
| 41 } | |
| 42 clear(); | |
| 43 /* | |
| 44 * Free up the monsters on the last level | |
| 45 */ | |
| 46 for (tp = mlist; tp != NULL; tp = next(tp)) | |
| 47 free_list(tp->t_pack); | |
| 48 free_list(mlist); | |
| 49 /* | |
| 50 * Throw away stuff left on the previous level (if anything) | |
| 51 */ | |
| 52 free_list(lvl_obj); | |
| 53 do_rooms(); /* Draw rooms */ | |
| 54 do_passages(); /* Draw passages */ | |
| 55 no_food++; | |
| 56 put_things(); /* Place objects (if any) */ | |
| 57 /* | |
| 58 * Place the traps | |
| 59 */ | |
| 60 if (rnd(10) < level) | |
| 61 { | |
| 62 ntraps = rnd(level / 4) + 1; | |
| 63 if (ntraps > MAXTRAPS) | |
| 64 ntraps = MAXTRAPS; | |
| 65 i = ntraps; | |
| 66 while (i--) | |
| 67 { | |
| 68 /* | |
| 69 * not only wouldn't it be NICE to have traps in mazes | |
| 70 * (not that we care about being nice), since the trap | |
| 71 * number is stored where the passage number is, we | |
| 72 * can't actually do it. | |
| 73 */ | |
| 74 do | |
| 75 { | |
| 76 find_floor(NULL, &stairs, FALSE, FALSE); | |
| 77 } while ( (chat(stairs.y, stairs.x) != FLOOR) && | |
| 78 (flat(stairs.y, stairs.x) & F_REAL) ); | |
| 79 sp = &flat(stairs.y, stairs.x); | |
| 80 *sp &= ~(F_REAL | F_TMASK); | |
| 81 *sp |= rnd(NTRAPS); | |
| 82 } | |
| 83 } | |
| 84 /* | |
| 85 * Place the staircase down. | |
| 86 */ | |
| 87 find_floor(NULL, &stairs, FALSE, FALSE); | |
| 88 chat(stairs.y, stairs.x) = STAIRS; | |
| 89 seenstairs = FALSE; | |
| 90 | |
| 91 for (tp = mlist; tp != NULL; tp = next(tp)) | |
| 92 tp->t_room = roomin(&tp->t_pos); | |
| 93 | |
| 94 find_floor(NULL, &hero, FALSE, TRUE); | |
| 95 enter_room(&hero); | |
| 96 mvaddch(hero.y, hero.x, PLAYER); | |
| 97 if (on(player, SEEMONST)) | |
| 98 turn_see(FALSE); | |
| 99 if (on(player, ISHALU)) | |
| 100 visuals(); | |
| 101 } | |
| 102 | |
| 103 /* | |
| 104 * rnd_room: | |
| 105 * Pick a room that is really there | |
| 106 */ | |
| 107 int | |
| 108 rnd_room(void) | |
| 109 { | |
| 110 int rm; | |
| 111 | |
| 112 do | |
| 113 { | |
| 114 rm = rnd(MAXROOMS); | |
| 115 } while (rooms[rm].r_flags & ISGONE); | |
| 116 return rm; | |
| 117 } | |
| 118 | |
| 119 /* | |
| 120 * put_things: | |
| 121 * Put potions and scrolls on this level | |
| 122 */ | |
| 123 | |
| 124 void | |
| 125 put_things(void) | |
| 126 { | |
| 127 int i; | |
| 128 THING *obj; | |
| 129 | |
| 130 /* | |
| 131 * Once you have found the amulet, the only way to get new stuff is | |
| 132 * go down into the dungeon. | |
| 133 */ | |
| 134 if (amulet && level < max_level) | |
| 135 return; | |
| 136 /* | |
| 137 * check for treasure rooms, and if so, put it in. | |
| 138 */ | |
| 139 if (rnd(TREAS_ROOM) == 0) | |
| 140 treas_room(); | |
| 141 /* | |
| 142 * Do MAXOBJ attempts to put things on a level | |
| 143 */ | |
| 144 for (i = 0; i < MAXOBJ; i++) | |
| 145 if (rnd(100) < 36) | |
| 146 { | |
| 147 /* | |
| 148 * Pick a new object and link it in the list | |
| 149 */ | |
| 150 obj = new_thing(); | |
| 151 attach(lvl_obj, obj); | |
| 152 /* | |
| 153 * Put it somewhere | |
| 154 */ | |
| 155 find_floor(NULL, &obj->o_pos, FALSE, FALSE); | |
| 156 chat(obj->o_pos.y, obj->o_pos.x) = obj->o_type; | |
| 157 } | |
| 158 /* | |
| 159 * If he is really deep in the dungeon and he hasn't found the | |
| 160 * amulet yet, put it somewhere on the ground | |
| 161 */ | |
| 162 if (level >= AMULETLEVEL && !amulet) | |
| 163 { | |
| 164 obj = new_item(); | |
| 165 attach(lvl_obj, obj); | |
| 166 obj->o_hplus = 0; | |
| 167 obj->o_dplus = 0; | |
| 168 strncpy(obj->o_damage,"0x0",sizeof(obj->o_damage)); | |
| 169 strncpy(obj->o_hurldmg,"0x0",sizeof(obj->o_hurldmg)); | |
| 170 obj->o_arm = 11; | |
| 171 obj->o_type = AMULET; | |
| 172 /* | |
| 173 * Put it somewhere | |
| 174 */ | |
| 175 find_floor(NULL, &obj->o_pos, FALSE, FALSE); | |
| 176 chat(obj->o_pos.y, obj->o_pos.x) = AMULET; | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 /* | |
| 181 * treas_room: | |
| 182 * Add a treasure room | |
| 183 */ | |
| 184 #define MAXTRIES 10 /* max number of tries to put down a monster */ | |
| 185 | |
| 186 | |
| 187 void | |
| 188 treas_room(void) | |
| 189 { | |
| 190 int nm; | |
| 191 THING *tp; | |
| 192 struct room *rp; | |
| 193 int spots, num_monst; | |
| 194 coord mp; | |
| 195 | |
| 196 rp = &rooms[rnd_room()]; | |
| 197 spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS; | |
| 198 if (spots > (MAXTREAS - MINTREAS)) | |
| 199 spots = (MAXTREAS - MINTREAS); | |
| 200 num_monst = nm = rnd(spots) + MINTREAS; | |
| 201 while (nm--) | |
| 202 { | |
| 203 find_floor(rp, &mp, 2 * MAXTRIES, FALSE); | |
| 204 tp = new_thing(); | |
| 205 tp->o_pos = mp; | |
| 206 attach(lvl_obj, tp); | |
| 207 chat(mp.y, mp.x) = tp->o_type; | |
| 208 } | |
| 209 | |
| 210 /* | |
| 211 * fill up room with monsters from the next level down | |
| 212 */ | |
| 213 | |
| 214 if ((nm = rnd(spots) + MINTREAS) < num_monst + 2) | |
| 215 nm = num_monst + 2; | |
| 216 spots = (rp->r_max.y - 2) * (rp->r_max.x - 2); | |
| 217 if (nm > spots) | |
| 218 nm = spots; | |
| 219 level++; | |
| 220 while (nm--) | |
| 221 { | |
| 222 spots = 0; | |
| 223 if (find_floor(rp, &mp, MAXTRIES, TRUE)) | |
| 224 { | |
| 225 tp = new_item(); | |
| 226 new_monster(tp, randmonster(FALSE), &mp); | |
| 227 tp->t_flags |= ISMEAN; /* no sloughers in THIS room */ | |
| 228 give_pack(tp); | |
| 229 } | |
| 230 } | |
| 231 level--; | |
| 232 } |
