Wikihack
Advertisement

Below is the full text to src/mkroom.c from NetHack 3.4.3. To link to a particular line, write [[mkroom.c#line123]], for example. This file deals with the creation of special rooms, like shops, temples, zoos, leprechaun halls, etc..

Top of file[]

1.    /*	SCCS Id: @(#)mkroom.c	3.4	2001/09/06	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    /*
6.     * Entry points:
7.     *	mkroom() -- make and stock a room of a given type
8.     *	nexttodoor() -- return TRUE if adjacent to a door
9.     *	has_dnstairs() -- return TRUE if given room has a down staircase
10.    *	has_upstairs() -- return TRUE if given room has an up staircase
11.    *	courtmon() -- generate a court monster
12.    *	save_rooms() -- save rooms into file fd
13.    *	rest_rooms() -- restore rooms from file fd
14.    */
15.   
16.   #include "hack.h"
17.   
18.   #ifdef OVLB
19.   STATIC_DCL boolean FDECL(isbig, (struct mkroom *));
20.   STATIC_DCL struct mkroom * FDECL(pick_room,(BOOLEAN_P));
21.   STATIC_DCL void NDECL(mkshop), FDECL(mkzoo,(int)), NDECL(mkswamp);
22.   STATIC_DCL void NDECL(mktemple);
23.   STATIC_DCL coord * FDECL(shrine_pos, (int));
24.   STATIC_DCL struct permonst * NDECL(morguemon);
25.   STATIC_DCL struct permonst * NDECL(antholemon);
26.   STATIC_DCL struct permonst * NDECL(squadmon);
27.   STATIC_DCL void FDECL(save_room, (int,struct mkroom *));
28.   STATIC_DCL void FDECL(rest_room, (int,struct mkroom *));
29.   #endif /* OVLB */
30.   
31.   #define sq(x) ((x)*(x))
32.   
33.   extern const struct shclass shtypes[];	/* defined in shknam.c */
34.   
35.   #ifdef OVLB
36.   

isbig[]

37.   STATIC_OVL boolean
38.   isbig(sroom)
39.   register struct mkroom *sroom;
40.   {
41.   	register int area = (sroom->hx - sroom->lx + 1)
42.   			   * (sroom->hy - sroom->ly + 1);
43.   	return((boolean)( area > 20 ));
44.   }
45.   

mkroom[]

46.   void
47.   mkroom(roomtype)
48.   /* make and stock a room of a given type */
49.   int	roomtype;
50.   {
51.       if (roomtype >= SHOPBASE)
52.   	mkshop();	/* someday, we should be able to specify shop type */
53.       else switch(roomtype) {
54.   	case COURT:	mkzoo(COURT); break;
55.   	case ZOO:	mkzoo(ZOO); break;
56.   	case BEEHIVE:	mkzoo(BEEHIVE); break;
57.   	case MORGUE:	mkzoo(MORGUE); break;
58.   	case BARRACKS:	mkzoo(BARRACKS); break;
59.   	case SWAMP:	mkswamp(); break;
60.   	case TEMPLE:	mktemple(); break;
61.   	case LEPREHALL:	mkzoo(LEPREHALL); break;
62.   	case COCKNEST:	mkzoo(COCKNEST); break;
63.   	case ANTHOLE:	mkzoo(ANTHOLE); break;
64.   	default:	impossible("Tried to make a room of type %d.", roomtype);
65.       }
66.   }
67.   

mkshop[]

68.   STATIC_OVL void
69.   mkshop()
70.   {
71.   	register struct mkroom *sroom;
72.   	int i = -1;
73.   #ifdef WIZARD
74.   	char *ep = (char *)0;	/* (init == lint suppression) */
75.   
76.   	/* first determine shoptype */
77.   	if(wizard){
78.   #ifndef MAC
79.   		ep = nh_getenv("SHOPTYPE");
80.   		if(ep){
81.   			if(*ep == 'z' || *ep == 'Z'){
82.   				mkzoo(ZOO);
83.   				return;
84.   			}
85.   			if(*ep == 'm' || *ep == 'M'){
86.   				mkzoo(MORGUE);
87.   				return;
88.   			}
89.   			if(*ep == 'b' || *ep == 'B'){
90.   				mkzoo(BEEHIVE);
91.   				return;
92.   			}
93.   			if(*ep == 't' || *ep == 'T' || *ep == '\\'){
94.   				mkzoo(COURT);
95.   				return;
96.   			}
97.   			if(*ep == 's' || *ep == 'S'){
98.   				mkzoo(BARRACKS);
99.   				return;
100.  			}
101.  			if(*ep == 'a' || *ep == 'A'){
102.  				mkzoo(ANTHOLE);
103.  				return;
104.  			}
105.  			if(*ep == 'c' || *ep == 'C'){
106.  				mkzoo(COCKNEST);
107.  				return;
108.  			}
109.  			if(*ep == 'l' || *ep == 'L'){
110.  				mkzoo(LEPREHALL);
111.  				return;
112.  			}
113.  			if(*ep == '_'){
114.  				mktemple();
115.  				return;
116.  			}
117.  			if(*ep == '}'){
118.  				mkswamp();
119.  				return;
120.  			}
121.  			for(i=0; shtypes[i].name; i++)
122.  				if(*ep == def_oc_syms[(int)shtypes[i].symb])
123.  				    goto gottype;
124.  			if(*ep == 'g' || *ep == 'G')
125.  				i = 0;
126.  			else
127.  				i = -1;
128.  		}
129.  #endif
130.  	}
131.  #ifndef MAC
132.  gottype:
133.  #endif
134.  #endif
135.  	for(sroom = &rooms[0]; ; sroom++){
136.  		if(sroom->hx < 0) return;
137.  		if(sroom - rooms >= nroom) {
138.  			pline("rooms not closed by -1?");
139.  			return;
140.  		}
141.  		if(sroom->rtype != OROOM) continue;
142.  		if(has_dnstairs(sroom) || has_upstairs(sroom))
143.  			continue;
144.  		if(
145.  #ifdef WIZARD
146.  		   (wizard && ep && sroom->doorct != 0) ||
147.  #endif
148.  			sroom->doorct == 1) break;
149.  	}
150.  	if (!sroom->rlit) {
151.  		int x, y;
152.  
153.  		for(x = sroom->lx - 1; x <= sroom->hx + 1; x++)
154.  		for(y = sroom->ly - 1; y <= sroom->hy + 1; y++)
155.  			levl[x][y].lit = 1;
156.  		sroom->rlit = 1;
157.  	}
158.  
159.  	if(i < 0) {			/* shoptype not yet determined */
160.  	    register int j;
161.  
162.  	    /* pick a shop type at random */
163.  	    for (j = rnd(100), i = 0; (j -= shtypes[i].prob) > 0; i++)
164.  		continue;
165.  
166.  	    /* big rooms cannot be wand or book shops,
167.  	     * - so make them general stores
168.  	     */
169.  	    if(isbig(sroom) && (shtypes[i].symb == WAND_CLASS
170.  				|| shtypes[i].symb == SPBOOK_CLASS)) i = 0;
171.  	}
172.  	sroom->rtype = SHOPBASE + i;
173.  
174.  	/* set room bits before stocking the shop */
175.  #ifdef SPECIALIZATION
176.  	topologize(sroom, FALSE); /* doesn't matter - this is a special room */
177.  #else
178.  	topologize(sroom);
179.  #endif
180.  
181.  	/* stock the room with a shopkeeper and artifacts */
182.  	stock_room(i, sroom);
183.  }
184.  

pick_room[]

185.  STATIC_OVL struct mkroom *
186.  pick_room(strict)
187.  register boolean strict;
188.  /* pick an unused room, preferably with only one door */
189.  {
190.  	register struct mkroom *sroom;
191.  	register int i = nroom;
192.  
193.  	for(sroom = &rooms[rn2(nroom)]; i--; sroom++) {
194.  		if(sroom == &rooms[nroom])
195.  			sroom = &rooms[0];
196.  		if(sroom->hx < 0)
197.  			return (struct mkroom *)0;
198.  		if(sroom->rtype != OROOM)	continue;
199.  		if(!strict) {
200.  		    if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
201.  			continue;
202.  		} else if(has_upstairs(sroom) || has_dnstairs(sroom))
203.  			continue;
204.  		if(sroom->doorct == 1 || !rn2(5)
205.  #ifdef WIZARD
206.  						|| wizard
207.  #endif
208.  							)
209.  			return sroom;
210.  	}
211.  	return (struct mkroom *)0;
212.  }
213.  

mkzoo[]

214.  STATIC_OVL void
215.  mkzoo(type)
216.  int type;
217.  {
218.  	register struct mkroom *sroom;
219.  
220.  	if ((sroom = pick_room(FALSE)) != 0) {
221.  		sroom->rtype = type;
222.  		fill_zoo(sroom);
223.  	}
224.  }
225.  

fill_zoo[]

226.  void
227.  fill_zoo(sroom)
228.  struct mkroom *sroom;
229.  {
230.  	struct monst *mon;
231.  	register int sx,sy,i;
232.  	int sh, tx, ty, goldlim, type = sroom->rtype;
233.  	int rmno = (sroom - rooms) + ROOMOFFSET;
234.  	coord mm;
235.  
236.  #ifdef GCC_WARN
237.  	tx = ty = goldlim = 0;
238.  #endif
239.  
240.  	sh = sroom->fdoor;
241.  	switch(type) {
242.  	    case COURT:
243.  		if(level.flags.is_maze_lev) {
244.  		    for(tx = sroom->lx; tx <= sroom->hx; tx++)
245.  			for(ty = sroom->ly; ty <= sroom->hy; ty++)
246.  			    if(IS_THRONE(levl[tx][ty].typ))
247.  				goto throne_placed;
248.  		}
249.  		i = 100;
250.  		do {	/* don't place throne on top of stairs */
251.  			(void) somexy(sroom, &mm);
252.  			tx = mm.x; ty = mm.y;
253.  		} while (occupied((xchar)tx, (xchar)ty) && --i > 0);
254.  	    throne_placed:
255.  		/* TODO: try to ensure the enthroned monster is an M2_PRINCE */
256.  		break;
257.  	    case BEEHIVE:
258.  		tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
259.  		ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
260.  		if(sroom->irregular) {
261.  		    /* center might not be valid, so put queen elsewhere */
262.  		    if ((int) levl[tx][ty].roomno != rmno ||
263.  			    levl[tx][ty].edge) {
264.  			(void) somexy(sroom, &mm);
265.  			tx = mm.x; ty = mm.y;
266.  		    }
267.  		}
268.  		break;
269.  	    case ZOO:
270.  	    case LEPREHALL:
271.  		goldlim = 500 * level_difficulty();
272.  		break;
273.  	}
274.  	for(sx = sroom->lx; sx <= sroom->hx; sx++)
275.  	    for(sy = sroom->ly; sy <= sroom->hy; sy++) {
276.  		if(sroom->irregular) {
277.  		    if ((int) levl[sx][sy].roomno != rmno ||
278.  			  levl[sx][sy].edge ||
279.  			  (sroom->doorct &&
280.  			   distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1))
281.  			continue;
282.  		} else if(!SPACE_POS(levl[sx][sy].typ) ||
283.  			  (sroom->doorct &&
284.  			   ((sx == sroom->lx && doors[sh].x == sx-1) ||
285.  			    (sx == sroom->hx && doors[sh].x == sx+1) ||
286.  			    (sy == sroom->ly && doors[sh].y == sy-1) ||
287.  			    (sy == sroom->hy && doors[sh].y == sy+1))))
288.  		    continue;
289.  		/* don't place monster on explicitly placed throne */
290.  		if(type == COURT && IS_THRONE(levl[sx][sy].typ))
291.  		    continue;
292.  		mon = makemon(
293.  		    (type == COURT) ? courtmon() :
294.  		    (type == BARRACKS) ? squadmon() :
295.  		    (type == MORGUE) ? morguemon() :
296.  		    (type == BEEHIVE) ?
297.  			(sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] :
298.  			 &mons[PM_KILLER_BEE]) :
299.  		    (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] :
300.  		    (type == COCKNEST) ? &mons[PM_COCKATRICE] :
301.  		    (type == ANTHOLE) ? antholemon() :
302.  		    (struct permonst *) 0,
303.  		   sx, sy, NO_MM_FLAGS);
304.  		if(mon) {
305.  			mon->msleeping = 1;
306.  			if (type==COURT && mon->mpeaceful) {
307.  				mon->mpeaceful = 0;
308.  				set_malign(mon);
309.  			}
310.  		}
311.  		switch(type) {
312.  		    case ZOO:
313.  		    case LEPREHALL:
314.  			if(sroom->doorct)
315.  			{
316.  			    int distval = dist2(sx,sy,doors[sh].x,doors[sh].y);
317.  			    i = sq(distval);
318.  			}
319.  			else
320.  			    i = goldlim;
321.  			if(i >= goldlim) i = 5*level_difficulty();
322.  			goldlim -= i;
323.  			(void) mkgold((long) rn1(i, 10), sx, sy);
324.  			break;
325.  		    case MORGUE:
326.  			if(!rn2(5))
327.  			    (void) mk_tt_object(CORPSE, sx, sy);
328.  			if(!rn2(10))	/* lots of treasure buried with dead */
329.  			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
330.  					     sx, sy, TRUE, FALSE);
331.  			if (!rn2(5))
332.  			    make_grave(sx, sy, (char *)0);
333.  			break;
334.  		    case BEEHIVE:
335.  			if(!rn2(3))
336.  			    (void) mksobj_at(LUMP_OF_ROYAL_JELLY,
337.  					     sx, sy, TRUE, FALSE);
338.  			break;
339.  		    case BARRACKS:
340.  			if(!rn2(20))	/* the payroll and some loot */
341.  			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
342.  					     sx, sy, TRUE, FALSE);
343.  			break;
344.  		    case COCKNEST:
345.  			if(!rn2(3)) {
346.  			    struct obj *sobj = mk_tt_object(STATUE, sx, sy);
347.  
348.  			    if (sobj) {
349.  				for (i = rn2(5); i; i--)
350.  				    (void) add_to_container(sobj,
351.  						mkobj(RANDOM_CLASS, FALSE));
352.  				sobj->owt = weight(sobj);
353.  			    }
354.  			}
355.  			break;
356.  		    case ANTHOLE:
357.  			if(!rn2(3))
358.  			    (void) mkobj_at(FOOD_CLASS, sx, sy, FALSE);
359.  			break;
360.  		}
361.  	    }
362.  	switch (type) {
363.  	      case COURT:
364.  		{
365.  		  struct obj *chest;
366.  		  levl[tx][ty].typ = THRONE;
367.  		  (void) somexy(sroom, &mm);
368.  		  (void) mkgold((long) rn1(50 * level_difficulty(),10), mm.x, mm.y);
369.  		  /* the royal coffers */
370.  		  chest = mksobj_at(CHEST, mm.x, mm.y, TRUE, FALSE);
371.  		  chest->spe = 2; /* so it can be found later */
372.  		  level.flags.has_court = 1;
373.  		  break;
374.  		}
375.  	      case BARRACKS:
376.  		  level.flags.has_barracks = 1;
377.  		  break;
378.  	      case ZOO:
379.  		  level.flags.has_zoo = 1;
380.  		  break;
381.  	      case MORGUE:
382.  		  level.flags.has_morgue = 1;
383.  		  break;
384.  	      case SWAMP:
385.  		  level.flags.has_swamp = 1;
386.  		  break;
387.  	      case BEEHIVE:
388.  		  level.flags.has_beehive = 1;
389.  		  break;
390.  	}
391.  }
392.  

mkundead[]

393.  /* make a swarm of undead around mm */
394.  void
395.  mkundead(mm, revive_corpses, mm_flags)
396.  coord *mm;
397.  boolean revive_corpses;
398.  int mm_flags;
399.  {
400.  	int cnt = (level_difficulty() + 1)/10 + rnd(5);
401.  	struct permonst *mdat;
402.  	struct obj *otmp;
403.  	coord cc;
404.  
405.  	while (cnt--) {
406.  	    mdat = morguemon();
407.  	    if (enexto(&cc, mm->x, mm->y, mdat) &&
408.  		    (!revive_corpses ||
409.  		     !(otmp = sobj_at(CORPSE, cc.x, cc.y)) ||
410.  		     !revive(otmp)))
411.  		(void) makemon(mdat, cc.x, cc.y, mm_flags);
412.  	}
413.  	level.flags.graveyard = TRUE;	/* reduced chance for undead corpse */
414.  }
415.  

morguemon[]

416.  STATIC_OVL struct permonst *
417.  morguemon()
418.  {
419.  	register int i = rn2(100), hd = rn2(level_difficulty());
420.  
421.  	if(hd > 10 && i < 10)
422.  		return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) :
423.  						       &mons[ndemon(A_NONE)]);
424.  	if(hd > 8 && i > 85)
425.  		return(mkclass(S_VAMPIRE,0));
426.  
427.  	return((i < 20) ? &mons[PM_GHOST]
428.  			: (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE,0));
429.  }
430.  

antholemon[]

431.  STATIC_OVL struct permonst *
432.  antholemon()
433.  {
434.  	int mtyp;
435.  
436.  	/* Same monsters within a level, different ones between levels */
437.  	switch ((level_difficulty() + ((long)u.ubirthday)) % 3) {
438.  	default:	mtyp = PM_GIANT_ANT; break;
439.  	case 0:		mtyp = PM_SOLDIER_ANT; break;
440.  	case 1:		mtyp = PM_FIRE_ANT; break;
441.  	}
442.  	return ((mvitals[mtyp].mvflags & G_GONE) ?
443.  			(struct permonst *)0 : &mons[mtyp]);
444.  }
445.  

mkswamp[]

446.  STATIC_OVL void
447.  mkswamp()	/* Michiel Huisjes & Fred de Wilde */
448.  {
449.  	register struct mkroom *sroom;
450.  	register int sx,sy,i,eelct = 0;
451.  
452.  	for(i=0; i<5; i++) {		/* turn up to 5 rooms swampy */
453.  		sroom = &rooms[rn2(nroom)];
454.  		if(sroom->hx < 0 || sroom->rtype != OROOM ||
455.  		   has_upstairs(sroom) || has_dnstairs(sroom))
456.  			continue;
457.  
458.  		/* satisfied; make a swamp */
459.  		sroom->rtype = SWAMP;
460.  		for(sx = sroom->lx; sx <= sroom->hx; sx++)
461.  		for(sy = sroom->ly; sy <= sroom->hy; sy++)
462.  		if(!OBJ_AT(sx, sy) &&
463.  		   !MON_AT(sx, sy) && !t_at(sx,sy) && !nexttodoor(sx,sy)) {
464.  		    if((sx+sy)%2) {
465.  			levl[sx][sy].typ = POOL;
466.  			if(!eelct || !rn2(4)) {
467.  			    /* mkclass() won't do, as we might get kraken */
468.  			    (void) makemon(rn2(5) ? &mons[PM_GIANT_EEL]
469.  						  : rn2(2) ? &mons[PM_PIRANHA]
470.  						  : &mons[PM_ELECTRIC_EEL],
471.  						sx, sy, NO_MM_FLAGS);
472.  			    eelct++;
473.  			}
474.  		    } else
475.  			if(!rn2(4))	/* swamps tend to be moldy */
476.  			    (void) makemon(mkclass(S_FUNGUS,0),
477.  						sx, sy, NO_MM_FLAGS);
478.  		}
479.  		level.flags.has_swamp = 1;
480.  	}
481.  }
482.  

shrine_pos[]

483.  STATIC_OVL coord *
484.  shrine_pos(roomno)
485.  int roomno;
486.  {
487.  	static coord buf;
488.  	struct mkroom *troom = &rooms[roomno - ROOMOFFSET];
489.  
490.  	buf.x = troom->lx + ((troom->hx - troom->lx) / 2);
491.  	buf.y = troom->ly + ((troom->hy - troom->ly) / 2);
492.  	return(&buf);
493.  }
494.  

mktemple[]

495.  STATIC_OVL void
496.  mktemple()
497.  {
498.  	register struct mkroom *sroom;
499.  	coord *shrine_spot;
500.  	register struct rm *lev;
501.  
502.  	if(!(sroom = pick_room(TRUE))) return;
503.  
504.  	/* set up Priest and shrine */
505.  	sroom->rtype = TEMPLE;
506.  	/*
507.  	 * In temples, shrines are blessed altars
508.  	 * located in the center of the room
509.  	 */
510.  	shrine_spot = shrine_pos((sroom - rooms) + ROOMOFFSET);
511.  	lev = &levl[shrine_spot->x][shrine_spot->y];
512.  	lev->typ = ALTAR;
513.  	lev->altarmask = induced_align(80);
514.  	priestini(&u.uz, sroom, shrine_spot->x, shrine_spot->y, FALSE);
515.  	lev->altarmask |= AM_SHRINE;
516.  	level.flags.has_temple = 1;
517.  }
518.  

nexttodoor[]

519.  boolean
520.  nexttodoor(sx,sy)
521.  register int sx, sy;
522.  {
523.  	register int dx, dy;
524.  	register struct rm *lev;
525.  	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) {
526.  		if(!isok(sx+dx, sy+dy)) continue;
527.  		if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
528.  		    lev->typ == SDOOR)
529.  			return(TRUE);
530.  	}
531.  	return(FALSE);
532.  }
533.  

has_dnstairs[]

534.  boolean
535.  has_dnstairs(sroom)
536.  register struct mkroom *sroom;
537.  {
538.  	if (sroom == dnstairs_room)
539.  		return TRUE;
540.  	if (sstairs.sx && !sstairs.up)
541.  		return((boolean)(sroom == sstairs_room));
542.  	return FALSE;
543.  }
544.  

has_upstairs[]

545.  boolean
546.  has_upstairs(sroom)
547.  register struct mkroom *sroom;
548.  {
549.  	if (sroom == upstairs_room)
550.  		return TRUE;
551.  	if (sstairs.sx && sstairs.up)
552.  		return((boolean)(sroom == sstairs_room));
553.  	return FALSE;
554.  }
555.  
556.  #endif /* OVLB */
557.  #ifdef OVL0
558.  

somex[]

559.  int
560.  somex(croom)
561.  register struct mkroom *croom;
562.  {
563.  	return rn2(croom->hx-croom->lx+1) + croom->lx;
564.  }
565.  

somey[]

566.  int
567.  somey(croom)
568.  register struct mkroom *croom;
569.  {
570.  	return rn2(croom->hy-croom->ly+1) + croom->ly;
571.  }
572.  

inside_room[]

573.  boolean
574.  inside_room(croom, x, y)
575.  struct mkroom *croom;
576.  xchar x, y;
577.  {
578.  	return((boolean)(x >= croom->lx-1 && x <= croom->hx+1 &&
579.  		y >= croom->ly-1 && y <= croom->hy+1));
580.  }
581.  

somexy[]

582.  boolean
583.  somexy(croom, c)
584.  struct mkroom *croom;
585.  coord *c;
586.  {
587.  	int try_cnt = 0;
588.  	int i;
589.  
590.  	if (croom->irregular) {
591.  	    i = (croom - rooms) + ROOMOFFSET;
592.  
593.  	    while(try_cnt++ < 100) {
594.  		c->x = somex(croom);
595.  		c->y = somey(croom);
596.  		if (!levl[c->x][c->y].edge &&
597.  			(int) levl[c->x][c->y].roomno == i)
598.  		    return TRUE;
599.  	    }
600.  	    /* try harder; exhaustively search until one is found */
601.  	    for(c->x = croom->lx; c->x <= croom->hx; c->x++)
602.  		for(c->y = croom->ly; c->y <= croom->hy; c->y++)
603.  		    if (!levl[c->x][c->y].edge &&
604.  			    (int) levl[c->x][c->y].roomno == i)
605.  			return TRUE;
606.  	    return FALSE;
607.  	}
608.  
609.  	if (!croom->nsubrooms) {
610.  		c->x = somex(croom);
611.  		c->y = somey(croom);
612.  		return TRUE;
613.  	}
614.  
615.  	/* Check that coords doesn't fall into a subroom or into a wall */
616.  
617.  	while(try_cnt++ < 100) {
618.  		c->x = somex(croom);
619.  		c->y = somey(croom);
620.  		if (IS_WALL(levl[c->x][c->y].typ))
621.  		    continue;
622.  		for(i=0 ; i<croom->nsubrooms;i++)
623.  		    if(inside_room(croom->sbrooms[i], c->x, c->y))
624.  			goto you_lose;
625.  		break;
626.  you_lose:	;
627.  	}
628.  	if (try_cnt >= 100)
629.  	    return FALSE;
630.  	return TRUE;
631.  }
632.  

search_special[]

633.  /*
634.   * Search for a special room given its type (zoo, court, etc...)
635.   *	Special values :
636.   *		- ANY_SHOP
637.   *		- ANY_TYPE
638.   */
639.  
640.  struct mkroom *
641.  search_special(type)
642.  schar type;
643.  {
644.  	register struct mkroom *croom;
645.  
646.  	for(croom = &rooms[0]; croom->hx >= 0; croom++)
647.  	    if((type == ANY_TYPE && croom->rtype != OROOM) ||
648.  	       (type == ANY_SHOP && croom->rtype >= SHOPBASE) ||
649.  	       croom->rtype == type)
650.  		return croom;
651.  	for(croom = &subrooms[0]; croom->hx >= 0; croom++)
652.  	    if((type == ANY_TYPE && croom->rtype != OROOM) ||
653.  	       (type == ANY_SHOP && croom->rtype >= SHOPBASE) ||
654.  	       croom->rtype == type)
655.  		return croom;
656.  	return (struct mkroom *) 0;
657.  }
658.  
659.  #endif /* OVL0 */
660.  #ifdef OVLB
661.  

courtmon[]

662.  struct permonst *
663.  courtmon()
664.  {
665.  	int     i = rn2(60) + rn2(3*level_difficulty());
666.  	if (i > 100)		return(mkclass(S_DRAGON,0));
667.  	else if (i > 95)	return(mkclass(S_GIANT,0));
668.  	else if (i > 85)	return(mkclass(S_TROLL,0));
669.  	else if (i > 75)	return(mkclass(S_CENTAUR,0));
670.  	else if (i > 60)	return(mkclass(S_ORC,0));
671.  	else if (i > 45)	return(&mons[PM_BUGBEAR]);
672.  	else if (i > 30)	return(&mons[PM_HOBGOBLIN]);
673.  	else if (i > 15)	return(mkclass(S_GNOME,0));
674.  	else			return(mkclass(S_KOBOLD,0));
675.  }
676.  

squadmon[]

677.  #define NSTYPES (PM_CAPTAIN - PM_SOLDIER + 1)
678.  
679.  static struct {
680.      unsigned	pm;
681.      unsigned	prob;
682.  } squadprob[NSTYPES] = {
683.      {PM_SOLDIER, 80}, {PM_SERGEANT, 15}, {PM_LIEUTENANT, 4}, {PM_CAPTAIN, 1}
684.  };
685.  
686.  STATIC_OVL struct permonst *
687.  squadmon()		/* return soldier types. */
688.  {
689.  	int sel_prob, i, cpro, mndx;
690.  
691.  	sel_prob = rnd(80+level_difficulty());
692.  
693.  	cpro = 0;
694.  	for (i = 0; i < NSTYPES; i++) {
695.  	    cpro += squadprob[i].prob;
696.  	    if (cpro > sel_prob) {
697.  		mndx = squadprob[i].pm;
698.  		goto gotone;
699.  	    }
700.  	}
701.  	mndx = squadprob[rn2(NSTYPES)].pm;
702.  gotone:
703.  	if (!(mvitals[mndx].mvflags & G_GONE)) return(&mons[mndx]);
704.  	else			    return((struct permonst *) 0);
705.  }
706.  

save_room[]

707.  /*
708.   * save_room : A recursive function that saves a room and its subrooms
709.   * (if any).
710.   */
711.  
712.  STATIC_OVL void
713.  save_room(fd, r)
714.  int	fd;
715.  struct mkroom *r;
716.  {
717.  	short i;
718.  	/*
719.  	 * Well, I really should write only useful information instead
720.  	 * of writing the whole structure. That is I should not write
721.  	 * the subrooms pointers, but who cares ?
722.  	 */
723.  	bwrite(fd, (genericptr_t) r, sizeof(struct mkroom));
724.  	for(i=0; i<r->nsubrooms; i++)
725.  	    save_room(fd, r->sbrooms[i]);
726.  }
727.  

save_rooms[]

728.  /*
729.   * save_rooms : Save all the rooms on disk!
730.   */
731.  
732.  void
733.  save_rooms(fd)
734.  int fd;
735.  {
736.  	short i;
737.  
738.  	/* First, write the number of rooms */
739.  	bwrite(fd, (genericptr_t) &nroom, sizeof(nroom));
740.  	for(i=0; i<nroom; i++)
741.  	    save_room(fd, &rooms[i]);
742.  }
743.  

rest_room[]

744.  STATIC_OVL void
745.  rest_room(fd, r)
746.  int fd;
747.  struct mkroom *r;
748.  {
749.  	short i;
750.  
751.  	mread(fd, (genericptr_t) r, sizeof(struct mkroom));
752.  	for(i=0; i<r->nsubrooms; i++) {
753.  		r->sbrooms[i] = &subrooms[nsubroom];
754.  		rest_room(fd, &subrooms[nsubroom]);
755.  		subrooms[nsubroom++].resident = (struct monst *)0;
756.  	}
757.  }
758.  

rest_rooms[]

759.  /*
760.   * rest_rooms : That's for restoring rooms. Read the rooms structure from
761.   * the disk.
762.   */
763.  
764.  void
765.  rest_rooms(fd)
766.  int	fd;
767.  {
768.  	short i;
769.  
770.  	mread(fd, (genericptr_t) &nroom, sizeof(nroom));
771.  	nsubroom = 0;
772.  	for(i = 0; i<nroom; i++) {
773.  	    rest_room(fd, &rooms[i]);
774.  	    rooms[i].resident = (struct monst *)0;
775.  	}
776.  	rooms[nroom].hx = -1;		/* restore ending flags */
777.  	subrooms[nsubroom].hx = -1;
778.  }
779.  #endif /* OVLB */
780.  
781.  /*mkroom.c*/
Advertisement