Annotation of early-roguelike/urogue/newlvl.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: newlvl.c - Dig and draw a new level
3:
4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6: All rights reserved.
7:
8: Based on "Advanced Rogue"
9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
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: /*
20: Notes
21:
22: Add treasure room code from Rogue 5.2,
23: put in #ifdef 0/#endif bracket at end of code
24: */
25:
26: #include "rogue.h"
27:
28: /*
29: new_level()
30: Dig and draw a new level
31: */
32:
33: void
34: new_level(LEVTYPE ltype, int special)
35: {
36: int rm, i, cnt;
37: struct linked_list *item, *nitem;
38: struct thing *tp;
39: struct linked_list *fpack = NULL;
40: int going_down = TRUE;
41: coord stairs;
42:
43: /* Start player off right */
44:
45: turn_off(player, ISHELD);
46: turn_off(player, ISFLEE);
47: extinguish_fuse(FUSE_SUFFOCATE);
48: hold_count = 0;
49: trap_tries = 0;
50: no_food++;
51:
52: if (level >= max_level)
53: max_level = level;
54: else
55: going_down = FALSE;
56:
57: /* Free up the monsters on the last level */
58:
59: if (fam_ptr != NULL) /* save what familiar is carrying */
60: {
61: fpack = (THINGPTR(fam_ptr))->t_pack;
62: (THINGPTR(fam_ptr))->t_pack = NULL;
63: fam_ptr = NULL; /* just in case */
64: }
65:
66: for (i = 1; i <= mons_summoned; i++)
67: extinguish_fuse(FUSE_UNSUMMON);
68:
69: mons_summoned = 0;
70:
71: for (item = mlist; item != NULL; item = nitem)
72: {
73: tp = THINGPTR(item);
74: nitem = next(item);
75:
76: if (on(*tp, ISUNIQUE)) /* Put alive UNIQUE on next level */
77: monsters[tp->t_index].m_normal = TRUE;
78:
79: killed(NULL, item, NOMESSAGE, NOPOINTS);
80: }
81:
82: free_list(lvl_obj); /* Free up previous objects (if any) */
83:
84: wclear(cw);
85: wclear(mw);
86: clear();
87: refresh();
88: levtype = ltype;
89:
90: switch (ltype)
91: {
92: case THRONE:
93: do_throne(special); /* do monster throne stuff */
94: break;
95:
96: case MAZELEV:
97: do_maze();
98: break;
99:
100: case POSTLEV:
101: do_post();
102: levtype = ltype = NORMLEV;
103: level++;
104:
105: default:
106: do_rooms(); /* Draw rooms */
107: do_passages(); /* Draw passages */
108: break;
109: }
110:
111: /* Place the staircase down. */
112:
113: cnt = 0;
114:
115: do
116: {
117: rm = rnd_room();
118: rnd_pos(&rooms[rm], &stairs);
119: }
120: while (!(mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000));
121:
122: addch(STAIRS);
123:
124: put_things(ltype); /* Place objects (if any) */
125:
126: if (has_artifact && level == 1)
127: create_lucifer(&stairs);
128:
129: /* Place the traps */
130:
131: ntraps = 0; /* No traps yet */
132:
133: if (levtype == NORMLEV)
134: {
135: if (rnd(10) < level)
136: {
137: char ch = 0;
138:
139: i = ntraps = min(MAXTRAPS, rnd(level / 2) + 1);
140:
141: /* maybe a lair */
142:
143: if (level > 35 && ltype == NORMLEV && rnd(wizard ? 3 : 10) == 0)
144: {
145: cnt = 0;
146:
147: do
148: {
149: rm = rnd_room();
150:
151: if (rooms[rm].r_flags & ISTREAS)
152: continue;
153:
154: rnd_pos(&rooms[rm], &stairs);
155: }
156: while (!(mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000));
157:
158: addch(LAIR);
159: i--;
160: traps[i].tr_flags = 0;
161: traps[i].tr_type = LAIR;
162: traps[i].tr_show = FLOOR;
163: traps[i].tr_pos = stairs;
164: }
165:
166: while (i--)
167: {
168: cnt = 0;
169:
170: do
171: {
172: rm = rnd_room();
173:
174: if (rooms[rm].r_flags & ISTREAS)
175: continue;
176:
177: rnd_pos(&rooms[rm], &stairs);
178: }
179: while (!(mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000));
180:
181: traps[i].tr_flags = 0;
182:
183: switch (rnd(11))
184: {
185: case 0:
186: ch = TRAPDOOR;
187: break;
188:
189: case 1:
190: ch = BEARTRAP;
191: break;
192:
193: case 2:
194: ch = SLEEPTRAP;
195: break;
196:
197: case 3:
198: ch = ARROWTRAP;
199: break;
200:
201: case 4:
202: ch = TELTRAP;
203: break;
204:
205: case 5:
206: ch = DARTTRAP;
207: break;
208:
209: case 6:
210: ch = POOL;
211:
212: if (rnd(10))
213: traps[i].tr_flags = ISFOUND;
214:
215: break;
216:
217: case 7:
218: ch = MAZETRAP;
219: break;
220:
221: case 8:
222: ch = FIRETRAP;
223: break;
224:
225: case 9:
226: ch = POISONTRAP;
227: break;
228:
229: case 10:
230: ch = RUSTTRAP;
231: break;
232: }
233:
234: addch(ch);
235: traps[i].tr_type = ch;
236: traps[i].tr_show = FLOOR;
237: traps[i].tr_pos = stairs;
238: }
239: }
240: }
241:
242: do /* Position hero */
243: {
244: rm = rnd_room();
245:
246: if (levtype != THRONE && (rooms[rm].r_flags & ISTREAS))
247: continue;
248:
249: rnd_pos(&rooms[rm], &hero);
250: }
251: while(!(winat(hero.y, hero.x) == FLOOR &&
252: DISTANCE(hero, stairs) > 16));
253:
254: oldrp = &rooms[rm]; /* Set the current room */
255: player.t_oldpos = player.t_pos; /* Set the current position */
256:
257: if (levtype != POSTLEV && levtype != THRONE)
258: {
259: if (on(player, BLESSMAP) && rnd(5) == 0)
260: {
261: read_scroll(&player, S_MAP, ISNORMAL);
262:
263: if (rnd(3) == 0)
264: turn_off(player, BLESSMAP);
265: }
266:
267: if (player.t_ctype == C_THIEF || on(player, BLESSGOLD) && rnd(5) == 0)
268: {
269: read_scroll(&player, S_GFIND, ISNORMAL);
270:
271: if (rnd(3) == 0)
272: turn_off(player, BLESSGOLD);
273: }
274:
275: if (player.t_ctype == C_RANGER || on(player, BLESSFOOD) && rnd(5) == 0)
276: {
277: read_scroll(&player, S_FOODDET, ISNORMAL);
278:
279: if (rnd(3) == 0)
280: turn_off(player, BLESSFOOD);
281: }
282:
283: if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_ILLUSION ||
284: on(player, BLESSMAGIC) && rnd(5) == 0)
285: {
286: quaff(&player, P_TREASDET, ISNORMAL);
287:
288: if (rnd(3) == 0)
289: turn_off(player, BLESSMAGIC);
290: }
291:
292: if (player.t_ctype == C_DRUID || on(player, BLESSMONS) && rnd(5) == 0)
293: {
294: quaff(&player, P_MONSTDET, ISNORMAL);
295:
296: if (rnd(3) == 0)
297: turn_off(player, BLESSMONS);
298: }
299: else if (player.t_ctype == C_CLERIC ||
300: player.t_ctype == C_PALADIN || is_wearing(R_PIETY))
301: undead_sense();
302: }
303:
304: if (is_wearing(R_AGGR))
305: aggravate();
306:
307: if (is_wearing(R_ADORNMENT) ||
308: cur_armor != NULL && cur_armor->o_which == MITHRIL)
309: {
310: int greed = FALSE;
311:
312: for (item = mlist; item != NULL; item = next(item))
313: {
314: tp = THINGPTR(item);
315:
316: if (on(*tp, ISGREED))
317: {
318: turn_on(*tp, ISRUN);
319: turn_on(*tp, ISMEAN);
320: tp->t_ischasing = TRUE;
321: tp->t_chasee = &player;
322: greed = TRUE;
323: }
324: }
325:
326: if (greed)
327: msg("An uneasy feeling comes over you.");
328: }
329:
330: if (is_carrying(TR_PALANTIR)) /* Palantir shows all */
331: {
332: msg("The Palantir reveals all!");
333:
334: overlay(stdscr, cw); /* Wizard mode 'f' command */
335: overlay(mw, cw); /* followed by 'm' command */
336: }
337:
338: if (is_carrying(TR_PHIAL)) /* Phial lights your way */
339: {
340: if (!is_carrying(TR_PALANTIR))
341: msg("The Phial banishes the darkness!");
342:
343: for (i = 0; i < MAXROOMS; i++)
344: rooms[i].r_flags &= ~ISDARK;
345: }
346:
347: if (is_carrying(TR_AMULET)) /* Amulet describes the level */
348: {
349: level_eval();
350: }
351:
352:
353: wmove(cw, hero.y, hero.x);
354: waddch(cw, PLAYER);
355: light(&hero);
356:
357: /* Summon familiar if player has one */
358:
359: if (on(player, HASFAMILIAR))
360: {
361: summon_monster((short) fam_type, FAMILIAR, MESSAGE);
362:
363: if (fam_ptr != NULL) /* add old pack to new */
364: {
365: tp = THINGPTR(fam_ptr);
366:
367: if (tp->t_pack == NULL)
368: tp->t_pack = fpack;
369: else if (fpack != NULL)
370: {
371: for (item = tp->t_pack; item->l_next != NULL;item = next(item))
372: ;
373:
374: item->l_next = fpack;
375: debug("new_level: l_prev = %p",item);
376: fpack->l_prev = item;
377: }
378: }
379: else
380: free_list(fpack);
381: }
382:
383: mem_check(__FILE__,__LINE__);
384: status(TRUE);
385: }
386:
387: /*
388: put_things()
389: put potions and scrolls on this level
390: */
391:
392: void
393: put_things(LEVTYPE ltype)
394: {
395: int i, rm, cnt;
396: struct linked_list *item;
397: struct object *cur;
398: int got_unique = FALSE;
399: int length, width, maxobjects;
400: coord tp;
401:
402: /*
403: * Once you have found an artifact, the only way to get new stuff is
404: * go down into the dungeon.
405: */
406:
407: if (has_artifact && level < max_level && ltype != THRONE)
408: return;
409:
410: /*
411: * There is a chance that there is a treasure room on this level
412: * Increasing chance after level 10
413: */
414:
415: if (ltype != MAZELEV && rnd(50) < level - 10)
416: {
417: int n, j;
418: struct room *rp;
419:
420: /* Count the number of free spaces */
421: n = 0; /* 0 tries */
422:
423: do
424: {
425: rp = &rooms[rnd_room()];
426: width = rp->r_max.y - 2;
427: length = rp->r_max.x - 2;
428: }
429: while(!((width * length <= MAXTREAS) || (n++ > MAXROOMS * 4)));
430:
431: /* Mark the room as a treasure room */
432:
433: rp->r_flags |= ISTREAS;
434:
435: /* Make all the doors secret doors */
436:
437: for (n = 0; n < rp->r_nexits; n++)
438: {
439: move(rp->r_exit[n].y, rp->r_exit[n].x);
440: addch(SECRETDOOR);
441: }
442:
443: /* Put in the monsters and treasures */
444:
445: for (j = 1; j < rp->r_max.y - 1; j++)
446: for (n = 1; n < rp->r_max.x - 1; n++)
447: {
448: coord trp;
449:
450: trp.y = rp->r_pos.y + j;
451: trp.x = rp->r_pos.x + n;
452:
453: /* Monsters */
454:
455: if ((rnd(100) < (MAXTREAS * 100) /
456: (width * length)) &&
457: (mvwinch(mw, rp->r_pos.y + j,
458: rp->r_pos.x + n) == ' '))
459: {
460: struct thing *th;
461:
462: /* Make a monster */
463:
464: item = new_item(sizeof *th);
465: th = THINGPTR(item);
466:
467: /*
468: * Put it there and aggravate it
469: * (unless it can escape) only put
470: * one UNIQUE per treasure room at
471: * most
472: */
473:
474: if (got_unique)
475: new_monster(item, randmonster(NOWANDER, GRAB), &trp,
476: NOMAXSTATS);
477: else
478: {
479: new_monster(item, randmonster(NOWANDER, NOGRAB), &trp,
480: NOMAXSTATS);
481:
482: if (on(*th, ISUNIQUE))
483: got_unique = TRUE;
484: }
485:
486: turn_off(*th, ISFRIENDLY);
487: turn_on(*th, ISMEAN);
488:
489: if (off(*th, CANINWALL))
490: {
491: th->t_ischasing = TRUE;
492: th->t_chasee = &player;
493: turn_on(*th, ISRUN);
494: }
495: }
496:
497: /* Treasures */
498:
499: if ((rnd(100) < (MAXTREAS * 100) /
500: (width * length)) &&
501: (mvinch(rp->r_pos.y + j,
502: rp->r_pos.x + n) == FLOOR))
503: {
504: item = new_thing();
505: cur = OBJPTR(item);
506: cur->o_pos = trp;
507: add_obj(item, trp.y, trp.x);
508: }
509: }
510: }
511:
512: /* Do MAXOBJ attempts to put things on a level, maybe */
513:
514: maxobjects = (ltype == THRONE) ? rnd(3 * MAXOBJ) + 35 : MAXOBJ;
515:
516: for (i = 0; i < maxobjects; i++)
517: if (rnd(100) < 40 || ltype == THRONE)
518: {
519: /* Pick a new object and link it in the list */
520:
521: item = new_thing();
522: cur = OBJPTR(item);
523:
524: /* Put it somewhere */
525:
526: cnt = 0;
527:
528: do
529: {
530: rm = rnd_room();
531: rnd_pos(&rooms[rm], &tp);
532: }
533: while(!(winat(tp.y, tp.x) == FLOOR || cnt++ > 500));
534:
535: cur->o_pos = tp;
536: add_obj(item, tp.y, tp.x);
537: }
538:
539: /*
540: * If he is really deep in the dungeon and he hasn't found an
541: * artifact yet, put it somewhere on the ground
542: */
543:
544: if (make_artifact())
545: {
546: item = new_item(sizeof *cur);
547: cur = OBJPTR(item);
548: new_artifact(-1, cur);
549: cnt = 0;
550:
551: do
552: {
553: rm = rnd_room();
554: rnd_pos(&rooms[rm], &tp);
555: }
556: while(!(winat(tp.y, tp.x) == FLOOR || cnt++ > 500));
557:
558: cur->o_pos = tp;
559: add_obj(item, tp.y, tp.x);
560: }
561: }
562:
563: /*
564: do_throne()
565: Put a monster's throne room and monsters on the screen
566: */
567:
568: void
569: do_throne(int special)
570: {
571: coord mp;
572: int save_level;
573: int i;
574: struct room *rp;
575: struct thing *tp;
576: struct linked_list *item;
577: int throne_monster;
578:
579: for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
580: {
581: rp->r_nexits = 0; /* no exits */
582: rp->r_flags = ISGONE; /* kill all rooms */
583: }
584:
585: rp = &rooms[0]; /* point to only room */
586: rp->r_flags = 0; /* this room NOT gone */
587: rp->r_max.x = 40;
588: rp->r_max.y = 10; /* 10 * 40 room */
589: rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */
590: rp->r_pos.y = 3; /* 2nd line */
591: draw_room(rp); /* draw the only room */
592:
593: save_level = level;
594: level = max(2 * level, level + roll(4, 6));
595:
596: if (special == 0) /* Who has he offended? */
597: do
598: throne_monster = nummonst - roll(1, NUMSUMMON);
599: while(!monsters[throne_monster].m_normal);
600: else
601: throne_monster = special;
602:
603: /* Create summoning monster */
604:
605: item = new_item(sizeof *tp);
606:
607: tp = THINGPTR(item);
608:
609: do
610: {
611: rnd_pos(rp, &mp);
612: }
613: while(mvwinch(stdscr, mp.y, mp.x) != FLOOR);
614:
615: new_monster(item, throne_monster, &mp, MAXSTATS);
616: turn_on(*tp, CANSEE);
617: turn_off(*tp, ISFRIENDLY);
618:
619: if (on(*tp, CANSUMMON)) /* summon his helpers */
620: summon_help(tp, FORCE);
621: else
622: {
623: for (i = roll(4, 10); i >= 0; i--)
624: {
625: item = new_item(sizeof *tp);
626: tp = THINGPTR(item);
627:
628: do
629: {
630: rnd_pos(rp, &mp);
631: }
632: while(mvwinch(stdscr, mp.y, mp.x) != FLOOR);
633:
634: new_monster(item, randmonster(NOWANDER, NOGRAB), &mp, MAXSTATS);
635: turn_on(*tp, CANSEE);
636: turn_off(*tp, ISFRIENDLY);
637: }
638: }
639:
640: level = save_level + roll(2, 3); /* send the hero down */
641: aggravate();
642: }
643:
644: /*
645: create_lucifer()
646: special surprise on the way back up create Lucifer
647: with more than the usual god abilities
648: */
649:
650: void
651: create_lucifer(coord *stairs)
652: {
653: struct linked_list *item = new_item(sizeof(struct thing));
654: struct thing *tp = THINGPTR(item);
655:
656: new_monster(item, nummonst + 1, stairs, MAXSTATS);
657: turn_on(*tp, CANINWALL);
658: turn_on(*tp, CANHUH);
659: turn_on(*tp, CANBLINK);
660: turn_on(*tp, CANSNORE);
661: turn_on(*tp, CANDISEASE);
662: turn_on(*tp, NOCOLD);
663: turn_on(*tp, TOUCHFEAR);
664: turn_on(*tp, BMAGICHIT);
665: turn_on(*tp, NOFIRE);
666: turn_on(*tp, NOBOLT);
667: turn_on(*tp, CANBLIND);
668: turn_on(*tp, CANINFEST);
669: turn_on(*tp, CANSMELL);
670: turn_on(*tp, CANPARALYZE);
671: turn_on(*tp, CANSTINK);
672: turn_on(*tp, CANCHILL);
673: turn_on(*tp, CANFRIGHTEN);
674: turn_on(*tp, CANHOLD);
675: turn_on(*tp, CANBRANDOM);
676: }
CVSweb