Mercurial > hg > early-roguelike
comparison rogue4/new_level.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
| author | edwarj4 |
|---|---|
| date | Sat, 24 Oct 2009 16:52:52 +0000 |
| parents | |
| children | 1b73a8641b37 |
comparison
equal
deleted
inserted
replaced
| 11:949d558c2162 | 12:9535a08ddc39 |
|---|---|
| 1 /* | |
| 2 * new_level: | |
| 3 * Dig and draw a new level | |
| 4 * | |
| 5 * @(#)new_level.c 4.19 (Berkeley) 1/12/82 | |
| 6 * | |
| 7 * Rogue: Exploring the Dungeons of Doom | |
| 8 * Copyright (C) 1980, 1981, 1982 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 <time.h> | |
| 15 #include <curses.h> | |
| 16 #include <string.h> | |
| 17 #include "rogue.h" | |
| 18 | |
| 19 #define TREAS_ROOM 20 /* one chance in TREAS_ROOM for a treasure room */ | |
| 20 #define MAXTREAS 10 /* maximum number of treasures in a treasure room */ | |
| 21 #define MINTREAS 2 /* minimum number of treasures in a treasure room */ | |
| 22 | |
| 23 new_level() | |
| 24 { | |
| 25 register int rm, i; | |
| 26 register THING *tp; | |
| 27 register char *sp; | |
| 28 register THING **mp; | |
| 29 register int index; | |
| 30 coord stairs; | |
| 31 | |
| 32 player.t_flags &= ~ISHELD; /* unhold when you go down just in case */ | |
| 33 if (level > max_level) | |
| 34 max_level = level; | |
| 35 /* | |
| 36 * Clean things off from last level | |
| 37 */ | |
| 38 clear(); | |
| 39 for (sp = _level; sp < &_level[MAXCOLS*MAXLINES]; ) | |
| 40 *sp++ = ' '; | |
| 41 for (sp = _flags; sp < &_flags[MAXCOLS*MAXLINES]; ) | |
| 42 *sp++ = F_REAL; | |
| 43 for (mp = _monst; mp < &_monst[MAXCOLS*MAXLINES]; ) | |
| 44 *mp++ = NULL; | |
| 45 clear(); | |
| 46 /* | |
| 47 * Free up the monsters on the last level | |
| 48 */ | |
| 49 for (tp = mlist; tp != NULL; tp = next(tp)) | |
| 50 free_list(tp->t_pack); | |
| 51 free_list(mlist); | |
| 52 /* | |
| 53 * Throw away stuff left on the previous level (if anything) | |
| 54 */ | |
| 55 free_list(lvl_obj); | |
| 56 do_rooms(); /* Draw rooms */ | |
| 57 do_passages(); /* Draw passages */ | |
| 58 no_food++; | |
| 59 put_things(); /* Place objects (if any) */ | |
| 60 /* | |
| 61 * Place the staircase down. | |
| 62 */ | |
| 63 i = 0; | |
| 64 do { | |
| 65 rm = rnd_room(); | |
| 66 rnd_pos(&rooms[rm], &stairs); | |
| 67 index = INDEX(stairs.y, stairs.x); | |
| 68 if (i++ > 100) | |
| 69 { | |
| 70 i = 0; | |
| 71 srand(getpid() + (int) time((time_t *) NULL)); | |
| 72 } | |
| 73 } until (_level[index] == FLOOR); | |
| 74 _level[index] = STAIRS; | |
| 75 /* | |
| 76 * Place the traps | |
| 77 */ | |
| 78 if (rnd(10) < level) | |
| 79 { | |
| 80 ntraps = rnd(level / 4) + 1; | |
| 81 if (ntraps > MAXTRAPS) | |
| 82 ntraps = MAXTRAPS; | |
| 83 i = ntraps; | |
| 84 while (i--) | |
| 85 { | |
| 86 do | |
| 87 { | |
| 88 rm = rnd_room(); | |
| 89 rnd_pos(&rooms[rm], &stairs); | |
| 90 index = INDEX(stairs.y, stairs.x); | |
| 91 } until (_level[index] == FLOOR && (_flags[index] & F_REAL)); | |
| 92 sp = &_flags[index]; | |
| 93 *sp &= ~(F_REAL | F_TMASK); | |
| 94 *sp |= rnd(NTRAPS); | |
| 95 } | |
| 96 } | |
| 97 do | |
| 98 { | |
| 99 rm = rnd_room(); | |
| 100 rnd_pos(&rooms[rm], &hero); | |
| 101 index = INDEX(hero.y, hero.x); | |
| 102 } until (_level[index] == FLOOR && (_flags[index] & F_REAL) | |
| 103 && _monst[index] == NULL); | |
| 104 enter_room(&hero); | |
| 105 move(hero.y, hero.x); | |
| 106 addch(PLAYER); | |
| 107 if (on(player, SEEMONST)) | |
| 108 turn_see(FALSE); | |
| 109 } | |
| 110 | |
| 111 /* | |
| 112 * rnd_room: | |
| 113 * Pick a room that is really there | |
| 114 */ | |
| 115 rnd_room() | |
| 116 { | |
| 117 register int rm; | |
| 118 | |
| 119 do | |
| 120 { | |
| 121 rm = rnd(MAXROOMS); | |
| 122 } while (rooms[rm].r_flags & ISGONE); | |
| 123 return rm; | |
| 124 } | |
| 125 | |
| 126 /* | |
| 127 * put_things: | |
| 128 * Put potions and scrolls on this level | |
| 129 */ | |
| 130 put_things() | |
| 131 { | |
| 132 register int i; | |
| 133 register THING *cur; | |
| 134 register int rm; | |
| 135 coord tp; | |
| 136 | |
| 137 /* | |
| 138 * Once you have found the amulet, the only way to get new stuff is | |
| 139 * go down into the dungeon. | |
| 140 */ | |
| 141 if (amulet && level < max_level) | |
| 142 return; | |
| 143 /* | |
| 144 * check for treasure rooms, and if so, put it in. | |
| 145 */ | |
| 146 if (rnd(TREAS_ROOM) == 0) | |
| 147 treas_room(); | |
| 148 /* | |
| 149 * Do MAXOBJ attempts to put things on a level | |
| 150 */ | |
| 151 for (i = 0; i < MAXOBJ; i++) | |
| 152 if (rnd(100) < 35) | |
| 153 { | |
| 154 /* | |
| 155 * Pick a new object and link it in the list | |
| 156 */ | |
| 157 cur = new_thing(); | |
| 158 attach(lvl_obj, cur); | |
| 159 /* | |
| 160 * Put it somewhere | |
| 161 */ | |
| 162 do { | |
| 163 rm = rnd_room(); | |
| 164 rnd_pos(&rooms[rm], &tp); | |
| 165 } until (chat(tp.y, tp.x) == FLOOR); | |
| 166 chat(tp.y, tp.x) = cur->o_type; | |
| 167 cur->o_pos = tp; | |
| 168 } | |
| 169 /* | |
| 170 * If he is really deep in the dungeon and he hasn't found the | |
| 171 * amulet yet, put it somewhere on the ground | |
| 172 */ | |
| 173 if (level >= AMULETLEVEL && !amulet) | |
| 174 { | |
| 175 cur = new_item(); | |
| 176 attach(lvl_obj, cur); | |
| 177 cur->o_hplus = cur->o_dplus = 0; | |
| 178 strcpy(cur->o_damage,"0d0"); | |
| 179 strcpy(cur->o_hurldmg,"0d0"); | |
| 180 cur->o_ac = 11; | |
| 181 cur->o_type = AMULET; | |
| 182 /* | |
| 183 * Put it somewhere | |
| 184 */ | |
| 185 do { | |
| 186 rm = rnd_room(); | |
| 187 rnd_pos(&rooms[rm], &tp); | |
| 188 } until (winat(tp.y, tp.x) == FLOOR); | |
| 189 chat(tp.y, tp.x) = AMULET; | |
| 190 cur->o_pos = tp; | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 /* | |
| 195 * treas_room: | |
| 196 * Add a treasure room | |
| 197 */ | |
| 198 #define MAXTRIES 10 /* max number of tries to put down a monster */ | |
| 199 | |
| 200 treas_room() | |
| 201 { | |
| 202 register int nm, index; | |
| 203 register THING *tp; | |
| 204 register struct room *rp; | |
| 205 register int spots, num_monst; | |
| 206 coord mp; | |
| 207 | |
| 208 rp = &rooms[rnd_room()]; | |
| 209 spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS; | |
| 210 if (spots > (MAXTREAS - MINTREAS)) | |
| 211 spots = (MAXTREAS - MINTREAS); | |
| 212 num_monst = nm = rnd(spots) + MINTREAS; | |
| 213 while (nm--) | |
| 214 { | |
| 215 do | |
| 216 { | |
| 217 rnd_pos(rp, &mp); | |
| 218 index = INDEX(mp.y, mp.x); | |
| 219 } until (_level[index] == FLOOR); | |
| 220 tp = new_thing(); | |
| 221 tp->o_pos = mp; | |
| 222 attach(lvl_obj, tp); | |
| 223 _level[index] = tp->o_type; | |
| 224 } | |
| 225 | |
| 226 /* | |
| 227 * fill up room with monsters from the next level down | |
| 228 */ | |
| 229 | |
| 230 if ((nm = rnd(spots) + MINTREAS) < num_monst + 2) | |
| 231 nm = num_monst + 2; | |
| 232 spots = (rp->r_max.y - 2) * (rp->r_max.x - 2); | |
| 233 if (nm > spots) | |
| 234 nm = spots; | |
| 235 level++; | |
| 236 while (nm--) | |
| 237 { | |
| 238 spots = 0; | |
| 239 do | |
| 240 { | |
| 241 rnd_pos(rp, &mp); | |
| 242 index = INDEX(mp.y, mp.x); | |
| 243 spots++; | |
| 244 } until (_monst[index] == NULL || spots > MAXTRIES); | |
| 245 if (_monst[index] == NULL) | |
| 246 { | |
| 247 tp = new_item(); | |
| 248 new_monster(tp, randmonster(FALSE), &mp); | |
| 249 tp->t_flags |= ISMEAN; /* no sloughers in THIS room */ | |
| 250 give_pack(tp); | |
| 251 } | |
| 252 } | |
| 253 level--; | |
| 254 } |
