hack.mkshop.c 9.9 KB

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