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 31 #ifdef WIZARD 32 /* first determine shoptype */ 33 if (wizard) { 34 char *ep = getenv("SHOPTYPE"); 35 if (ep) { 36 if (*ep == 'z' || *ep == 'Z') { 37 mkzoo(ZOO); 38 return; 39 } 40 if (*ep == 'm' || *ep == 'M') { 41 mkzoo(MORGUE); 42 return; 43 } 44 if (*ep == 'b' || *ep == 'B') { 45 mkzoo(BEEHIVE); 46 return; 47 } 48 if (*ep == 's' || *ep == 'S') { 49 mkswamp(); 50 return; 51 } 52 for (i = 0; shtypes[i]; i++) 53 if (*ep == shtypes[i]) 54 break; 55 goto gottype; 56 } 57 } 58 gottype: 59 #endif /* WIZARD */ 60 for (sroom = &rooms[0], roomno = 0;; sroom++, roomno++) { 61 if (sroom->hx < 0) 62 return; 63 if (sroom - rooms >= nroom) { 64 pline("rooms not closed by -1?"); 65 return; 66 } 67 if (sroom->rtype) 68 continue; 69 if (!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) 70 continue; 71 if ( 72 #ifdef WIZARD 73 (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) || 74 #endif /* WIZARD */ 75 (sroom->doorct <= 2 && sroom->doorct > 0)) 76 break; 77 } 78 79 if (i < 0) { /* shoptype not yet determined */ 80 int j; 81 82 for (j = rn2(100), i = 0; (j -= shprobs[i]) >= 0; i++) 83 if (!shtypes[i]) /* superfluous */ 84 break; 85 if (isbig(sroom) && i + SHOPBASE == WANDSHOP) 86 i = GENERAL - SHOPBASE; 87 } 88 sroom->rtype = i + SHOPBASE; 89 let = shtypes[i]; 90 sh = sroom->fdoor; 91 sx = doors[sh].x; 92 sy = doors[sh].y; 93 if (sx == sroom->lx - 1) 94 sx++; 95 else if (sx == sroom->hx + 1) 96 sx--; 97 else if (sy == sroom->ly - 1) 98 sy++; 99 else if (sy == sroom->hy + 1) 100 sy--; 101 else { 102 #ifdef WIZARD 103 /* This is said to happen sometimes, but I've never seen it. */ 104 if (wizard) { 105 int j = sroom->doorct; 106 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); 112 while (j--) { 113 pline("door [%d,%d]", doors[sh].x, doors[sh].y); 114 sh++; 115 } 116 more(); 117 } 118 #endif /* WIZARD */ 119 return; 120 } 121 if (!(shk = makemon(PM_SHK, sx, sy))) 122 return; 123 shk->isshk = shk->mpeaceful = 1; 124 shk->msleep = 0; 125 shk->mtrapseen = ~0; /* we know all the traps already */ 126 ESHK->shoproom = roomno; 127 ESHK->shoplevel = dlevel; 128 ESHK->shd = doors[sh]; 129 ESHK->shk.x = sx; 130 ESHK->shk.y = sy; 131 ESHK->robbed = 0; 132 ESHK->visitct = 0; 133 ESHK->following = 0; 134 shk->mgold = 1000 + 30 * rnd(100); /* initial capital */ 135 ESHK->billct = 0; 136 findname(ESHK->shknam, let); 137 for (sx = sroom->lx; sx <= sroom->hx; sx++) 138 for (sy = sroom->ly; sy <= sroom->hy; sy++) { 139 struct monst *mtmp; 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)) 144 continue; 145 if (rn2(100) < dlevel && !m_at(sx, sy) && 146 (mtmp = makemon(PM_MIMIC, sx, sy))) { 147 mtmp->mimic = 1; 148 mtmp->mappearance = 149 (let && rn2(10) < dlevel) ? let : ']'; 150 continue; 151 } 152 mkobj_at(let, sx, sy); 153 } 154 } 155 156 void 157 mkzoo(int type) 158 { 159 struct mkroom *sroom; 160 struct monst *mon; 161 int sh, sx, sy, i; 162 int goldlim = 500 * dlevel; 163 int moct = 0; 164 165 i = nroom; 166 for (sroom = &rooms[rn2(nroom)];; sroom++) { 167 if (sroom == &rooms[nroom]) 168 sroom = &rooms[0]; 169 if (!i-- || sroom->hx < 0) 170 return; 171 if (sroom->rtype) 172 continue; 173 if (type == MORGUE && sroom->rlit) 174 continue; 175 if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 176 continue; 177 if (sroom->doorct == 1 || !rn2(5)) 178 break; 179 } 180 sroom->rtype = type; 181 sh = sroom->fdoor; 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)) 188 continue; 189 mon = makemon( 190 (type == MORGUE) ? morguemon() : 191 (type == BEEHIVE) ? PM_KILLER_BEE : NULL, 192 sx, sy); 193 if (mon) 194 mon->msleep = 1; 195 switch (type) { 196 case ZOO: 197 i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y)); 198 if (i >= goldlim) 199 i = 5 * dlevel; 200 goldlim -= i; 201 mkgold((long)(10 + rn2(i)), sx, sy); 202 break; 203 case MORGUE: 204 /* Usually there is one dead body in the morgue */ 205 if (!moct && rn2(3)) { 206 mksobj_at(CORPSE, sx, sy); 207 moct++; 208 } 209 break; 210 case BEEHIVE: 211 if (!rn2(3)) 212 mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); 213 break; 214 } 215 } 216 } 217 218 static struct permonst * 219 morguemon(void) 220 { 221 int i = rn2(100), hd = rn2(dlevel); 222 223 if (hd > 10 && i < 10) 224 return (PM_DEMON); 225 if (hd > 8 && i > 85) 226 return (PM_VAMPIRE); 227 return ((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE); 228 } 229 230 void 231 mkswamp(void) /* Michiel Huisjes & Fred de Wilde */ 232 { 233 struct mkroom *sroom; 234 int sx, sy, i, eelct = 0; 235 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)) 240 continue; 241 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); 253 eelct++; 254 } 255 } 256 } 257 } 258 259 static bool 260 nexttodoor(int sx, int sy) 261 { 262 int dx, dy; 263 struct rm *lev; 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) 268 return (1); 269 return (0); 270 } 271 272 static bool 273 has_dnstairs(struct mkroom *sroom) 274 { 275 return (sroom->lx <= xdnstair && xdnstair <= sroom->hx && 276 sroom->ly <= ydnstair && ydnstair <= sroom->hy); 277 } 278 279 static bool 280 has_upstairs(struct mkroom *sroom) 281 { 282 return (sroom->lx <= xupstair && xupstair <= sroom->hx && 283 sroom->ly <= yupstair && yupstair <= sroom->hy); 284 } 285 286 static bool 287 isbig(struct mkroom *sroom) 288 { 289 int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); 290 return (area > 20); 291 } 292 293 static int 294 dist2(int x0, int y0, int x1, int y1) 295 { 296 return ((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1)); 297 } 298 299 static int 300 sq(int a) 301 { 302 return (a * a); 303 } 304 #endif /* QUEST */ 305