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