1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.mkshop.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.mkshop.c,v 1.4 1999/11/16 10:26:37 marcel Exp $ */
4 /* $DragonFly: src/games/hack/hack.mkshop.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
9 #define ESHK ((struct eshk *)(&(shk->mextra[0])))
11 extern char shtypes
[]; /* = "=/)%?!["; 8 types: 7 specialized, 1 mixed */
12 schar shprobs
[] = { 3,3,5,5,10,10,14,50 }; /* their probabilities */
14 static struct permonst
*morguemon(void);
15 static bool nexttodoor(int, int);
16 static bool has_dnstairs(struct mkroom
*);
17 static bool has_upstairs(struct mkroom
*);
18 static bool isbig(struct mkroom
*);
19 static int dist2(int, int, int, int);
26 int sh
, sx
, sy
, i
= -1;
32 /* first determine shoptype */
34 char *ep
= getenv("SHOPTYPE");
36 if (*ep
== 'z' || *ep
== 'Z') {
40 if (*ep
== 'm' || *ep
== 'M') {
44 if (*ep
== 'b' || *ep
== 'B') {
48 if (*ep
== 's' || *ep
== 'S') {
52 for (i
= 0; shtypes
[i
]; i
++)
53 if (*ep
== shtypes
[i
])
60 for (sroom
= &rooms
[0], roomno
= 0;; sroom
++, roomno
++) {
63 if (sroom
- rooms
>= nroom
) {
64 pline("rooms not closed by -1?");
69 if (!sroom
->rlit
|| has_dnstairs(sroom
) || has_upstairs(sroom
))
73 (wizard
&& getenv("SHOPTYPE") && sroom
->doorct
!= 0) ||
75 (sroom
->doorct
<= 2 && sroom
->doorct
> 0))
79 if (i
< 0) { /* shoptype not yet determined */
82 for (j
= rn2(100), i
= 0; (j
-= shprobs
[i
]) >= 0; i
++)
83 if (!shtypes
[i
]) /* superfluous */
85 if (isbig(sroom
) && i
+ SHOPBASE
== WANDSHOP
)
86 i
= GENERAL
- SHOPBASE
;
88 sroom
->rtype
= i
+ SHOPBASE
;
93 if (sx
== sroom
->lx
- 1)
95 else if (sx
== sroom
->hx
+ 1)
97 else if (sy
== sroom
->ly
- 1)
99 else if (sy
== sroom
->hy
+ 1)
103 /* This is said to happen sometimes, but I've never seen it. */
105 int j
= sroom
->doorct
;
107 pline("Where is shopdoor?");
108 pline("Room at (%d,%d),(%d,%d).", sroom
->lx
, sroom
->ly
,
109 sroom
->hx
, sroom
->hy
);
110 pline("doormax=%d doorct=%d fdoor=%d",
111 doorindex
, sroom
->doorct
, sh
);
113 pline("door [%d,%d]", doors
[sh
].x
, doors
[sh
].y
);
121 if (!(shk
= makemon(PM_SHK
, sx
, sy
)))
123 shk
->isshk
= shk
->mpeaceful
= 1;
125 shk
->mtrapseen
= ~0; /* we know all the traps already */
126 ESHK
->shoproom
= roomno
;
127 ESHK
->shoplevel
= dlevel
;
128 ESHK
->shd
= doors
[sh
];
134 shk
->mgold
= 1000 + 30 * rnd(100); /* initial capital */
136 findname(ESHK
->shknam
, let
);
137 for (sx
= sroom
->lx
; sx
<= sroom
->hx
; sx
++)
138 for (sy
= sroom
->ly
; sy
<= sroom
->hy
; sy
++) {
140 if ((sx
== sroom
->lx
&& doors
[sh
].x
== sx
- 1) ||
141 (sx
== sroom
->hx
&& doors
[sh
].x
== sx
+ 1) ||
142 (sy
== sroom
->ly
&& doors
[sh
].y
== sy
- 1) ||
143 (sy
== sroom
->hy
&& doors
[sh
].y
== sy
+ 1))
145 if (rn2(100) < dlevel
&& !m_at(sx
, sy
) &&
146 (mtmp
= makemon(PM_MIMIC
, sx
, sy
))) {
149 (let
&& rn2(10) < dlevel
) ? let
: ']';
152 mkobj_at(let
, sx
, sy
);
159 struct mkroom
*sroom
;
162 int goldlim
= 500 * dlevel
;
166 for (sroom
= &rooms
[rn2(nroom
)];; sroom
++) {
167 if (sroom
== &rooms
[nroom
])
169 if (!i
-- || sroom
->hx
< 0)
173 if (type
== MORGUE
&& sroom
->rlit
)
175 if (has_upstairs(sroom
) || (has_dnstairs(sroom
) && rn2(3)))
177 if (sroom
->doorct
== 1 || !rn2(5))
182 for (sx
= sroom
->lx
; sx
<= sroom
->hx
; sx
++)
183 for (sy
= sroom
->ly
; sy
<= sroom
->hy
; sy
++) {
184 if ((sx
== sroom
->lx
&& doors
[sh
].x
== sx
- 1) ||
185 (sx
== sroom
->hx
&& doors
[sh
].x
== sx
+ 1) ||
186 (sy
== sroom
->ly
&& doors
[sh
].y
== sy
- 1) ||
187 (sy
== sroom
->hy
&& doors
[sh
].y
== sy
+ 1))
190 (type
== MORGUE
) ? morguemon() :
191 (type
== BEEHIVE
) ? PM_KILLER_BEE
: NULL
,
197 i
= sq(dist2(sx
, sy
, doors
[sh
].x
, doors
[sh
].y
));
201 mkgold((long)(10 + rn2(i
)), sx
, sy
);
204 /* Usually there is one dead body in the morgue */
205 if (!moct
&& rn2(3)) {
206 mksobj_at(CORPSE
, sx
, sy
);
212 mksobj_at(LUMP_OF_ROYAL_JELLY
, sx
, sy
);
218 static struct permonst
*
221 int i
= rn2(100), hd
= rn2(dlevel
);
223 if (hd
> 10 && i
< 10)
225 if (hd
> 8 && i
> 85)
227 return ((i
< 40) ? PM_GHOST
: (i
< 60) ? PM_WRAITH
: PM_ZOMBIE
);
231 mkswamp(void) /* Michiel Huisjes & Fred de Wilde */
233 struct mkroom
*sroom
;
234 int sx
, sy
, i
, eelct
= 0;
236 for (i
= 0; i
< 5; i
++) { /* 5 tries */
237 sroom
= &rooms
[rn2(nroom
)];
238 if (sroom
->hx
< 0 || sroom
->rtype
||
239 has_upstairs(sroom
) || has_dnstairs(sroom
))
242 /* satisfied; make a swamp */
243 sroom
->rtype
= SWAMP
;
244 for (sx
= sroom
->lx
; sx
<= sroom
->hx
; sx
++)
245 for (sy
= sroom
->ly
; sy
<= sroom
->hy
; sy
++)
246 if ((sx
+ sy
) % 2 && !o_at(sx
, sy
) &&
247 !t_at(sx
, sy
) && !m_at(sx
, sy
) &&
248 !nexttodoor(sx
, sy
)) {
249 levl
[sx
][sy
].typ
= POOL
;
250 levl
[sx
][sy
].scrsym
= POOL_SYM
;
251 if (!eelct
|| !rn2(4)) {
252 makemon(PM_EEL
, sx
, sy
);
260 nexttodoor(int sx
, int sy
)
264 for (dx
= -1; dx
<= 1; dx
++)
265 for (dy
= -1; dy
<= 1; dy
++)
266 if ((lev
= &levl
[sx
+ dx
][sy
+ dy
])->typ
== DOOR
||
267 lev
->typ
== SDOOR
|| lev
->typ
== LDOOR
)
273 has_dnstairs(struct mkroom
*sroom
)
275 return (sroom
->lx
<= xdnstair
&& xdnstair
<= sroom
->hx
&&
276 sroom
->ly
<= ydnstair
&& ydnstair
<= sroom
->hy
);
280 has_upstairs(struct mkroom
*sroom
)
282 return (sroom
->lx
<= xupstair
&& xupstair
<= sroom
->hx
&&
283 sroom
->ly
<= yupstair
&& yupstair
<= sroom
->hy
);
287 isbig(struct mkroom
*sroom
)
289 int area
= (sroom
->hx
- sroom
->lx
) * (sroom
->hy
- sroom
->ly
);
294 dist2(int x0
, int y0
, int x1
, int y1
)
296 return ((x0
- x1
) * (x0
- x1
) + (y0
- y1
) * (y0
- y1
));