comparison urogue/newlvl.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children e52a8a7ad4c5
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
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 }