hack.mkshop.c revision 1.2 1 1.1 cgd /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 1.1 cgd /* hack.mkshop.c - version 1.0.3 */
3 1.1 cgd
4 1.2 mycroft #include <stdlib.h>
5 1.1 cgd #ifndef QUEST
6 1.1 cgd #include "hack.h"
7 1.1 cgd #include "def.mkroom.h"
8 1.1 cgd #include "def.eshk.h"
9 1.1 cgd #define ESHK ((struct eshk *)(&(shk->mextra[0])))
10 1.1 cgd extern struct monst *makemon();
11 1.1 cgd extern struct obj *mkobj_at();
12 1.1 cgd extern int nroom;
13 1.1 cgd extern char shtypes[]; /* = "=/)%?!["; 8 types: 7 specialized, 1 mixed */
14 1.1 cgd schar shprobs[] = { 3,3,5,5,10,10,14,50 }; /* their probabilities */
15 1.1 cgd
16 1.1 cgd mkshop(){
17 1.1 cgd register struct mkroom *sroom;
18 1.1 cgd register int sh,sx,sy,i = -1;
19 1.1 cgd register char let;
20 1.1 cgd int roomno;
21 1.1 cgd register struct monst *shk;
22 1.1 cgd #ifdef WIZARD
23 1.1 cgd /* first determine shoptype */
24 1.1 cgd if(wizard){
25 1.1 cgd register char *ep = getenv("SHOPTYPE");
26 1.1 cgd if(ep){
27 1.1 cgd if(*ep == 'z' || *ep == 'Z'){
28 1.1 cgd mkzoo(ZOO);
29 1.1 cgd return;
30 1.1 cgd }
31 1.1 cgd if(*ep == 'm' || *ep == 'M'){
32 1.1 cgd mkzoo(MORGUE);
33 1.1 cgd return;
34 1.1 cgd }
35 1.1 cgd if(*ep == 'b' || *ep == 'B'){
36 1.1 cgd mkzoo(BEEHIVE);
37 1.1 cgd return;
38 1.1 cgd }
39 1.1 cgd if(*ep == 's' || *ep == 'S'){
40 1.1 cgd mkswamp();
41 1.1 cgd return;
42 1.1 cgd }
43 1.1 cgd for(i=0; shtypes[i]; i++)
44 1.1 cgd if(*ep == shtypes[i]) break;
45 1.1 cgd goto gottype;
46 1.1 cgd }
47 1.1 cgd }
48 1.1 cgd gottype:
49 1.1 cgd #endif WIZARD
50 1.1 cgd for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
51 1.1 cgd if(sroom->hx < 0) return;
52 1.1 cgd if(sroom - rooms >= nroom) {
53 1.1 cgd pline("rooms not closed by -1?");
54 1.1 cgd return;
55 1.1 cgd }
56 1.1 cgd if(sroom->rtype) continue;
57 1.1 cgd if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
58 1.1 cgd continue;
59 1.1 cgd if(
60 1.1 cgd #ifdef WIZARD
61 1.1 cgd (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
62 1.1 cgd #endif WIZARD
63 1.1 cgd sroom->doorct <= 2 && sroom->doorct > 0) break;
64 1.1 cgd }
65 1.1 cgd
66 1.1 cgd if(i < 0) { /* shoptype not yet determined */
67 1.1 cgd register int j;
68 1.1 cgd
69 1.1 cgd for(j = rn2(100), i = 0; (j -= shprobs[i])>= 0; i++)
70 1.1 cgd if(!shtypes[i]) break; /* superfluous */
71 1.1 cgd if(isbig(sroom) && i + SHOPBASE == WANDSHOP)
72 1.1 cgd i = GENERAL-SHOPBASE;
73 1.1 cgd }
74 1.1 cgd sroom->rtype = i + SHOPBASE;
75 1.1 cgd let = shtypes[i];
76 1.1 cgd sh = sroom->fdoor;
77 1.1 cgd sx = doors[sh].x;
78 1.1 cgd sy = doors[sh].y;
79 1.1 cgd if(sx == sroom->lx-1) sx++; else
80 1.1 cgd if(sx == sroom->hx+1) sx--; else
81 1.1 cgd if(sy == sroom->ly-1) sy++; else
82 1.1 cgd if(sy == sroom->hy+1) sy--; else {
83 1.1 cgd #ifdef WIZARD
84 1.1 cgd /* This is said to happen sometimes, but I've never seen it. */
85 1.1 cgd if(wizard) {
86 1.1 cgd register int j = sroom->doorct;
87 1.1 cgd extern int doorindex;
88 1.1 cgd
89 1.1 cgd pline("Where is shopdoor?");
90 1.1 cgd pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly,
91 1.1 cgd sroom->hx, sroom->hy);
92 1.1 cgd pline("doormax=%d doorct=%d fdoor=%d",
93 1.1 cgd doorindex, sroom->doorct, sh);
94 1.1 cgd while(j--) {
95 1.1 cgd pline("door [%d,%d]", doors[sh].x, doors[sh].y);
96 1.1 cgd sh++;
97 1.1 cgd }
98 1.1 cgd more();
99 1.1 cgd }
100 1.1 cgd #endif WIZARD
101 1.1 cgd return;
102 1.1 cgd }
103 1.1 cgd if(!(shk = makemon(PM_SHK,sx,sy))) return;
104 1.1 cgd shk->isshk = shk->mpeaceful = 1;
105 1.1 cgd shk->msleep = 0;
106 1.1 cgd shk->mtrapseen = ~0; /* we know all the traps already */
107 1.1 cgd ESHK->shoproom = roomno;
108 1.1 cgd ESHK->shoplevel = dlevel;
109 1.1 cgd ESHK->shd = doors[sh];
110 1.1 cgd ESHK->shk.x = sx;
111 1.1 cgd ESHK->shk.y = sy;
112 1.1 cgd ESHK->robbed = 0;
113 1.1 cgd ESHK->visitct = 0;
114 1.1 cgd ESHK->following = 0;
115 1.1 cgd shk->mgold = 1000 + 30*rnd(100); /* initial capital */
116 1.1 cgd ESHK->billct = 0;
117 1.1 cgd findname(ESHK->shknam, let);
118 1.1 cgd for(sx = sroom->lx; sx <= sroom->hx; sx++)
119 1.1 cgd for(sy = sroom->ly; sy <= sroom->hy; sy++){
120 1.1 cgd register struct monst *mtmp;
121 1.1 cgd if((sx == sroom->lx && doors[sh].x == sx-1) ||
122 1.1 cgd (sx == sroom->hx && doors[sh].x == sx+1) ||
123 1.1 cgd (sy == sroom->ly && doors[sh].y == sy-1) ||
124 1.1 cgd (sy == sroom->hy && doors[sh].y == sy+1)) continue;
125 1.1 cgd if(rn2(100) < dlevel && !m_at(sx,sy) &&
126 1.1 cgd (mtmp = makemon(PM_MIMIC, sx, sy))){
127 1.1 cgd mtmp->mimic = 1;
128 1.1 cgd mtmp->mappearance =
129 1.1 cgd (let && rn2(10) < dlevel) ? let : ']';
130 1.1 cgd continue;
131 1.1 cgd }
132 1.1 cgd (void) mkobj_at(let, sx, sy);
133 1.1 cgd }
134 1.1 cgd }
135 1.1 cgd
136 1.1 cgd mkzoo(type)
137 1.1 cgd int type;
138 1.1 cgd {
139 1.1 cgd register struct mkroom *sroom;
140 1.1 cgd register struct monst *mon;
141 1.1 cgd register int sh,sx,sy,i;
142 1.1 cgd int goldlim = 500 * dlevel;
143 1.1 cgd int moct = 0;
144 1.1 cgd struct permonst *morguemon();
145 1.1 cgd
146 1.1 cgd i = nroom;
147 1.1 cgd for(sroom = &rooms[rn2(nroom)]; ; sroom++) {
148 1.1 cgd if(sroom == &rooms[nroom])
149 1.1 cgd sroom = &rooms[0];
150 1.1 cgd if(!i-- || sroom->hx < 0)
151 1.1 cgd return;
152 1.1 cgd if(sroom->rtype)
153 1.1 cgd continue;
154 1.1 cgd if(type == MORGUE && sroom->rlit)
155 1.1 cgd continue;
156 1.1 cgd if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
157 1.1 cgd continue;
158 1.1 cgd if(sroom->doorct == 1 || !rn2(5))
159 1.1 cgd break;
160 1.1 cgd }
161 1.1 cgd sroom->rtype = type;
162 1.1 cgd sh = sroom->fdoor;
163 1.1 cgd for(sx = sroom->lx; sx <= sroom->hx; sx++)
164 1.1 cgd for(sy = sroom->ly; sy <= sroom->hy; sy++){
165 1.1 cgd if((sx == sroom->lx && doors[sh].x == sx-1) ||
166 1.1 cgd (sx == sroom->hx && doors[sh].x == sx+1) ||
167 1.1 cgd (sy == sroom->ly && doors[sh].y == sy-1) ||
168 1.1 cgd (sy == sroom->hy && doors[sh].y == sy+1)) continue;
169 1.1 cgd mon = makemon(
170 1.1 cgd (type == MORGUE) ? morguemon() :
171 1.1 cgd (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0,
172 1.1 cgd sx, sy);
173 1.1 cgd if(mon) mon->msleep = 1;
174 1.1 cgd switch(type) {
175 1.1 cgd case ZOO:
176 1.1 cgd i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
177 1.1 cgd if(i >= goldlim) i = 5*dlevel;
178 1.1 cgd goldlim -= i;
179 1.1 cgd mkgold((long)(10 + rn2(i)), sx, sy);
180 1.1 cgd break;
181 1.1 cgd case MORGUE:
182 1.1 cgd /* Usually there is one dead body in the morgue */
183 1.1 cgd if(!moct && rn2(3)) {
184 1.1 cgd mksobj_at(CORPSE, sx, sy);
185 1.1 cgd moct++;
186 1.1 cgd }
187 1.1 cgd break;
188 1.1 cgd case BEEHIVE:
189 1.1 cgd if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
190 1.1 cgd break;
191 1.1 cgd }
192 1.1 cgd }
193 1.1 cgd }
194 1.1 cgd
195 1.1 cgd struct permonst *
196 1.1 cgd morguemon()
197 1.1 cgd {
198 1.1 cgd extern struct permonst pm_ghost;
199 1.1 cgd register int i = rn2(100), hd = rn2(dlevel);
200 1.1 cgd
201 1.1 cgd if(hd > 10 && i < 10) return(PM_DEMON);
202 1.1 cgd if(hd > 8 && i > 85) return(PM_VAMPIRE);
203 1.1 cgd return((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE);
204 1.1 cgd }
205 1.1 cgd
206 1.1 cgd mkswamp() /* Michiel Huisjes & Fred de Wilde */
207 1.1 cgd {
208 1.1 cgd register struct mkroom *sroom;
209 1.1 cgd register int sx,sy,i,eelct = 0;
210 1.1 cgd extern struct permonst pm_eel;
211 1.1 cgd
212 1.1 cgd for(i=0; i<5; i++) { /* 5 tries */
213 1.1 cgd sroom = &rooms[rn2(nroom)];
214 1.1 cgd if(sroom->hx < 0 || sroom->rtype ||
215 1.1 cgd has_upstairs(sroom) || has_dnstairs(sroom))
216 1.1 cgd continue;
217 1.1 cgd
218 1.1 cgd /* satisfied; make a swamp */
219 1.1 cgd sroom->rtype = SWAMP;
220 1.1 cgd for(sx = sroom->lx; sx <= sroom->hx; sx++)
221 1.1 cgd for(sy = sroom->ly; sy <= sroom->hy; sy++)
222 1.1 cgd if((sx+sy)%2 && !o_at(sx,sy) && !t_at(sx,sy)
223 1.1 cgd && !m_at(sx,sy) && !nexttodoor(sx,sy)){
224 1.1 cgd levl[sx][sy].typ = POOL;
225 1.1 cgd levl[sx][sy].scrsym = POOL_SYM;
226 1.1 cgd if(!eelct || !rn2(4)) {
227 1.1 cgd (void) makemon(PM_EEL, sx, sy);
228 1.1 cgd eelct++;
229 1.1 cgd }
230 1.1 cgd }
231 1.1 cgd }
232 1.1 cgd }
233 1.1 cgd
234 1.1 cgd nexttodoor(sx,sy)
235 1.1 cgd register sx,sy;
236 1.1 cgd {
237 1.1 cgd register dx,dy;
238 1.1 cgd register struct rm *lev;
239 1.1 cgd for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
240 1.1 cgd if((lev = &levl[sx+dx][sy+dy])->typ == DOOR ||
241 1.1 cgd lev->typ == SDOOR || lev->typ == LDOOR)
242 1.1 cgd return(1);
243 1.1 cgd return(0);
244 1.1 cgd }
245 1.1 cgd
246 1.1 cgd has_dnstairs(sroom)
247 1.1 cgd register struct mkroom *sroom;
248 1.1 cgd {
249 1.1 cgd return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
250 1.1 cgd sroom->ly <= ydnstair && ydnstair <= sroom->hy);
251 1.1 cgd }
252 1.1 cgd
253 1.1 cgd has_upstairs(sroom)
254 1.1 cgd register struct mkroom *sroom;
255 1.1 cgd {
256 1.1 cgd return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
257 1.1 cgd sroom->ly <= yupstair && yupstair <= sroom->hy);
258 1.1 cgd }
259 1.1 cgd
260 1.1 cgd isbig(sroom)
261 1.1 cgd register struct mkroom *sroom;
262 1.1 cgd {
263 1.1 cgd register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
264 1.1 cgd return( area > 20 );
265 1.1 cgd }
266 1.1 cgd
267 1.1 cgd dist2(x0,y0,x1,y1){
268 1.1 cgd return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
269 1.1 cgd }
270 1.1 cgd
271 1.1 cgd sq(a) int a; {
272 1.1 cgd return(a*a);
273 1.1 cgd }
274 1.1 cgd #endif QUEST
275