Home | History | Annotate | Line # | Download | only in hack
      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