1/*	$NetBSD: hack.mkmaze.c,v 1.7 2009/06/07 18:30:39 dholland Exp $	*/
2
3/*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37/*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 *    notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 *    notice, this list of conditions and the following disclaimer in the
48 *    documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 *    derived from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64#include <sys/cdefs.h>
65#ifndef lint
66__RCSID("$NetBSD: hack.mkmaze.c,v 1.7 2009/06/07 18:30:39 dholland Exp $");
67#endif				/* not lint */
68
69#include "hack.h"
70#include "extern.h"
71#include "def.mkroom.h"		/* not really used */
72
73static const struct permonst hell_hound =
74{"hell hound", 'd', 12, 14, 2, 3, 6, 0};
75
76static void walkfrom(int, int);
77static void move(int *, int *, int);
78static int okay(int, int, int);
79
80void
81makemaz(void)
82{
83	int             x, y;
84	int		zx, zy;
85	coord           mm;
86	boolean         al = (dlevel >= 30 && !flags.made_amulet);
87
88	for (x = 2; x < COLNO - 1; x++)
89		for (y = 2; y < ROWNO - 1; y++)
90			levl[x][y].typ = (x % 2 && y % 2) ? 0 : HWALL;
91	if (al) {
92		struct monst   *mtmp;
93
94		zx = 2 * (COLNO / 4) - 1;
95		zy = 2 * (ROWNO / 4) - 1;
96		for (x = zx - 2; x < zx + 4; x++)
97			for (y = zy - 2; y <= zy + 2; y++) {
98				levl[x][y].typ =
99					(y == zy - 2 || y == zy + 2 || x == zx - 2 || x == zx + 3) ? POOL :
100					(y == zy - 1 || y == zy + 1 || x == zx - 1 || x == zx + 2) ? HWALL :
101					ROOM;
102			}
103		(void) mkobj_at(AMULET_SYM, zx, zy);
104		flags.made_amulet = 1;
105		walkfrom(zx + 4, zy);
106		if ((mtmp = makemon(&hell_hound, zx, zy)) != NULL)
107			mtmp->msleep = 1;
108		if ((mtmp = makemon(PM_WIZARD, zx + 1, zy)) != NULL) {
109			mtmp->msleep = 1;
110			flags.no_of_wizards = 1;
111		}
112	} else {
113		mm = mazexy();
114		zx = mm.x;
115		zy = mm.y;
116		walkfrom(zx, zy);
117		(void) mksobj_at(WAN_WISHING, zx, zy);
118		(void) mkobj_at(ROCK_SYM, zx, zy);	/* put a rock on top of
119							 * it */
120	}
121
122	for (x = 2; x < COLNO - 1; x++)
123		for (y = 2; y < ROWNO - 1; y++) {
124			switch (levl[x][y].typ) {
125			case HWALL:
126				levl[x][y].scrsym = '-';
127				break;
128			case ROOM:
129				levl[x][y].scrsym = '.';
130				break;
131			}
132		}
133	for (x = rn1(8, 11); x; x--) {
134		mm = mazexy();
135		(void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y);
136	}
137	for (x = rn1(10, 2); x; x--) {
138		mm = mazexy();
139		(void) mkobj_at(ROCK_SYM, mm.x, mm.y);
140	}
141	mm = mazexy();
142	(void) makemon(PM_MINOTAUR, mm.x, mm.y);
143	for (x = rn1(5, 7); x; x--) {
144		mm = mazexy();
145		(void) makemon((struct permonst *) 0, mm.x, mm.y);
146	}
147	for (x = rn1(6, 7); x; x--) {
148		mm = mazexy();
149		mkgold(0L, mm.x, mm.y);
150	}
151	for (x = rn1(6, 7); x; x--)
152		mktrap(0, 1, (struct mkroom *) 0);
153	mm = mazexy();
154	levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = '<';
155	levl[xupstair][yupstair].typ = STAIRS;
156	xdnstair = ydnstair = 0;
157}
158
159static void
160walkfrom(int x, int y)
161{
162	int             q, a, dir;
163	int             dirs[4];
164	levl[x][y].typ = ROOM;
165	while (1) {
166		q = 0;
167		for (a = 0; a < 4; a++)
168			if (okay(x, y, a))
169				dirs[q++] = a;
170		if (!q)
171			return;
172		dir = dirs[rn2(q)];
173		move(&x, &y, dir);
174		levl[x][y].typ = ROOM;
175		move(&x, &y, dir);
176		walkfrom(x, y);
177	}
178}
179
180static void
181move(int *x, int *y, int dir)
182{
183	switch (dir) {
184	case 0:
185		--(*y);
186		break;
187	case 1:
188		(*x)++;
189		break;
190	case 2:
191		(*y)++;
192		break;
193	case 3:
194		--(*x);
195		break;
196	}
197}
198
199static int
200okay(int x, int y, int dir)
201{
202	move(&x, &y, dir);
203	move(&x, &y, dir);
204	if (x < 3 || y < 3 || x > COLNO - 3 || y > ROWNO - 3 || levl[x][y].typ != 0)
205		return (0);
206	else
207		return (1);
208}
209
210coord
211mazexy(void)
212{
213	coord           mm;
214	mm.x = 3 + 2 * rn2(COLNO / 2 - 2);
215	mm.y = 3 + 2 * rn2(ROWNO / 2 - 2);
216	return mm;
217}
218