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);
31 /* first determine shoptype */
33 char *ep
= getenv("SHOPTYPE");
35 if(*ep
== 'z' || *ep
== 'Z'){
39 if(*ep
== 'm' || *ep
== 'M'){
43 if(*ep
== 'b' || *ep
== 'B'){
47 if(*ep
== 's' || *ep
== 'S'){
51 for(i
=0; shtypes
[i
]; i
++)
52 if(*ep
== shtypes
[i
]) break;
58 for(sroom
= &rooms
[0], roomno
= 0; ; sroom
++, roomno
++){
59 if(sroom
->hx
< 0) return;
60 if(sroom
- rooms
>= nroom
) {
61 pline("rooms not closed by -1?");
64 if(sroom
->rtype
) continue;
65 if(!sroom
->rlit
|| has_dnstairs(sroom
) || has_upstairs(sroom
))
69 ((wizard
&& getenv("SHOPTYPE") && sroom
->doorct
!= 0)) ||
71 (sroom
->doorct
<= 2 && sroom
->doorct
> 0)) break;
74 if(i
< 0) { /* shoptype not yet determined */
77 for(j
= rn2(100), i
= 0; (j
-= shprobs
[i
])>= 0; i
++)
78 if(!shtypes
[i
]) break; /* superfluous */
79 if(isbig(sroom
) && i
+ SHOPBASE
== WANDSHOP
)
82 sroom
->rtype
= i
+ SHOPBASE
;
87 if(sx
== sroom
->lx
-1) sx
++; else
88 if(sx
== sroom
->hx
+1) sx
--; else
89 if(sy
== sroom
->ly
-1) sy
++; else
90 if(sy
== sroom
->hy
+1) sy
--; else {
92 /* This is said to happen sometimes, but I've never seen it. */
94 int j
= sroom
->doorct
;
96 pline("Where is shopdoor?");
97 pline("Room at (%d,%d),(%d,%d).", sroom
->lx
, sroom
->ly
,
98 sroom
->hx
, sroom
->hy
);
99 pline("doormax=%d doorct=%d fdoor=%d",
100 doorindex
, sroom
->doorct
, sh
);
102 pline("door [%d,%d]", doors
[sh
].x
, doors
[sh
].y
);
110 if(!(shk
= makemon(PM_SHK
,sx
,sy
))) return;
111 shk
->isshk
= shk
->mpeaceful
= 1;
113 shk
->mtrapseen
= ~0; /* we know all the traps already */
114 ESHK
->shoproom
= roomno
;
115 ESHK
->shoplevel
= dlevel
;
116 ESHK
->shd
= doors
[sh
];
122 shk
->mgold
= 1000 + 30*rnd(100); /* initial capital */
124 findname(ESHK
->shknam
, let
);
125 for(sx
= sroom
->lx
; sx
<= sroom
->hx
; sx
++)
126 for(sy
= sroom
->ly
; sy
<= sroom
->hy
; sy
++){
128 if((sx
== sroom
->lx
&& doors
[sh
].x
== sx
-1) ||
129 (sx
== sroom
->hx
&& doors
[sh
].x
== sx
+1) ||
130 (sy
== sroom
->ly
&& doors
[sh
].y
== sy
-1) ||
131 (sy
== sroom
->hy
&& doors
[sh
].y
== sy
+1)) continue;
132 if(rn2(100) < dlevel
&& !m_at(sx
,sy
) &&
133 (mtmp
= makemon(PM_MIMIC
, sx
, sy
))){
136 (let
&& rn2(10) < dlevel
) ? let
: ']';
139 mkobj_at(let
, sx
, sy
);
146 struct mkroom
*sroom
;
149 int goldlim
= 500 * dlevel
;
153 for(sroom
= &rooms
[rn2(nroom
)]; ; sroom
++) {
154 if(sroom
== &rooms
[nroom
])
156 if(!i
-- || sroom
->hx
< 0)
160 if(type
== MORGUE
&& sroom
->rlit
)
162 if(has_upstairs(sroom
) || (has_dnstairs(sroom
) && rn2(3)))
164 if(sroom
->doorct
== 1 || !rn2(5))
169 for(sx
= sroom
->lx
; sx
<= sroom
->hx
; sx
++)
170 for(sy
= sroom
->ly
; sy
<= sroom
->hy
; sy
++){
171 if((sx
== sroom
->lx
&& doors
[sh
].x
== sx
-1) ||
172 (sx
== sroom
->hx
&& doors
[sh
].x
== sx
+1) ||
173 (sy
== sroom
->ly
&& doors
[sh
].y
== sy
-1) ||
174 (sy
== sroom
->hy
&& doors
[sh
].y
== sy
+1)) continue;
176 (type
== MORGUE
) ? morguemon() :
177 (type
== BEEHIVE
) ? PM_KILLER_BEE
: (struct permonst
*) 0,
179 if(mon
) mon
->msleep
= 1;
182 i
= sq(dist2(sx
,sy
,doors
[sh
].x
,doors
[sh
].y
));
183 if(i
>= goldlim
) i
= 5*dlevel
;
185 mkgold((long)(10 + rn2(i
)), sx
, sy
);
188 /* Usually there is one dead body in the morgue */
189 if(!moct
&& rn2(3)) {
190 mksobj_at(CORPSE
, sx
, sy
);
195 if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY
, sx
, sy
);
201 static struct permonst
*
204 int i
= rn2(100), hd
= rn2(dlevel
);
206 if(hd
> 10 && i
< 10) return(PM_DEMON
);
207 if(hd
> 8 && i
> 85) return(PM_VAMPIRE
);
208 return((i
< 40) ? PM_GHOST
: (i
< 60) ? PM_WRAITH
: PM_ZOMBIE
);
212 mkswamp(void) /* Michiel Huisjes & Fred de Wilde */
214 struct mkroom
*sroom
;
215 int sx
,sy
,i
,eelct
= 0;
217 for(i
=0; i
<5; i
++) { /* 5 tries */
218 sroom
= &rooms
[rn2(nroom
)];
219 if(sroom
->hx
< 0 || sroom
->rtype
||
220 has_upstairs(sroom
) || has_dnstairs(sroom
))
223 /* satisfied; make a swamp */
224 sroom
->rtype
= SWAMP
;
225 for(sx
= sroom
->lx
; sx
<= sroom
->hx
; sx
++)
226 for(sy
= sroom
->ly
; sy
<= sroom
->hy
; sy
++)
227 if((sx
+sy
)%2 && !o_at(sx
,sy
) && !t_at(sx
,sy
)
228 && !m_at(sx
,sy
) && !nexttodoor(sx
,sy
)){
229 levl
[sx
][sy
].typ
= POOL
;
230 levl
[sx
][sy
].scrsym
= POOL_SYM
;
231 if(!eelct
|| !rn2(4)) {
232 makemon(PM_EEL
, sx
, sy
);
240 nexttodoor(int sx
, int sy
)
244 for(dx
= -1; dx
<= 1; dx
++) for(dy
= -1; dy
<= 1; dy
++)
245 if((lev
= &levl
[sx
+dx
][sy
+dy
])->typ
== DOOR
||
246 lev
->typ
== SDOOR
|| lev
->typ
== LDOOR
)
252 has_dnstairs(struct mkroom
*sroom
)
254 return(sroom
->lx
<= xdnstair
&& xdnstair
<= sroom
->hx
&&
255 sroom
->ly
<= ydnstair
&& ydnstair
<= sroom
->hy
);
259 has_upstairs(struct mkroom
*sroom
)
261 return(sroom
->lx
<= xupstair
&& xupstair
<= sroom
->hx
&&
262 sroom
->ly
<= yupstair
&& yupstair
<= sroom
->hy
);
266 isbig(struct mkroom
*sroom
)
268 int area
= (sroom
->hx
- sroom
->lx
) * (sroom
->hy
- sroom
->ly
);
273 dist2(int x0
, int y0
, int x1
, int y1
)
275 return((x0
-x1
)*(x0
-x1
) + (y0
-y1
)*(y0
-y1
));