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 $ */ 5 6 #ifndef QUEST 7 #include "hack.h" 8 #include "def.eshk.h" 9 #define ESHK ((struct eshk *)(&(shk->mextra[0]))) 10 extern int nroom; 11 extern char shtypes[]; /* = "=/)%?!["; 8 types: 7 specialized, 1 mixed */ 12 schar shprobs[] = { 3,3,5,5,10,10,14,50 }; /* their probabilities */ 13 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); 20 static int sq(int); 21 22 void 23 mkshop(void) 24 { 25 struct mkroom *sroom; 26 int sh,sx,sy,i = -1; 27 char let; 28 int roomno; 29 struct monst *shk; 30 #ifdef WIZARD 31 /* first determine shoptype */ 32 if(wizard){ 33 char *ep = getenv("SHOPTYPE"); 34 if(ep){ 35 if(*ep == 'z' || *ep == 'Z'){ 36 mkzoo(ZOO); 37 return; 38 } 39 if(*ep == 'm' || *ep == 'M'){ 40 mkzoo(MORGUE); 41 return; 42 } 43 if(*ep == 'b' || *ep == 'B'){ 44 mkzoo(BEEHIVE); 45 return; 46 } 47 if(*ep == 's' || *ep == 'S'){ 48 mkswamp(); 49 return; 50 } 51 for(i=0; shtypes[i]; i++) 52 if(*ep == shtypes[i]) break; 53 goto gottype; 54 } 55 } 56 gottype: 57 #endif /* WIZARD */ 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?"); 62 return; 63 } 64 if(sroom->rtype) continue; 65 if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) 66 continue; 67 if( 68 #ifdef WIZARD 69 ((wizard && getenv("SHOPTYPE") && sroom->doorct != 0)) || 70 #endif /* WIZARD */ 71 (sroom->doorct <= 2 && sroom->doorct > 0)) break; 72 } 73 74 if(i < 0) { /* shoptype not yet determined */ 75 int j; 76 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) 80 i = GENERAL-SHOPBASE; 81 } 82 sroom->rtype = i + SHOPBASE; 83 let = shtypes[i]; 84 sh = sroom->fdoor; 85 sx = doors[sh].x; 86 sy = doors[sh].y; 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 { 91 #ifdef WIZARD 92 /* This is said to happen sometimes, but I've never seen it. */ 93 if(wizard) { 94 int j = sroom->doorct; 95 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); 101 while(j--) { 102 pline("door [%d,%d]", doors[sh].x, doors[sh].y); 103 sh++; 104 } 105 more(); 106 } 107 #endif /* WIZARD */ 108 return; 109 } 110 if(!(shk = makemon(PM_SHK,sx,sy))) return; 111 shk->isshk = shk->mpeaceful = 1; 112 shk->msleep = 0; 113 shk->mtrapseen = ~0; /* we know all the traps already */ 114 ESHK->shoproom = roomno; 115 ESHK->shoplevel = dlevel; 116 ESHK->shd = doors[sh]; 117 ESHK->shk.x = sx; 118 ESHK->shk.y = sy; 119 ESHK->robbed = 0; 120 ESHK->visitct = 0; 121 ESHK->following = 0; 122 shk->mgold = 1000 + 30*rnd(100); /* initial capital */ 123 ESHK->billct = 0; 124 findname(ESHK->shknam, let); 125 for(sx = sroom->lx; sx <= sroom->hx; sx++) 126 for(sy = sroom->ly; sy <= sroom->hy; sy++){ 127 struct monst *mtmp; 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))){ 134 mtmp->mimic = 1; 135 mtmp->mappearance = 136 (let && rn2(10) < dlevel) ? let : ']'; 137 continue; 138 } 139 mkobj_at(let, sx, sy); 140 } 141 } 142 143 void 144 mkzoo(int type) 145 { 146 struct mkroom *sroom; 147 struct monst *mon; 148 int sh,sx,sy,i; 149 int goldlim = 500 * dlevel; 150 int moct = 0; 151 152 i = nroom; 153 for(sroom = &rooms[rn2(nroom)]; ; sroom++) { 154 if(sroom == &rooms[nroom]) 155 sroom = &rooms[0]; 156 if(!i-- || sroom->hx < 0) 157 return; 158 if(sroom->rtype) 159 continue; 160 if(type == MORGUE && sroom->rlit) 161 continue; 162 if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 163 continue; 164 if(sroom->doorct == 1 || !rn2(5)) 165 break; 166 } 167 sroom->rtype = type; 168 sh = sroom->fdoor; 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; 175 mon = makemon( 176 (type == MORGUE) ? morguemon() : 177 (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, 178 sx, sy); 179 if(mon) mon->msleep = 1; 180 switch(type) { 181 case ZOO: 182 i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y)); 183 if(i >= goldlim) i = 5*dlevel; 184 goldlim -= i; 185 mkgold((long)(10 + rn2(i)), sx, sy); 186 break; 187 case MORGUE: 188 /* Usually there is one dead body in the morgue */ 189 if(!moct && rn2(3)) { 190 mksobj_at(CORPSE, sx, sy); 191 moct++; 192 } 193 break; 194 case BEEHIVE: 195 if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); 196 break; 197 } 198 } 199 } 200 201 static struct permonst * 202 morguemon(void) 203 { 204 int i = rn2(100), hd = rn2(dlevel); 205 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); 209 } 210 211 void 212 mkswamp(void) /* Michiel Huisjes & Fred de Wilde */ 213 { 214 struct mkroom *sroom; 215 int sx,sy,i,eelct = 0; 216 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)) 221 continue; 222 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); 233 eelct++; 234 } 235 } 236 } 237 } 238 239 static bool 240 nexttodoor(int sx, int sy) 241 { 242 int dx,dy; 243 struct rm *lev; 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) 247 return(1); 248 return(0); 249 } 250 251 static bool 252 has_dnstairs(struct mkroom *sroom) 253 { 254 return(sroom->lx <= xdnstair && xdnstair <= sroom->hx && 255 sroom->ly <= ydnstair && ydnstair <= sroom->hy); 256 } 257 258 static bool 259 has_upstairs(struct mkroom *sroom) 260 { 261 return(sroom->lx <= xupstair && xupstair <= sroom->hx && 262 sroom->ly <= yupstair && yupstair <= sroom->hy); 263 } 264 265 static bool 266 isbig(struct mkroom *sroom) 267 { 268 int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); 269 return( area > 20 ); 270 } 271 272 static int 273 dist2(int x0, int y0, int x1, int y1) 274 { 275 return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1)); 276 } 277 278 static int 279 sq(int a) 280 { 281 return(a*a); 282 } 283 #endif /* QUEST */ 284