Mercurial > hg > early-roguelike
comparison xrogue/n_level.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 21 Apr 2015 08:55:20 -0400 |
parents | |
children | f54901b9c39b |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 133:e6179860cb76 |
---|---|
1 /* | |
2 n_level.c - Dig and draw a new level | |
3 | |
4 XRogue: Expeditions into the Dungeons of Doom | |
5 Copyright (C) 1991 Robert Pietkivitch | |
6 All rights reserved. | |
7 | |
8 Based on "Advanced Rogue" | |
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
10 All rights reserved. | |
11 | |
12 Based on "Rogue: Exploring the Dungeons of Doom" | |
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
14 All rights reserved. | |
15 | |
16 See the file LICENSE.TXT for full copyright and licensing information. | |
17 */ | |
18 | |
19 #include <curses.h> | |
20 #include "rogue.h" | |
21 #define TERRASAVE 3 | |
22 | |
23 /* | |
24 * new_level: | |
25 * Dig and draw a new level | |
26 */ | |
27 | |
28 new_level(ltype) | |
29 LEVTYPE ltype; /* designates type of level to create */ | |
30 { | |
31 register int rm = 0, i, cnt; | |
32 register unsigned char ch; | |
33 register struct linked_list *item; | |
34 register struct thing *tp; | |
35 register struct object *obj; | |
36 int waslit = 0; /* Was the previous outside level lit? */ | |
37 int starty = 0, startx = 0, deltay = 0, deltax = 0; | |
38 bool fresh=TRUE, vert = 0, top; | |
39 struct room *rp; | |
40 struct linked_list *nitem, *savmonst=NULL, *savitems=NULL; | |
41 coord stairs = {0,0}; | |
42 | |
43 if (wizard) { | |
44 msg("Turns: %ld", turns); /* Number of turns for last level */ | |
45 mpos = 0; | |
46 } | |
47 | |
48 /* Start player off right */ | |
49 turn_off(player, ISHELD); | |
50 turn_off(player, ISFLEE); | |
51 extinguish(suffocate); | |
52 hold_count = 0; | |
53 trap_tries = 0; | |
54 | |
55 /* Are we just entering a dungeon? If so, how big is it? */ | |
56 if (ltype != OUTSIDE && nfloors < 0) nfloors = HARDER+20 + rnd(51); | |
57 | |
58 if (level > max_level) | |
59 max_level = level; | |
60 | |
61 /* Are we starting a new outside level? */ | |
62 if (ltype == OUTSIDE) { | |
63 register int i, j; | |
64 | |
65 /* Save some information prior to clearing the screen */ | |
66 if (level == -1 || mvinch(hero.y, hero.x) == HORZWALL) vert = TRUE; | |
67 else vert = FALSE; | |
68 | |
69 if (level < 1) { | |
70 fresh = TRUE; | |
71 starty = 2; | |
72 startx = 1; | |
73 deltay = deltax = 1; | |
74 level = max_level; /* Restore level to deepest attempt */ | |
75 prev_max = level; /* reset for boundary crossings below */ | |
76 } | |
77 else if (level >= 1 && prev_max == 1000) { | |
78 fresh = TRUE; | |
79 starty = 2; | |
80 startx = 1; | |
81 deltay = deltax = 1; | |
82 prev_max = level; /* reset for boundary crossings below */ | |
83 } | |
84 else { /* Copy several lines of the terrain to the other end */ | |
85 | |
86 unsigned char cch; /* Copy character */ | |
87 | |
88 if (wizard) msg("Crossing sector boundary "); | |
89 | |
90 /* Was the area dark (not magically lit)? */ | |
91 if (!(rooms[0].r_flags & ISDARK)) waslit = 1; | |
92 | |
93 fresh = FALSE; | |
94 if ((vert && hero.y == 1) || (!vert && hero.x == 0)) top = TRUE; | |
95 else top = FALSE; | |
96 for (i=0; i<TERRASAVE; i++) { | |
97 if (vert) | |
98 for (j=1; j<cols-1; j++) { | |
99 if (top) { | |
100 cch = mvinch(i+2, j); | |
101 mvaddch(lines-6+i, j, cch); | |
102 } | |
103 else { | |
104 cch = mvinch(lines-4-i, j); | |
105 mvaddch(4-i, j, cch); | |
106 } | |
107 } | |
108 else | |
109 for (j=2; j<lines-3; j++) { | |
110 if (top) { | |
111 cch = mvinch(j, i+1); | |
112 mvaddch(j, cols-4+i, cch); | |
113 } | |
114 else { | |
115 cch = mvinch(j, cols-2-i); | |
116 mvaddch(j, 3-i, cch); | |
117 } | |
118 } | |
119 } | |
120 | |
121 if (vert) { | |
122 startx = deltax = 1; | |
123 if (top) { | |
124 starty = lines-4-TERRASAVE; | |
125 deltay = -1; | |
126 } | |
127 else { | |
128 starty = TERRASAVE + 2; | |
129 deltay = 1; | |
130 } | |
131 } | |
132 else { | |
133 starty = 2; | |
134 deltay = 1; | |
135 if (top) { | |
136 startx = cols-2-TERRASAVE; | |
137 deltax = -1; | |
138 } | |
139 else { | |
140 deltax = 1; | |
141 startx = TERRASAVE + 1; | |
142 } | |
143 } | |
144 | |
145 /* Check if any monsters should be saved */ | |
146 for (item = mlist; item != NULL; item = nitem) { | |
147 nitem = next(item); | |
148 tp = THINGPTR(item); | |
149 if (vert) { | |
150 if (top) { | |
151 if (tp->t_pos.y < TERRASAVE + 2) | |
152 tp->t_pos.y += lines - 5 - TERRASAVE; | |
153 else continue; | |
154 } | |
155 else { | |
156 if (tp->t_pos.y > lines - 4 - TERRASAVE) | |
157 tp->t_pos.y += 5 + TERRASAVE - lines; | |
158 else continue; | |
159 } | |
160 } | |
161 else { | |
162 if (top) { | |
163 if (tp->t_pos.x < TERRASAVE + 1) | |
164 tp->t_pos.x += cols - 2 - TERRASAVE; | |
165 else continue; | |
166 } | |
167 else { | |
168 if (tp->t_pos.x > cols - 2 - TERRASAVE) | |
169 tp->t_pos.x += 2 + TERRASAVE - cols; | |
170 else continue; | |
171 } | |
172 } | |
173 | |
174 /* | |
175 * If the monster is busy chasing another monster, don't save | |
176 * it | |
177 */ | |
178 if (tp->t_dest && tp->t_dest != &hero) continue; | |
179 | |
180 /* Outside has plenty of monsters, don't need these. | |
181 * detach(mlist, item); | |
182 * attach(savmonst, item); | |
183 */ | |
184 } | |
185 | |
186 /* Check if any treasure should be saved */ | |
187 for (item = lvl_obj; item != NULL; item = nitem) { | |
188 nitem = next(item); | |
189 obj = OBJPTR(item); | |
190 if (vert) { | |
191 if (top) { | |
192 if (obj->o_pos.y < TERRASAVE + 2) | |
193 obj->o_pos.y += lines - 5 - TERRASAVE; | |
194 else continue; | |
195 } | |
196 else { | |
197 if (obj->o_pos.y > lines - 4 - TERRASAVE) | |
198 obj->o_pos.y += 5 + TERRASAVE - lines; | |
199 else continue; | |
200 } | |
201 } | |
202 else { | |
203 if (top) { | |
204 if (obj->o_pos.x < TERRASAVE + 1) | |
205 obj->o_pos.x += cols - 2 - TERRASAVE; | |
206 else continue; | |
207 } | |
208 else { | |
209 if (obj->o_pos.x > cols - 2 - TERRASAVE) | |
210 obj->o_pos.x += 2 + TERRASAVE - cols; | |
211 else continue; | |
212 } | |
213 } | |
214 detach(lvl_obj, item); | |
215 attach(savitems, item); | |
216 } | |
217 } | |
218 } | |
219 | |
220 wclear(cw); | |
221 wclear(mw); | |
222 if (fresh || levtype != OUTSIDE) clear(); | |
223 /* | |
224 * check to see if he missed a UNIQUE, If he did then put it back | |
225 * in the monster table for next time | |
226 */ | |
227 for (item = mlist; item != NULL; item = next(item)) { | |
228 tp = THINGPTR(item); | |
229 if (on(*tp, ISUNIQUE)) | |
230 monsters[tp->t_index].m_normal = TRUE; | |
231 } | |
232 /* | |
233 * Free up the monsters on the last level | |
234 */ | |
235 t_free_list(mlist); | |
236 o_free_list(lvl_obj); /* Free up previous objects (if any) */ | |
237 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) | |
238 r_free_list(rp->r_exit); /* Free up the exit lists */ | |
239 | |
240 levtype = ltype; | |
241 foods_this_level = 0; /* food for hero this level */ | |
242 | |
243 /* What kind of level are we on? */ | |
244 if (ltype == POSTLEV || ltype == STARTLEV) { | |
245 if (ltype == POSTLEV) | |
246 do_post(FALSE); /* Trading post */ | |
247 else | |
248 do_post(TRUE); /* Equipage */ | |
249 | |
250 levtype = ltype = POSTLEV; | |
251 } | |
252 else if (ltype == MAZELEV) { | |
253 do_maze(); | |
254 no_food++; | |
255 put_things(ltype); /* Place objects (if any) */ | |
256 } | |
257 else if (ltype == OUTSIDE) { | |
258 /* Move the cursor back onto the hero */ | |
259 wmove(cw, hero.y, hero.x); | |
260 init_terrain(); | |
261 do_terrain(starty, startx, deltay, deltax, (bool) (fresh || !vert)); | |
262 no_food++; | |
263 put_things(ltype); | |
264 | |
265 /* Should we magically light this area? */ | |
266 if (waslit) rooms[0].r_flags &= ~ISDARK; | |
267 } | |
268 else { | |
269 do_rooms(); /* Draw rooms */ | |
270 do_passages(); /* Draw passages */ | |
271 no_food++; | |
272 put_things(ltype); /* Place objects (if any) */ | |
273 } | |
274 /* | |
275 * Place the staircase down. Only a small chance for an outside stairway. | |
276 */ | |
277 if (ltype != OUTSIDE || roll(1, 5) == 5) { | |
278 cnt = 0; | |
279 do { | |
280 rm = rnd_room(); | |
281 rnd_pos(&rooms[rm], &stairs); | |
282 } until (mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 2500); | |
283 addch(STAIRS); | |
284 } | |
285 /* | |
286 * maybe add a trading post | |
287 */ | |
288 if (level > 5 && rnd(10) == 7 && ltype == NORMLEV) { | |
289 cnt = 0; | |
290 do { | |
291 rm = rnd_room(); | |
292 if (rooms[rm].r_flags & ISTREAS) | |
293 continue; | |
294 rnd_pos(&rooms[rm], &stairs); | |
295 } until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 2500); | |
296 addch(POST); | |
297 } | |
298 if (ltype != POSTLEV) { /* Add monsters that fell through */ | |
299 nitem = tlist; | |
300 while (nitem != NULL) { | |
301 item = nitem; | |
302 nitem = next(item); /* because detach and attach mess up ptrs */ | |
303 tp = THINGPTR(item); | |
304 cnt = 0; | |
305 do { | |
306 rm = rnd_room(); | |
307 rnd_pos(&rooms[rm], &tp->t_pos); | |
308 } until (cnt++ > 2500 || winat(tp->t_pos.y, tp->t_pos.x) == FLOOR); | |
309 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type); | |
310 tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x); | |
311 | |
312 /* | |
313 * If it has a fire, mark it | |
314 */ | |
315 if (on(*tp, HASFIRE)) { | |
316 register struct linked_list *fire_item; | |
317 | |
318 fire_item = creat_item(); | |
319 ldata(fire_item) = (char *) tp; | |
320 attach(rooms[rm].r_fires, fire_item); | |
321 rooms[rm].r_flags |= HASFIRE; | |
322 } | |
323 | |
324 detach(tlist, item); | |
325 turn_off(*tp,ISELSEWHERE); | |
326 attach(mlist, item); | |
327 } | |
328 } | |
329 | |
330 /* Restore any saved monsters */ | |
331 for (item = savmonst; item != NULL; item = nitem) { | |
332 nitem = next(item); | |
333 tp = THINGPTR(item); | |
334 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type); | |
335 tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x); | |
336 | |
337 /* | |
338 * If it has a fire, mark it | |
339 */ | |
340 if (on(*tp, HASFIRE)) { | |
341 register struct linked_list *fire_item; | |
342 | |
343 fire_item = creat_item(); | |
344 ldata(fire_item) = (char *) tp; | |
345 attach(rooms[rm].r_fires, fire_item); | |
346 rooms[rm].r_flags |= HASFIRE; | |
347 } | |
348 | |
349 detach(savmonst, item); | |
350 attach(mlist, item); | |
351 } | |
352 | |
353 /* Restore any saved objects */ | |
354 for(item = savitems; item != NULL; item = nitem) { | |
355 nitem = next(item); | |
356 obj = OBJPTR(item); | |
357 mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type); | |
358 detach(savitems, item); | |
359 attach(lvl_obj, item); | |
360 } | |
361 | |
362 /* | |
363 * Place the traps (except for trading post) | |
364 */ | |
365 ntraps = 0; /* No traps yet */ | |
366 if (levtype == NORMLEV) { | |
367 if (rnd(10) < vlevel) { | |
368 ntraps = rnd(vlevel/4)+2; | |
369 if (ntraps > MAXTRAPS) | |
370 ntraps = MAXTRAPS; | |
371 i = ntraps; | |
372 while (i--) | |
373 { | |
374 cnt = 0; | |
375 do { | |
376 rm = rnd_room(); | |
377 if (rooms[rm].r_flags & ISTREAS) | |
378 continue; | |
379 rnd_pos(&rooms[rm], &stairs); | |
380 } until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 2500); | |
381 | |
382 traps[i].tr_flags = 0; | |
383 | |
384 /* If we are at the bottom, we can't set a trap door */ | |
385 if (level >= nfloors) ch = (unsigned char) rnd(8) + 1; | |
386 else ch = (unsigned char) rnd(9); | |
387 | |
388 switch((int) ch) { | |
389 case 0: ch = TRAPDOOR; | |
390 when 1: ch = BEARTRAP; | |
391 when 2: ch = SLEEPTRAP; | |
392 when 3: ch = ARROWTRAP; | |
393 when 4: ch = TELTRAP; | |
394 when 5: ch = DARTTRAP; | |
395 when 6: ch = POOL; | |
396 traps[i].tr_flags = ISFOUND; | |
397 when 7: ch = MAZETRAP; | |
398 when 8: ch = WORMHOLE; | |
399 } | |
400 addch(ch); | |
401 traps[i].tr_type = ch; | |
402 traps[i].tr_show = FLOOR; | |
403 traps[i].tr_pos = stairs; | |
404 } | |
405 } | |
406 } | |
407 if (fresh) { /* A whole new picture */ | |
408 /* | |
409 * try to find a room for the hero. The objective here is to: | |
410 * --> don't put him in a treasure room | |
411 * --> don't put him on an object | |
412 * --> try not to put him next to the stairs | |
413 */ | |
414 cnt = 2500; | |
415 do { | |
416 if (ltype != OUTSIDE) rm = rnd_room(); | |
417 else continue; | |
418 | |
419 if (rooms[rm].r_flags & ISTREAS) | |
420 continue; | |
421 | |
422 rnd_pos(&rooms[rm], &hero); | |
423 } until( cnt-- == 0 || | |
424 (winat(hero.y, hero.x) == FLOOR && | |
425 DISTANCE(hero.y, hero.x, stairs.y, stairs.x) > cnt/10)); | |
426 } | |
427 else { /* We're extending into an adjacent outside plane */ | |
428 rm = 0; | |
429 if (vert) { | |
430 if (hero.y == 1) hero.y = lines - 3 - TERRASAVE; /* Top to bottom */ | |
431 else hero.y = TERRASAVE + 1; /* Bottom to top */ | |
432 } | |
433 else { | |
434 if (hero.x == 0) hero.x = cols - 1 - TERRASAVE; /* Right to left */ | |
435 else hero.x = TERRASAVE; /* Left to right */ | |
436 } | |
437 } | |
438 oldrp = &rooms[rm]; /* Set the current room */ | |
439 player.t_oldpos = player.t_pos; /* Set the current position */ | |
440 | |
441 if (ISWEARING(R_AGGR) || | |
442 (cur_misc[WEAR_JEWEL] != NULL && | |
443 cur_misc[WEAR_JEWEL]->o_which == MM_JEWEL)) | |
444 aggravate(TRUE, TRUE); /* affect all charactors */ | |
445 | |
446 /* | |
447 * If player is moving up or above his deepest point, wake up any | |
448 * non-uniques | |
449 */ | |
450 else if (level < cur_max) { | |
451 aggravate(FALSE, FALSE); | |
452 } | |
453 | |
454 light(&hero); | |
455 wmove(cw, hero.y, hero.x); | |
456 waddch(cw, PLAYER); | |
457 | |
458 if (level > cur_max) | |
459 cur_max = level; | |
460 | |
461 draw(cw); | |
462 | |
463 status(TRUE); | |
464 | |
465 /* Do we sense any food on this level? */ | |
466 if (cur_relic[SURTUR_RING]) | |
467 quaff(P_FFIND, NULL, NULL, FALSE); | |
468 } | |
469 | |
470 /* | |
471 * Pick a room that is really there | |
472 */ | |
473 | |
474 rnd_room() | |
475 { | |
476 register int rm; | |
477 | |
478 if (levtype != NORMLEV) | |
479 rm = 0; | |
480 else do | |
481 { | |
482 rm = rnd(MAXROOMS); | |
483 } while (rooms[rm].r_flags & ISGONE); | |
484 return rm; | |
485 } | |
486 | |
487 /* | |
488 * put_things: | |
489 * put potions and scrolls on this level | |
490 */ | |
491 | |
492 put_things(ltype) | |
493 LEVTYPE ltype; /* designates type of level to create */ | |
494 { | |
495 register int i, rm, cnt; | |
496 register struct object *cur; | |
497 register struct linked_list *item, *nextitem, *exitptr; | |
498 int length, width; | |
499 int ITEMS = 0; /* number of items to place */ | |
500 coord tp, *exit; | |
501 | |
502 /* | |
503 * The only way to get new stuff is to go down into the dungeon. | |
504 */ | |
505 if (level < cur_max) { | |
506 if (ltype == NORMLEV) | |
507 return; | |
508 } | |
509 | |
510 if (ltype == OUTSIDE) goto jmp_here; /* a jump for outside */ | |
511 | |
512 /* | |
513 * There is a chance that there is a Treasure Room on this level | |
514 */ | |
515 if (ltype == NORMLEV && rnd(150) < level) { | |
516 register int j; | |
517 register struct room *rp; | |
518 | |
519 /* Count the number of free spaces */ | |
520 i = 0; /* 0 tries */ | |
521 do { | |
522 rp = &rooms[rnd_room()]; | |
523 width = rp->r_max.y - 2; | |
524 length = rp->r_max.x - 2; | |
525 } until ((width*length >= MAXTREAS) || (i++ > MAXROOMS*4)); | |
526 | |
527 /* Mark the room as a treasure room */ | |
528 rp->r_flags |= ISTREAS; | |
529 | |
530 /* Make all the doors secret doors */ | |
531 for (exitptr = rp->r_exit; exitptr; exitptr = next(exitptr)) { | |
532 exit = DOORPTR(exitptr); | |
533 move(exit->y, exit->x); | |
534 addch(SECRETDOOR); | |
535 } | |
536 | |
537 /* | |
538 * check to see if there are any monsters in room already | |
539 */ | |
540 for (item = mlist; item != NULL; item = nextitem) { | |
541 register struct thing *tp; | |
542 | |
543 tp = THINGPTR(item); | |
544 nextitem = next(item); | |
545 if (rp == roomin(&tp->t_pos)) { | |
546 /* | |
547 * Don't let nice creatures be generated in a treasure | |
548 * room. | |
549 */ | |
550 if ((player.t_ctype==C_PALADIN || player.t_ctype==C_RANGER || | |
551 player.t_ctype==C_MONK) && off(*tp, ISMEAN)) { | |
552 int index; | |
553 | |
554 if (on(*tp, ISUNIQUE)) index = tp->t_index; | |
555 else index = -1; | |
556 | |
557 /* Get rid of the monster */ | |
558 killed(item, FALSE, FALSE, FALSE); | |
559 | |
560 /* Restore uniques back in the table */ | |
561 if (index != -1) monsters[index].m_normal = TRUE; | |
562 | |
563 continue; | |
564 } | |
565 turn_on(*tp, ISMEAN); | |
566 turn_on(*tp, ISGUARDIAN); | |
567 } | |
568 } | |
569 | |
570 /* Put in the monsters and treasures */ | |
571 for (j=1; j<rp->r_max.y-1; j++) | |
572 for (i=1; i<rp->r_max.x-1; i++) { | |
573 coord trp; | |
574 | |
575 trp.y = rp->r_pos.y+j; | |
576 trp.x = rp->r_pos.x+i; | |
577 | |
578 /* Monsters */ | |
579 if ((rnd(100) < (MAXTREAS*100)/(width*length)) && | |
580 (mvwinch(mw, rp->r_pos.y+j, rp->r_pos.x+i) == ' ')) { | |
581 register struct thing *tp; | |
582 | |
583 /* | |
584 * Put it there and leave it asleep. Wake the monsters | |
585 * when the player enters the room. Hopefully, all bases | |
586 * are covered as far as the ways to get in. This way | |
587 * cpu time is not wasted on the awake monsters that | |
588 * can't get to the player anyway. | |
589 * try not to put any UNIQUEs in a treasure room. | |
590 * note that they may have put put in already by the | |
591 * non-treasure room code. | |
592 * also, try not to put ISMEAN monsters in a treasure | |
593 * room as these are supposed to be non-hostile until | |
594 * attacked. It also makes life simpler for the ranger, | |
595 * paladin, and monk. | |
596 */ | |
597 for(;;) { | |
598 item = new_item(sizeof *tp); /* Make a monster */ | |
599 tp = THINGPTR(item); | |
600 new_monster(item,randmonster(FALSE, TRUE),&trp,TRUE); | |
601 if (on(*tp, HASFIRE)) { | |
602 register struct linked_list *fire_item; | |
603 | |
604 fire_item = creat_item(); | |
605 ldata(fire_item) = (char *) tp; | |
606 attach(rp->r_fires, fire_item); | |
607 rp->r_flags |= HASFIRE; | |
608 } | |
609 /* | |
610 * only picky for these classes | |
611 */ | |
612 if (player.t_ctype != C_RANGER && | |
613 player.t_ctype != C_PALADIN && | |
614 player.t_ctype != C_MONK) | |
615 break; | |
616 if (on(*tp, ISMEAN)) | |
617 break; | |
618 killed (item, FALSE, FALSE, FALSE); | |
619 } | |
620 if (on(*tp, ISUNIQUE)) { /* just in case */ | |
621 carry_obj(tp, monsters[tp->t_index].m_carry); | |
622 tp->t_no_move = movement(tp); | |
623 } | |
624 turn_on(*tp, ISGUARDIAN); | |
625 | |
626 } | |
627 | |
628 /* Treasures */ | |
629 if ((rnd(100) < (MAXTREAS*100)/(width*length)) && | |
630 (mvinch(rp->r_pos.y+j, rp->r_pos.x+i) == FLOOR)) { | |
631 item = new_thing(ALL, TRUE); | |
632 attach(lvl_obj, item); | |
633 cur = OBJPTR(item); | |
634 | |
635 mvaddch(trp.y, trp.x, cur->o_type); | |
636 cur->o_pos = trp; | |
637 } | |
638 } | |
639 } | |
640 | |
641 jmp_here: /* outside jumper for equippage */ | |
642 | |
643 /* | |
644 * Do ITEMS attempts to put things in dungeon, maze, or outside | |
645 */ | |
646 | |
647 if (ltype == OUTSIDE) ITEMS = rnd(15)+1; | |
648 else if (ltype == MAZELEV) ITEMS = rnd(20)+1; | |
649 else ITEMS = MAXOBJ + rnd(4); | |
650 | |
651 for (i = 0; i < ITEMS; i++) | |
652 if (rnd(100) < 65) { | |
653 /* | |
654 * Pick a new object and link it in the list | |
655 */ | |
656 item = new_thing(ALL, TRUE); | |
657 attach(lvl_obj, item); | |
658 cur = OBJPTR(item); | |
659 /* | |
660 * Put it somewhere | |
661 */ | |
662 cnt = 0; | |
663 do { | |
664 if (ltype == OUTSIDE) rm = 0; | |
665 else rm = rnd_room(); | |
666 rnd_pos(&rooms[rm], &tp); | |
667 } until (winat(tp.y, tp.x) == FLOOR || cnt++ > 2500); | |
668 mvaddch(tp.y, tp.x, cur->o_type); | |
669 cur->o_pos = tp; | |
670 } | |
671 } | |
672 |