1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: /* hack.mkshop.c - version 1.0.3 */ 3: 4: #ifndef QUEST 5: #include "hack.h" 6: #include "def.mkroom.h" 7: #include "def.eshk.h" 8: #define ESHK ((struct eshk *)(&(shk->mextra[0]))) 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: } 274: #endif QUEST