1 1.11 dholland /* $NetBSD: hack.mkshop.c,v 1.11 2011/08/07 06:03:45 dholland Exp $ */ 2 1.5 christos 3 1.3 mycroft /* 4 1.8 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 1.8 jsm * Amsterdam 6 1.8 jsm * All rights reserved. 7 1.8 jsm * 8 1.8 jsm * Redistribution and use in source and binary forms, with or without 9 1.8 jsm * modification, are permitted provided that the following conditions are 10 1.8 jsm * met: 11 1.8 jsm * 12 1.8 jsm * - Redistributions of source code must retain the above copyright notice, 13 1.8 jsm * this list of conditions and the following disclaimer. 14 1.8 jsm * 15 1.8 jsm * - Redistributions in binary form must reproduce the above copyright 16 1.8 jsm * notice, this list of conditions and the following disclaimer in the 17 1.8 jsm * documentation and/or other materials provided with the distribution. 18 1.8 jsm * 19 1.8 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en 20 1.8 jsm * Informatica, nor the names of its contributors may be used to endorse or 21 1.8 jsm * promote products derived from this software without specific prior 22 1.8 jsm * written permission. 23 1.8 jsm * 24 1.8 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 1.8 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 1.8 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 1.8 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 1.8 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 1.8 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 1.8 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 1.8 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 1.8 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 1.8 jsm */ 36 1.8 jsm 37 1.8 jsm /* 38 1.8 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org> 39 1.8 jsm * All rights reserved. 40 1.8 jsm * 41 1.8 jsm * Redistribution and use in source and binary forms, with or without 42 1.8 jsm * modification, are permitted provided that the following conditions 43 1.8 jsm * are met: 44 1.8 jsm * 1. Redistributions of source code must retain the above copyright 45 1.8 jsm * notice, this list of conditions and the following disclaimer. 46 1.8 jsm * 2. Redistributions in binary form must reproduce the above copyright 47 1.8 jsm * notice, this list of conditions and the following disclaimer in the 48 1.8 jsm * documentation and/or other materials provided with the distribution. 49 1.8 jsm * 3. The name of the author may not be used to endorse or promote products 50 1.8 jsm * derived from this software without specific prior written permission. 51 1.8 jsm * 52 1.8 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 1.8 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 1.8 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 1.8 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 1.8 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 1.8 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 1.8 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 1.8 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.3 mycroft */ 63 1.3 mycroft 64 1.5 christos #include <sys/cdefs.h> 65 1.3 mycroft #ifndef lint 66 1.11 dholland __RCSID("$NetBSD: hack.mkshop.c,v 1.11 2011/08/07 06:03:45 dholland Exp $"); 67 1.5 christos #endif /* not lint */ 68 1.1 cgd 69 1.2 mycroft #include <stdlib.h> 70 1.1 cgd #ifndef QUEST 71 1.1 cgd #include "hack.h" 72 1.5 christos #include "extern.h" 73 1.1 cgd #include "def.mkroom.h" 74 1.1 cgd #include "def.eshk.h" 75 1.10 dholland 76 1.1 cgd #define ESHK ((struct eshk *)(&(shk->mextra[0]))) 77 1.10 dholland 78 1.10 dholland /* their probabilities */ 79 1.10 dholland static const schar shprobs[] = {3, 3, 5, 5, 10, 10, 14, 50}; 80 1.10 dholland 81 1.10 dholland static const struct permonst *morguemon(void); 82 1.10 dholland static int nexttodoor(int, int); 83 1.10 dholland static int has_dnstairs(struct mkroom *); 84 1.10 dholland static int has_upstairs(struct mkroom *); 85 1.10 dholland static int isbig(struct mkroom *); 86 1.10 dholland static int dist2(int, int, int, int); 87 1.10 dholland static int sq(int); 88 1.5 christos 89 1.5 christos void 90 1.9 dholland mkshop(void) 91 1.5 christos { 92 1.5 christos struct mkroom *sroom; 93 1.5 christos int sh, sx, sy, i = -1; 94 1.5 christos char let; 95 1.5 christos int roomno; 96 1.5 christos struct monst *shk; 97 1.1 cgd #ifdef WIZARD 98 1.1 cgd /* first determine shoptype */ 99 1.5 christos if (wizard) { 100 1.5 christos char *ep = getenv("SHOPTYPE"); 101 1.5 christos if (ep) { 102 1.5 christos if (*ep == 'z' || *ep == 'Z') { 103 1.1 cgd mkzoo(ZOO); 104 1.1 cgd return; 105 1.1 cgd } 106 1.5 christos if (*ep == 'm' || *ep == 'M') { 107 1.1 cgd mkzoo(MORGUE); 108 1.1 cgd return; 109 1.1 cgd } 110 1.5 christos if (*ep == 'b' || *ep == 'B') { 111 1.1 cgd mkzoo(BEEHIVE); 112 1.1 cgd return; 113 1.1 cgd } 114 1.5 christos if (*ep == 's' || *ep == 'S') { 115 1.1 cgd mkswamp(); 116 1.1 cgd return; 117 1.1 cgd } 118 1.5 christos for (i = 0; shtypes[i]; i++) 119 1.5 christos if (*ep == shtypes[i]) 120 1.5 christos break; 121 1.1 cgd goto gottype; 122 1.1 cgd } 123 1.1 cgd } 124 1.1 cgd gottype: 125 1.5 christos #endif /* WIZARD */ 126 1.5 christos for (sroom = &rooms[0], roomno = 0;; sroom++, roomno++) { 127 1.5 christos if (sroom->hx < 0) 128 1.5 christos return; 129 1.5 christos if (sroom - rooms >= nroom) { 130 1.1 cgd pline("rooms not closed by -1?"); 131 1.1 cgd return; 132 1.1 cgd } 133 1.5 christos if (sroom->rtype) 134 1.5 christos continue; 135 1.5 christos if (!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) 136 1.1 cgd continue; 137 1.5 christos if ( 138 1.1 cgd #ifdef WIZARD 139 1.5 christos (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) || 140 1.5 christos #endif /* WIZARD */ 141 1.7 chuck sroom->doorct == 1) 142 1.5 christos break; 143 1.1 cgd } 144 1.1 cgd 145 1.5 christos if (i < 0) { /* shoptype not yet determined */ 146 1.5 christos int j; 147 1.1 cgd 148 1.5 christos for (j = rn2(100), i = 0; (j -= shprobs[i]) >= 0; i++) 149 1.5 christos if (!shtypes[i]) 150 1.5 christos break; /* superfluous */ 151 1.5 christos if (isbig(sroom) && i + SHOPBASE == WANDSHOP) 152 1.5 christos i = GENERAL - SHOPBASE; 153 1.1 cgd } 154 1.1 cgd sroom->rtype = i + SHOPBASE; 155 1.1 cgd let = shtypes[i]; 156 1.1 cgd sh = sroom->fdoor; 157 1.1 cgd sx = doors[sh].x; 158 1.1 cgd sy = doors[sh].y; 159 1.5 christos if (sx == sroom->lx - 1) 160 1.5 christos sx++; 161 1.5 christos else if (sx == sroom->hx + 1) 162 1.5 christos sx--; 163 1.5 christos else if (sy == sroom->ly - 1) 164 1.5 christos sy++; 165 1.5 christos else if (sy == sroom->hy + 1) 166 1.5 christos sy--; 167 1.5 christos else { 168 1.1 cgd #ifdef WIZARD 169 1.5 christos /* This is said to happen sometimes, but I've never seen it. */ 170 1.5 christos if (wizard) { 171 1.5 christos int j = sroom->doorct; 172 1.5 christos 173 1.5 christos pline("Where is shopdoor?"); 174 1.5 christos pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly, 175 1.5 christos sroom->hx, sroom->hy); 176 1.5 christos pline("doormax=%d doorct=%d fdoor=%d", 177 1.5 christos doorindex, sroom->doorct, sh); 178 1.5 christos while (j--) { 179 1.5 christos pline("door [%d,%d]", doors[sh].x, doors[sh].y); 180 1.5 christos sh++; 181 1.5 christos } 182 1.5 christos more(); 183 1.1 cgd } 184 1.5 christos #endif /* WIZARD */ 185 1.5 christos return; 186 1.1 cgd } 187 1.5 christos if (!(shk = makemon(PM_SHK, sx, sy))) 188 1.5 christos return; 189 1.1 cgd shk->isshk = shk->mpeaceful = 1; 190 1.1 cgd shk->msleep = 0; 191 1.11 dholland shk->mtrapseen = ~0U; /* we know all the traps already */ 192 1.1 cgd ESHK->shoproom = roomno; 193 1.1 cgd ESHK->shoplevel = dlevel; 194 1.1 cgd ESHK->shd = doors[sh]; 195 1.1 cgd ESHK->shk.x = sx; 196 1.1 cgd ESHK->shk.y = sy; 197 1.1 cgd ESHK->robbed = 0; 198 1.1 cgd ESHK->visitct = 0; 199 1.1 cgd ESHK->following = 0; 200 1.5 christos shk->mgold = 1000 + 30 * rnd(100); /* initial capital */ 201 1.1 cgd ESHK->billct = 0; 202 1.1 cgd findname(ESHK->shknam, let); 203 1.5 christos for (sx = sroom->lx; sx <= sroom->hx; sx++) 204 1.5 christos for (sy = sroom->ly; sy <= sroom->hy; sy++) { 205 1.5 christos struct monst *mtmp; 206 1.5 christos if ((sx == sroom->lx && doors[sh].x == sx - 1) || 207 1.5 christos (sx == sroom->hx && doors[sh].x == sx + 1) || 208 1.5 christos (sy == sroom->ly && doors[sh].y == sy - 1) || 209 1.5 christos (sy == sroom->hy && doors[sh].y == sy + 1)) 210 1.5 christos continue; 211 1.5 christos if (rn2(100) < dlevel && !m_at(sx, sy) && 212 1.5 christos (mtmp = makemon(PM_MIMIC, sx, sy))) { 213 1.5 christos mtmp->mimic = 1; 214 1.5 christos mtmp->mappearance = 215 1.5 christos (let && rn2(10) < dlevel) ? let : ']'; 216 1.5 christos continue; 217 1.5 christos } 218 1.5 christos (void) mkobj_at(let, sx, sy); 219 1.1 cgd } 220 1.1 cgd } 221 1.1 cgd 222 1.5 christos void 223 1.9 dholland mkzoo(int type) 224 1.1 cgd { 225 1.5 christos struct mkroom *sroom; 226 1.5 christos struct monst *mon; 227 1.5 christos int sh, sx, sy, i; 228 1.5 christos int goldlim = 500 * dlevel; 229 1.5 christos int moct = 0; 230 1.1 cgd 231 1.1 cgd i = nroom; 232 1.5 christos for (sroom = &rooms[rn2(nroom)];; sroom++) { 233 1.5 christos if (sroom == &rooms[nroom]) 234 1.1 cgd sroom = &rooms[0]; 235 1.5 christos if (!i-- || sroom->hx < 0) 236 1.1 cgd return; 237 1.5 christos if (sroom->rtype) 238 1.1 cgd continue; 239 1.5 christos if (type == MORGUE && sroom->rlit) 240 1.1 cgd continue; 241 1.5 christos if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 242 1.1 cgd continue; 243 1.5 christos if (sroom->doorct == 1 || !rn2(5)) 244 1.1 cgd break; 245 1.1 cgd } 246 1.1 cgd sroom->rtype = type; 247 1.1 cgd sh = sroom->fdoor; 248 1.5 christos for (sx = sroom->lx; sx <= sroom->hx; sx++) 249 1.5 christos for (sy = sroom->ly; sy <= sroom->hy; sy++) { 250 1.5 christos if ((sx == sroom->lx && doors[sh].x == sx - 1) || 251 1.5 christos (sx == sroom->hx && doors[sh].x == sx + 1) || 252 1.5 christos (sy == sroom->ly && doors[sh].y == sy - 1) || 253 1.5 christos (sy == sroom->hy && doors[sh].y == sy + 1)) 254 1.5 christos continue; 255 1.5 christos mon = makemon( 256 1.5 christos (type == MORGUE) ? morguemon() : 257 1.5 christos (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, 258 1.5 christos sx, sy); 259 1.5 christos if (mon) 260 1.5 christos mon->msleep = 1; 261 1.5 christos switch (type) { 262 1.5 christos case ZOO: 263 1.5 christos i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y)); 264 1.5 christos if (i >= goldlim) 265 1.5 christos i = 5 * dlevel; 266 1.5 christos goldlim -= i; 267 1.5 christos mkgold((long) (10 + rn2(i)), sx, sy); 268 1.5 christos break; 269 1.5 christos case MORGUE: 270 1.5 christos /* 271 1.5 christos * Usually there is one dead body in the 272 1.5 christos * morgue 273 1.5 christos */ 274 1.5 christos if (!moct && rn2(3)) { 275 1.5 christos mksobj_at(CORPSE, sx, sy); 276 1.5 christos moct++; 277 1.5 christos } 278 1.5 christos break; 279 1.5 christos case BEEHIVE: 280 1.5 christos if (!rn2(3)) 281 1.5 christos mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); 282 1.5 christos break; 283 1.5 christos } 284 1.1 cgd } 285 1.1 cgd } 286 1.1 cgd 287 1.10 dholland static const struct permonst * 288 1.9 dholland morguemon(void) 289 1.1 cgd { 290 1.5 christos int i = rn2(100), hd = rn2(dlevel); 291 1.1 cgd 292 1.5 christos if (hd > 10 && i < 10) 293 1.5 christos return (PM_DEMON); 294 1.5 christos if (hd > 8 && i > 85) 295 1.5 christos return (PM_VAMPIRE); 296 1.5 christos return ((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE); 297 1.1 cgd } 298 1.1 cgd 299 1.5 christos void 300 1.9 dholland mkswamp(void) 301 1.5 christos { /* Michiel Huisjes & Fred de Wilde */ 302 1.5 christos struct mkroom *sroom; 303 1.5 christos int sx, sy, i, eelct = 0; 304 1.1 cgd 305 1.5 christos for (i = 0; i < 5; i++) { /* 5 tries */ 306 1.1 cgd sroom = &rooms[rn2(nroom)]; 307 1.5 christos if (sroom->hx < 0 || sroom->rtype || 308 1.5 christos has_upstairs(sroom) || has_dnstairs(sroom)) 309 1.1 cgd continue; 310 1.1 cgd 311 1.1 cgd /* satisfied; make a swamp */ 312 1.1 cgd sroom->rtype = SWAMP; 313 1.5 christos for (sx = sroom->lx; sx <= sroom->hx; sx++) 314 1.5 christos for (sy = sroom->ly; sy <= sroom->hy; sy++) 315 1.5 christos if ((sx + sy) % 2 && !o_at(sx, sy) && !t_at(sx, sy) 316 1.5 christos && !m_at(sx, sy) && !nexttodoor(sx, sy)) { 317 1.5 christos levl[sx][sy].typ = POOL; 318 1.5 christos levl[sx][sy].scrsym = POOL_SYM; 319 1.5 christos if (!eelct || !rn2(4)) { 320 1.5 christos (void) makemon(PM_EEL, sx, sy); 321 1.5 christos eelct++; 322 1.5 christos } 323 1.5 christos } 324 1.1 cgd } 325 1.1 cgd } 326 1.1 cgd 327 1.10 dholland static int 328 1.9 dholland nexttodoor(int sx, int sy) 329 1.1 cgd { 330 1.5 christos int dx, dy; 331 1.5 christos struct rm *lev; 332 1.5 christos for (dx = -1; dx <= 1; dx++) 333 1.5 christos for (dy = -1; dy <= 1; dy++) 334 1.5 christos if ((lev = &levl[sx + dx][sy + dy])->typ == DOOR || 335 1.5 christos lev->typ == SDOOR || lev->typ == LDOOR) 336 1.5 christos return (1); 337 1.5 christos return (0); 338 1.1 cgd } 339 1.1 cgd 340 1.10 dholland static int 341 1.9 dholland has_dnstairs(struct mkroom *sroom) 342 1.1 cgd { 343 1.5 christos return (sroom->lx <= xdnstair && xdnstair <= sroom->hx && 344 1.5 christos sroom->ly <= ydnstair && ydnstair <= sroom->hy); 345 1.1 cgd } 346 1.1 cgd 347 1.10 dholland static int 348 1.9 dholland has_upstairs(struct mkroom *sroom) 349 1.1 cgd { 350 1.5 christos return (sroom->lx <= xupstair && xupstair <= sroom->hx && 351 1.5 christos sroom->ly <= yupstair && yupstair <= sroom->hy); 352 1.1 cgd } 353 1.1 cgd 354 1.10 dholland static int 355 1.9 dholland isbig(struct mkroom *sroom) 356 1.1 cgd { 357 1.5 christos int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); 358 1.5 christos return (area > 20); 359 1.1 cgd } 360 1.1 cgd 361 1.10 dholland static int 362 1.9 dholland dist2(int x0, int y0, int x1, int y1) 363 1.5 christos { 364 1.5 christos return ((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1)); 365 1.1 cgd } 366 1.1 cgd 367 1.10 dholland static int 368 1.9 dholland sq(int a) 369 1.5 christos { 370 1.5 christos return (a * a); 371 1.1 cgd } 372 1.5 christos #endif /* QUEST */ 373