1 /*        $NetBSD: hack.mkmaze.c,v 1.8 2009/08/12 07:28:41 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.8 2009/08/12 07:28:41 dholland Exp $");
67 #endif                                  /* not lint */
68 
69 #include "hack.h"
70 #include "extern.h"
71 #include "def.mkroom.h"                 /* not really used */
72 
73 static const struct permonst hell_hound =
74 {"hell hound", 'd', 12, 14, 2, 3, 6, 0};
75 
76 static void walkfrom(int, int);
77 static void move(int *, int *, int);
78 static int okay(int, int, int);
79 
80 void
makemaz(void)81 makemaz(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 
159 static void
walkfrom(int x,int y)160 walkfrom(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 
180 static void
move(int * x,int * y,int dir)181 move(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 
199 static int
okay(int x,int y,int dir)200 okay(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 
210 coord
mazexy(void)211 mazexy(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