Source:SLASH'EM 0.0.7E7F2/shknam.c
Jump to navigation
Jump to search
Below is the full text to shknam.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[Source:SLASH'EM 0.0.7E7F2/shknam.c#line123]], for example.
Source code for vanilla NetHack is at Source code.
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)shknam.c 3.4 2003/01/09 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* shknam.c -- initialize a shop */ 6. 7. #include "hack.h" 8. #include "eshk.h" 9. 10. #ifndef OVLB 11. extern const struct shclass shtypes[]; 12. 13. #else 14. 15. STATIC_DCL void FDECL(mkshobj_at, (const struct shclass *,int,int)); 16. STATIC_DCL void FDECL(nameshk, (struct monst *,const char * const *)); 17. STATIC_DCL int FDECL(shkinit, (const struct shclass *,struct mkroom *)); 18. 19. #ifdef BLACKMARKET 20. STATIC_DCL void FDECL(stock_blkmar, 21. (const struct shclass *, struct mkroom *, int)); 22. #endif /* BLACKMARKET */ 23. #ifdef OTHER_SERVICES 24. /* WAC init shk services */ 25. static void FDECL(init_shk_services, (struct monst *)); 26. #endif 27. 28. 29. static const char * const shkliquors[] = { 30. /* Ukraine */ 31. "Njezjin", "Tsjernigof", "Ossipewsk", "Gorlowka", 32. /* Belarus */ 33. "Gomel", 34. /* N. Russia */ 35. "Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja", 36. "Narodnaja", "Kyzyl", 37. /* Silezie */ 38. "Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice", 39. "Brzeg", "Krnov", "Hradec Kralove", 40. /* Schweiz */ 41. "Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm", 42. "Flims", "Vals", "Schuls", "Zum Loch", 43. 0 44. }; 45. 46. static const char * const shkbooks[] = { 47. /* Eire */ 48. "Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch", 49. "Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra", 50. "Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan", 51. "Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh", 52. "Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea", 53. "Culdaff", "Dunfanaghy", "Inishbofin", "Kesh", 54. 0 55. }; 56. 57. static const char * const shkarmors[] = { 58. /* Turquie */ 59. "Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep", 60. "Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak", 61. "Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt", 62. "Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni", 63. "Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat", 64. "Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan", 65. 0 66. }; 67. 68. static const char * const shkwands[] = { 69. /* Wales */ 70. "Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach", 71. "Rhaeader", "Llandrindod", "Llanfair-ym-muallt", 72. "Y-Fenni", "Maesteg", "Rhydaman", "Beddgelert", 73. "Curig", "Llanrwst", "Llanerchymedd", "Caergybi", 74. /* Scotland */ 75. "Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar", 76. "Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven", 77. "Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch", 78. "Kyleakin", "Dunvegan", 79. 0 80. }; 81. 82. static const char * const shkrings[] = { 83. /* Hollandse familienamen */ 84. "Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken", 85. "Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy", 86. "Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix", 87. "Ypey", 88. /* Skandinaviske navne */ 89. "Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko", 90. "Enontekis", "Rovaniemi", "Avasaksa", "Haparanda", 91. "Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske", 92. 0 93. }; 94. 95. static const char * const shkfoods[] = { 96. /* Indonesia */ 97. "Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan", 98. "Bandjar", "Parbalingga", "Bojolali", "Sarangan", 99. "Ngebel", "Djombang", "Ardjawinangun", "Berbek", 100. "Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi", 101. "Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan", 102. "Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe", 103. "Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe", 104. 0 105. }; 106. 107. static const char * const shkweapons[] = { 108. /* Perigord */ 109. "Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard", 110. "Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac", 111. "Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac", 112. "Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac", 113. "Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon", 114. "Eymoutiers", "Eygurande", "Eauze", "Labouheyre", 115. 0 116. }; 117. 118. static const char * const shktools[] = { 119. /* Spmi */ 120. "Ymla", "Eed-morra", "Cubask", "Nieb", "Bnowr Falr", "Telloc Cyaj", 121. "Sperc", "Noskcirdneh", "Yawolloh", "Hyeghu", "Niskal", "Trahnil", 122. "Htargcm", "Enrobwem", "Kachzi Rellim", "Regien", "Donmyar", 123. "Yelpur", "Nosnehpets", "Stewe", "Renrut", "_Zlaw", "Nosalnef", 124. "Rewuorb", "Rellenk", "Yad", "Cire Htims", "Y-crad", "Nenilukah", 125. "Corsh", "Aned", 126. #ifdef OVERLAY 127. "Erreip", "Nehpets", "Mron", "Snivek", "Lapu", "Kahztiy", 128. #endif 129. #ifdef WIN32 130. "Lechaim", "Lexa", "Niod", 131. #endif 132. #ifdef MAC 133. "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s", 134. "Yao-hang", "Tonbar", "Nivek", "Kivenhoug", 135. #endif 136. #ifdef AMIGA 137. "Falo", "Nosid-da\'r", "Ekim-p", "Rebrol-nek", "Noslo", "Yl-rednow", 138. "Mured-oog", "Ivrajimsal", 139. #endif 140. #ifdef TOS 141. "Nivram", 142. #endif 143. #ifdef VMS 144. "Lez-tneg", "Ytnu-haled", "Niknar", 145. #endif 146. 0 147. }; 148. 149. static const char * const shklight[] = { 150. /* Romania */ 151. "Zarnesti", "Slanic", "Nehoiasu", "Ludus", "Sighisoara", "Nisipitu", 152. "Razboieni", "Bicaz", "Dorohoi", "Vaslui", "Fetesti", "Tirgu Neamt", 153. "Babadag", "Zimnicea", "Zlatna", "Jiu", "Eforie", "Mamaia", 154. /* Bulgaria */ 155. "Silistra", "Tulovo", "Panagyuritshte", "Smolyan", "Kirklareli", 156. "Pernik", "Lom", "Haskovo", "Dobrinishte", "Varvara", "Oryahovo", 157. "Troyan", "Lovech", "Sliven", 158. 0 159. }; 160. 161. static const char * const shkgeneral[] = { 162. /* Suriname */ 163. "Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi", 164. "Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo", 165. "Akalapi", "Sipaliwini", 166. /* Greenland */ 167. "Annootok", "Upernavik", "Angmagssalik", 168. /* N. Canada */ 169. "Aklavik", "Inuvik", "Tuktoyaktuk", 170. "Chicoutimi", "Ouiatchouane", "Chibougamau", 171. "Matagami", "Kipawa", "Kinojevis", 172. "Abitibi", "Maganasipi", 173. /* Iceland */ 174. "Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri", 175. "Holmavik", 176. 0 177. }; 178. 179. #ifdef BLACKMARKET 180. static const char *shkblack[] = { 181. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 182. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 183. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 184. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 185. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 186. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 187. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 188. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 189. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 190. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 191. "One-eyed Sam", "One-eyed Sam", "One-eyed Sam", 192. 0 193. }; 194. #endif /* BLACKMARKET */ 195. 196. /* STEPHEN WHITE'S NEW CODE */ 197. static const char *shkpet[] = { 198. "Silistra", "Tulovo", "Panagyuritshte", "Smolyan", "Kirklareli", 199. "Pernik", "Lom", "Haskovo", "Dobrinishte", "Varvara", "Oryahovo", 200. "Troyan", "Lovech", "Sliven", 201. 0 202. }; 203. 204. /* 205. * To add new shop types, all that is necessary is to edit the shtypes[] array. 206. * See mkroom.h for the structure definition. Typically, you'll have to lower 207. * some or all of the probability fields in old entries to free up some 208. * percentage for the new type. 209. * 210. * The placement type field is not yet used but will be in the near future. 211. * 212. * The iprobs array in each entry defines the probabilities for various kinds 213. * of objects to be present in the given shop type. You can associate with 214. * each percentage either a generic object type (represented by one of the 215. * *_CLASS macros) or a specific object (represented by an onames.h define). 216. * In the latter case, prepend it with a unary minus so the code can know 217. * (by testing the sign) whether to use mkobj() or mksobj(). 218. */ 219. /* KMH -- Don't forget to update mkroom.h and lev_main.c when adding 220. * a new shop type. 221. */ 222. const struct shclass shtypes[] = { 223. {"general store", RANDOM_CLASS, 24, 224. D_SHOP, {{100, RANDOM_CLASS}, {0, 0}, {0, 0}}, shkgeneral}, 225. {"used armor dealership", ARMOR_CLASS, 20, 226. D_SHOP, {{90, ARMOR_CLASS}, {10, WEAPON_CLASS}, {0, 0}}, 227. shkarmors}, 228. {"second-hand bookstore", SCROLL_CLASS, 4, D_SHOP, 229. {{90, SCROLL_CLASS}, {10, SPBOOK_CLASS}, {0, 0}}, shkbooks}, 230. {"liquor emporium", POTION_CLASS, 4, D_SHOP, 231. {{100, POTION_CLASS}, {0, 0}, {0, 0}}, shkliquors}, 232. #ifdef FIREARMS /* KMH -- no longer "antique" */ 233. {"weapons outlet", WEAPON_CLASS, 20, D_SHOP, { 234. {80, WEAPON_CLASS}, {6, -BULLET}, {3, -BULLET}, {1, -SILVER_BULLET}, 235. #else 236. {"antique weapons outlet", WEAPON_CLASS, 20, D_SHOP, { 237. {90, WEAPON_CLASS}, 238. #endif 239. {10, ARMOR_CLASS}, {0, 0}}, shkweapons}, 240. {"delicatessen", FOOD_CLASS, 4, D_SHOP, 241. {{83, FOOD_CLASS}, {5, -POT_FRUIT_JUICE}, {4, -POT_BOOZE}, 242. {5, -POT_WATER}, {3, -ICE_BOX}}, shkfoods}, 243. {"jewelers", RING_CLASS, 4, D_SHOP, 244. {{85, RING_CLASS}, {10, GEM_CLASS}, {5, AMULET_CLASS}, {0, 0}}, 245. shkrings}, 246. {"quality apparel and accessories", WAND_CLASS, 4, D_SHOP, 247. {{90, WAND_CLASS}, {5, -LEATHER_GLOVES}, {5, -ELVEN_CLOAK}, {0, 0}}, 248. shkwands}, 249. {"hardware store", TOOL_CLASS, 4, D_SHOP, 250. {{100, TOOL_CLASS}, {0, 0}}, shktools}, 251. /* Actually shktools is ignored; the code specifically chooses a 252. * random implementor name (along with candle shops having 253. * random shopkeepers) 254. */ 255. /* STEPHEN WHITE'S NEW CODE */ 256. {"pet store", FOOD_CLASS, 4, D_SHOP, { 257. #ifdef STEED 258. {67, -FIGURINE}, {5, -LEASH},{10, -TRIPE_RATION}, {5, -SADDLE}, 259. #else 260. {72, -FIGURINE}, {5, -LEASH},{10, -TRIPE_RATION}, 261. #endif 262. {10, -TIN_WHISTLE}, {3, -MAGIC_WHISTLE}}, shkpet}, 263. /* Robin Johnson -- 4% taken from pet store */ 264. {"frozen food store", FOOD_CLASS, 4, D_SHOP, 265. {{90, -ICE_BOX}, {10, -TIN}, 266. /* shopkeeper will pay for corpses, but they aren't generated */ 267. /* on the shop floor */ 268. {0, -CORPSE}, {0, 0}}, shkfoods}, 269. {"rare books", SPBOOK_CLASS, 4, D_SHOP, 270. {{90, SPBOOK_CLASS}, {10, SCROLL_CLASS}, {0, 0}}, shkbooks}, 271. /* Shops below this point are "unique". That is they must all have a 272. * probability of zero. They are only created via the special level 273. * loader. 274. */ 275. {"lighting store", TOOL_CLASS, 0, D_SHOP, 276. {{25, -WAX_CANDLE}, {35, -TALLOW_CANDLE}, {5, -TORCH}, {11, -BRASS_LANTERN}, 277. {16, -OIL_LAMP}, {3, -MAGIC_LAMP}, {5, -MAGIC_CANDLE}}, shklight}, 278. #ifdef BLACKMARKET 279. {"black market", RANDOM_CLASS, 0, D_SHOP, 280. {{100, RANDOM_CLASS}, {0, 0}, {0, 0}}, shkblack}, 281. #endif /* BLACKMARKET */ 282. {(char *)0, 0, 0, 0, {{0, 0}, {0, 0}, {0, 0}}, 0} 283. }; 284. 285. #if 0 286. /* validate shop probabilities; otherwise incorrect local changes could 287. end up provoking infinite loops or wild subscripts fetching garbage */ 288. void 289. init_shop_selection() 290. { 291. register int i, j, item_prob, shop_prob; 292. 293. for (shop_prob = 0, i = 0; i < SIZE(shtypes); i++) { 294. shop_prob += shtypes[i].prob; 295. for (item_prob = 0, j = 0; j < SIZE(shtypes[0].iprobs); j++) 296. item_prob += shtypes[i].iprobs[j].iprob; 297. if (item_prob != 100) 298. panic("item probabilities total to %d for %s shops!", 299. item_prob, shtypes[i].name); 300. } 301. if (shop_prob != 100) 302. panic("shop probabilities total to %d!", shop_prob); 303. } 304. #endif /*0*/ 305. 306. STATIC_OVL void 307. mkshobj_at(shp, sx, sy) 308. /* make an object of the appropriate type for a shop square */ 309. const struct shclass *shp; 310. int sx, sy; 311. { 312. struct monst *mtmp; 313. int atype; 314. struct permonst *ptr; 315. 316. if (rn2(100) < depth(&u.uz) && 317. !MON_AT(sx, sy) && (ptr = mkclass(S_MIMIC,0)) && 318. (mtmp = makemon(ptr,sx,sy,NO_MM_FLAGS)) != 0) { 319. /* note: makemon will set the mimic symbol to a shop item */ 320. if (rn2(10) >= depth(&u.uz)) { 321. mtmp->m_ap_type = M_AP_OBJECT; 322. mtmp->mappearance = STRANGE_OBJECT; 323. } 324. } else { 325. atype = get_shop_item(shp - shtypes); 326. if (atype < 0) 327. (void) mksobj_at(-atype, sx, sy, TRUE, TRUE); 328. else 329. (void) mkobj_at(atype, sx, sy, TRUE); 330. } 331. } 332. 333. /* extract a shopkeeper name for the given shop type */ 334. STATIC_OVL void 335. nameshk(shk, nlp) 336. struct monst *shk; 337. const char * const *nlp; 338. { 339. int i, trycnt, names_avail; 340. const char *shname = 0; 341. struct monst *mtmp; 342. int name_wanted; 343. s_level *sptr; 344. 345. if (nlp == shklight && In_mines(&u.uz) 346. && (sptr = Is_special(&u.uz)) != 0 && sptr->flags.town) { 347. /* special-case minetown lighting shk */ 348. shname = "Izchak"; 349. shk->female = FALSE; 350. #ifdef BLACKMARKET 351. } else if (nlp == shkblack) { 352. /* special-case black marketeer */ 353. shname = "One-eyed Sam"; 354. shk->female = shk->data->mflags2 & M2_MALE ? FALSE : TRUE; 355. #endif /* BLACKMARKET */ 356. } else { 357. /* We want variation from game to game, without needing the save 358. and restore support which would be necessary for randomization; 359. try not to make too many assumptions about time_t's internals; 360. use ledger_no rather than depth to keep mine town distinct. */ 361. int nseed = (int)((long)u.ubirthday / 257L); 362. 363. name_wanted = ledger_no(&u.uz) + (nseed % 13) - (nseed % 5); 364. if (name_wanted < 0) name_wanted += (13 + 5); 365. shk->female = name_wanted & 1; 366. 367. for (names_avail = 0; nlp[names_avail]; names_avail++) 368. continue; 369. 370. for (trycnt = 0; trycnt < 50; trycnt++) { 371. if (nlp == shktools) { 372. shname = shktools[rn2(names_avail)]; 373. shk->female = (*shname == '_'); 374. if (shk->female) shname++; 375. } else if (name_wanted < names_avail) { 376. shname = nlp[name_wanted]; 377. } else if ((i = rn2(names_avail)) != 0) { 378. shname = nlp[i - 1]; 379. } else if (nlp != shkgeneral) { 380. nlp = shkgeneral; /* try general names */ 381. for (names_avail = 0; nlp[names_avail]; names_avail++) 382. continue; 383. continue; /* next `trycnt' iteration */ 384. } else { 385. shname = shk->female ? "Lucrezia" : "Dirk"; 386. } 387. 388. /* is name already in use on this level? */ 389. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 390. if (DEADMONSTER(mtmp) || (mtmp == shk) || !mtmp->isshk) continue; 391. if (strcmp(ESHK(mtmp)->shknam, shname)) continue; 392. break; 393. } 394. if (!mtmp) break; /* new name */ 395. } 396. } 397. (void) strncpy(ESHK(shk)->shknam, shname, PL_NSIZ); 398. ESHK(shk)->shknam[PL_NSIZ-1] = 0; 399. } 400. 401. STATIC_OVL int 402. shkinit(shp, sroom) /* create a new shopkeeper in the given room */ 403. const struct shclass *shp; 404. struct mkroom *sroom; 405. { 406. register int sh, sx, sy; 407. struct monst *shk; 408. long shkmoney; /* Temporary placeholder for Shopkeeper's initial capital */ 409. 410. /* place the shopkeeper in the given room */ 411. sh = sroom->fdoor; 412. sx = doors[sh].x; 413. sy = doors[sh].y; 414. 415. /* check that the shopkeeper placement is sane */ 416. if(sroom->irregular) { 417. int rmno = (sroom - rooms) + ROOMOFFSET; 418. if (isok(sx-1,sy) && !levl[sx-1][sy].edge && 419. (int) levl[sx-1][sy].roomno == rmno) sx--; 420. else if (isok(sx+1,sy) && !levl[sx+1][sy].edge && 421. (int) levl[sx+1][sy].roomno == rmno) sx++; 422. else if (isok(sx,sy-1) && !levl[sx][sy-1].edge && 423. (int) levl[sx][sy-1].roomno == rmno) sy--; 424. else if (isok(sx,sy+1) && !levl[sx][sy+1].edge && 425. (int) levl[sx][sy+1].roomno == rmno) sx++; 426. else goto shk_failed; 427. } 428. else if(sx == sroom->lx-1) sx++; 429. else if(sx == sroom->hx+1) sx--; 430. else if(sy == sroom->ly-1) sy++; 431. else if(sy == sroom->hy+1) sy--; else { 432. shk_failed: 433. #ifdef DEBUG 434. # ifdef WIZARD 435. /* Said to happen sometimes, but I have never seen it. */ 436. /* Supposedly fixed by fdoor change in mklev.c */ 437. if(wizard) { 438. register int j = sroom->doorct; 439. 440. pline("Where is shopdoor?"); 441. pline("Room at (%d,%d),(%d,%d).", 442. sroom->lx, sroom->ly, sroom->hx, sroom->hy); 443. pline("doormax=%d doorct=%d fdoor=%d", 444. doorindex, sroom->doorct, sh); 445. while(j--) { 446. pline("door [%d,%d]", doors[sh].x, doors[sh].y); 447. sh++; 448. } 449. display_nhwindow(WIN_MESSAGE, FALSE); 450. } 451. # endif 452. #endif 453. return(-1); 454. } 455. 456. if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), FALSE); /* insurance */ 457. 458. /* now initialize the shopkeeper monster structure */ 459. 460. #ifdef BLACKMARKET 461. shk = 0; 462. if (Is_blackmarket(&u.uz)) { 463. shk = makemon(&mons[PM_BLACK_MARKETEER], sx, sy, NO_MM_FLAGS); 464. } 465. if (!shk) { 466. if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS))) 467. return(-1); 468. } 469. #else /* BLACKMARKET */ 470. if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS))) 471. return(-1); 472. #endif /* BLACKMARKET */ 473. 474. shk->isshk = shk->mpeaceful = 1; 475. set_malign(shk); 476. shk->msleeping = 0; 477. shk->mtrapseen = ~0; /* we know all the traps already */ 478. ESHK(shk)->shoproom = (sroom - rooms) + ROOMOFFSET; 479. sroom->resident = shk; 480. ESHK(shk)->shoptype = sroom->rtype; 481. assign_level(&(ESHK(shk)->shoplevel), &u.uz); 482. ESHK(shk)->shd.x = doors[sh].x; 483. ESHK(shk)->shd.y = doors[sh].y; 484. ESHK(shk)->shk.x = sx; 485. ESHK(shk)->shk.y = sy; 486. ESHK(shk)->robbed = 0L; 487. ESHK(shk)->credit = 0L; 488. ESHK(shk)->debit = 0L; 489. ESHK(shk)->loan = 0L; 490. ESHK(shk)->visitct = 0; 491. ESHK(shk)->following = 0; 492. ESHK(shk)->billct = 0; 493. #ifdef OTHER_SERVICES 494. /* WAC init services */ 495. init_shk_services(shk); 496. #endif 497. 498. shkmoney = 1000L + 30L*(long)rnd(100); /* initial capital */ 499. /* [CWC] Lets not create the money yet until we see if the 500. shk is a black marketeer, else we'll have to create 501. another money object, if GOLDOBJ is defined */ 502. 503. if (shp->shknms == shkrings) 504. (void) mongets(shk, TOUCHSTONE); 505. nameshk(shk, shp->shknms); 506. 507. #ifdef BLACKMARKET 508. if (Is_blackmarket(&u.uz)) 509. shkmoney = 7*shkmoney + rn2(3*shkmoney); 510. #endif 511. 512. #ifndef GOLDOBJ 513. shk->mgold = shkmoney; 514. #else 515. mkmonmoney(shk, shkmoney); 516. #endif 517. 518. #ifdef BLACKMARKET 519. if (Is_blackmarket(&u.uz)) { 520. register struct obj *otmp; 521. /* make sure black marketeer can wield Thiefbane */ 522. shk->data->maligntyp = -1; 523. /* black marketeer's equipment */ 524. otmp = mksobj(LONG_SWORD, FALSE, FALSE); 525. otmp = oname(otmp, artiname(ART_THIEFBANE)); 526. mpickobj(shk, otmp); 527. if (otmp->spe < 5) otmp->spe += rnd(5); 528. otmp = mksobj(SHIELD_OF_REFLECTION, FALSE, FALSE); 529. mpickobj(shk, otmp); 530. if (otmp->spe < 5) otmp->spe += rnd(5); 531. otmp = mksobj(GRAY_DRAGON_SCALE_MAIL, FALSE, FALSE); 532. mpickobj(shk, otmp); 533. if (otmp->spe < 5) otmp->spe += rnd(5); 534. otmp = mksobj(SPEED_BOOTS, FALSE, FALSE); 535. mpickobj(shk, otmp); 536. if (otmp->spe < 5) otmp->spe += rnd(5); 537. otmp = mksobj(AMULET_OF_LIFE_SAVING, FALSE, FALSE); 538. mpickobj(shk, otmp); 539. /* wear armor and amulet */ 540. m_dowear(shk, TRUE); 541. otmp = mksobj(SKELETON_KEY, FALSE, FALSE); 542. mpickobj(shk, otmp); 543. } 544. #endif /* BLACKMARKET */ 545. 546. return(sh); 547. } 548. 549. /* stock a newly-created room with objects */ 550. void 551. stock_room(shp_indx, sroom) 552. int shp_indx; 553. register struct mkroom *sroom; 554. { 555. /* 556. * Someday soon we'll dispatch on the shdist field of shclass to do 557. * different placements in this routine. Currently it only supports 558. * shop-style placement (all squares except a row nearest the first 559. * door get objects). 560. */ 561. register int sx, sy, sh; 562. char buf[BUFSZ]; 563. int rmno = (sroom - rooms) + ROOMOFFSET; 564. const struct shclass *shp = &shtypes[shp_indx]; 565. 566. /* first, try to place a shopkeeper in the room */ 567. if ((sh = shkinit(shp, sroom)) < 0) 568. return; 569. 570. /* make sure no doorways without doors, and no */ 571. /* trapped doors, in shops. */ 572. sx = doors[sroom->fdoor].x; 573. sy = doors[sroom->fdoor].y; 574. 575. if(levl[sx][sy].doormask == D_NODOOR) { 576. levl[sx][sy].doormask = D_ISOPEN; 577. newsym(sx,sy); 578. } 579. if(levl[sx][sy].typ == SDOOR) { 580. cvt_sdoor_to_door(&levl[sx][sy]); /* .typ = DOOR */ 581. newsym(sx,sy); 582. } 583. if(levl[sx][sy].doormask & D_TRAPPED) 584. levl[sx][sy].doormask = D_LOCKED; 585. 586. if(levl[sx][sy].doormask == D_LOCKED) { 587. register int m = sx, n = sy; 588. 589. if(inside_shop(sx+1,sy)) m--; 590. else if(inside_shop(sx-1,sy)) m++; 591. if(inside_shop(sx,sy+1)) n--; 592. else if(inside_shop(sx,sy-1)) n++; 593. Sprintf(buf, "Closed for inventory"); 594. make_engr_at(m, n, buf, 0L, DUST); 595. } 596. 597. #ifdef BLACKMARKET 598. if (Is_blackmarket(&u.uz)) { 599. stock_blkmar(shp, sroom, sh); 600. level.flags.has_shop = TRUE; 601. return; 602. } 603. #endif /* BLACKMARKET */ 604. 605. for(sx = sroom->lx; sx <= sroom->hx; sx++) 606. for(sy = sroom->ly; sy <= sroom->hy; sy++) { 607. if(sroom->irregular) { 608. if (levl[sx][sy].edge || (int) levl[sx][sy].roomno != rmno || 609. distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1) 610. continue; 611. } else if((sx == sroom->lx && doors[sh].x == sx-1) || 612. (sx == sroom->hx && doors[sh].x == sx+1) || 613. (sy == sroom->ly && doors[sh].y == sy-1) || 614. (sy == sroom->hy && doors[sh].y == sy+1)) continue; 615. mkshobj_at(shp, sx, sy); 616. } 617. 618. /* 619. * Special monster placements (if any) should go here: that way, 620. * monsters will sit on top of objects and not the other way around. 621. */ 622. 623. level.flags.has_shop = TRUE; 624. } 625. 626. #ifdef BLACKMARKET 627. /* stock a newly-created black market with objects */ 628. static void 629. stock_blkmar(shp, sroom, sh) 630. const struct shclass *shp; 631. register struct mkroom *sroom; 632. register int sh; 633. { 634. /* 635. * Someday soon we'll dispatch on the shdist field of shclass to do 636. * different placements in this routine. Currently it only supports 637. * shop-style placement (all squares except a row nearest the first 638. * door get objects). 639. */ 640. /* [max] removed register int cl, char buf[bufsz] */ 641. int i, sx, sy, first = 0, next = 0, total, partial, typ; 642. struct obj *otmp; 643. int blkmar_gen[NUM_OBJECTS+2]; 644. int *clp, *lastclp; 645. int goodcl[12]; 646. 647. goodcl[ 0] = WEAPON_CLASS; 648. goodcl[ 1] = ARMOR_CLASS; 649. goodcl[ 2] = RING_CLASS; 650. goodcl[ 3] = AMULET_CLASS; 651. goodcl[ 4] = TOOL_CLASS; 652. goodcl[ 5] = FOOD_CLASS; 653. goodcl[ 6] = POTION_CLASS; 654. goodcl[ 7] = SCROLL_CLASS; 655. goodcl[ 8] = SPBOOK_CLASS; 656. goodcl[ 9] = WAND_CLASS; 657. goodcl[10] = GEM_CLASS; 658. goodcl[11] = 0; 659. 660. for (i=0; i < NUM_OBJECTS; i++) { 661. blkmar_gen[i] = 0; 662. } 663. 664. total = 0; 665. for (clp=goodcl; *clp!=0; clp++) { 666. lastclp = clp; 667. first = bases[*clp]; 668. /* this assumes that luckstone & loadstone comes just after the gems */ 669. next = (*clp==GEM_CLASS) ? (LOADSTONE+1) : bases[(*clp)+1]; 670. total += next-first; 671. } 672. if (total==0) return; 673. 674. if (sroom->hx-sroom->lx<2) return; 675. clp = goodcl-1; 676. partial = 0; 677. for(sx = sroom->lx+1; sx <= sroom->hx; sx++) { 678. if (sx==sroom->lx+1 || 679. ((sx-sroom->lx-2)*total)/(sroom->hx-sroom->lx-1)>partial) { 680. clp++; 681. if (clp>lastclp) clp = lastclp; 682. first = bases[*clp]; 683. next = (*clp==GEM_CLASS) ? (LOADSTONE+1) : bases[(*clp)+1]; 684. partial += next-first; 685. } 686. 687. for(sy = sroom->ly; sy <= sroom->hy; sy++) { 688. if((sx == sroom->lx && doors[sh].x == sx-1) || 689. (sx == sroom->hx && doors[sh].x == sx+1) || 690. (sy == sroom->ly && doors[sh].y == sy-1) || 691. (sy == sroom->hy && doors[sh].y == sy+1) || (rn2(3))) 692. continue; 693. 694. for (i=0; i<50; i++) { 695. typ = rn2(next-first) + first; 696. 697. /* forbidden objects */ 698. if (typ==AMULET_OF_YENDOR || typ==CANDELABRUM_OF_INVOCATION || 699. typ==BELL_OF_OPENING || typ==SPE_BOOK_OF_THE_DEAD || 700. objects[typ].oc_nowish || typ==0) 701. continue; 702. 703. otmp = mkobj_at(RANDOM_CLASS,sx,sy,TRUE); 704. /* generate multiple copies with decreasing probabilities */ 705. /* if (rn2(blkmar_gen[typ]+1) && i<49) continue; */ 706. 707. /* otmp = mksobj_at(typ, sx, sy, TRUE, TRUE); 708. blkmar_gen[typ]++;*/ 709. 710. /* prevent wishing abuse */ 711. if (typ==WAN_WISHING) { 712. otmp->spe = 0; 713. otmp->recharged = 1; 714. } 715. if (typ==MAGIC_LAMP) { 716. otmp->spe = 0; 717. } 718. 719. break; 720. } 721. 722. } 723. } 724. 725. /* 726. * Special monster placements (if any) should go here: that way, 727. * monsters will sit on top of objects and not the other way around. 728. */ 729. } 730. #endif /* BLACKMARKET */ 731. 732. #ifdef OTHER_SERVICES 733. 734. static void 735. init_shk_services(shk) 736. struct monst *shk; 737. { 738. ESHK(shk)->services = 0L; 739. 740. /* KMH, balance patch 2 -- Increase probability of shopkeeper services. 741. * Requested by Dave <mitch45678@aol.com> 742. */ 743. #ifdef BLACKMARKET 744. if (Is_blackmarket(&u.uz)) { 745. ESHK(shk)->services = 746. SHK_ID_BASIC|SHK_ID_PREMIUM|SHK_UNCURSE|SHK_APPRAISE| 747. SHK_SPECIAL_A|SHK_SPECIAL_B|SHK_SPECIAL_C; 748. return; 749. } 750. #endif 751. 752. /* Guarantee some form of identification 753. * 1/3 both Basic and Premium ID 754. * 2/15 Premium ID only 755. * 8/15 Basic ID only 756. */ 757. if (!rn2(2)) ESHK(shk)->services |= (SHK_ID_BASIC|SHK_ID_PREMIUM); 758. else if (!rn2(4)) ESHK(shk)->services |= SHK_ID_PREMIUM; 759. else ESHK(shk)->services |= SHK_ID_BASIC; 760. 761. if (!rn2(3)) ESHK(shk)->services |= SHK_UNCURSE; 762. 763. if (!rn2(3) && shk_class_match(WEAPON_CLASS, shk)) 764. ESHK(shk)->services |= SHK_APPRAISE; 765. 766. if ((shk_class_match(WEAPON_CLASS, shk) == SHK_MATCH) || 767. (shk_class_match(ARMOR_CLASS, shk) == SHK_MATCH) || 768. (shk_class_match(WAND_CLASS, shk) == SHK_MATCH) || 769. (shk_class_match(TOOL_CLASS, shk) == SHK_MATCH) || 770. (shk_class_match(SPBOOK_CLASS, shk) == SHK_MATCH) || 771. (shk_class_match(RING_CLASS, shk) == SHK_MATCH)) { 772. if (!rn2(4/*5*/)) ESHK(shk)->services |= SHK_SPECIAL_A; 773. if (!rn2(4/*5*/)) ESHK(shk)->services |= SHK_SPECIAL_B; 774. } 775. if (!rn2(4/*5*/) && (shk_class_match(WEAPON_CLASS, shk) == SHK_MATCH)) 776. ESHK(shk)->services |= SHK_SPECIAL_C; 777. 778. return; 779. } 780. #endif 781. 782. #endif /* OVLB */ 783. #ifdef OVL0 784. 785. /* does shkp's shop stock this item type? */ 786. boolean 787. saleable(shkp, obj) 788. struct monst *shkp; 789. struct obj *obj; 790. { 791. int i, shp_indx = ESHK(shkp)->shoptype - SHOPBASE; 792. const struct shclass *shp = &shtypes[shp_indx]; 793. 794. if (shp->symb == RANDOM_CLASS) return TRUE; 795. else for (i = 0; i < SIZE(shtypes[0].iprobs) && shp->iprobs[i].iprob; i++) 796. if (shp->iprobs[i].itype < 0 ? 797. shp->iprobs[i].itype == - obj->otyp : 798. shp->iprobs[i].itype == obj->oclass) return TRUE; 799. /* not found */ 800. return FALSE; 801. } 802. 803. /* positive value: class; negative value: specific object type */ 804. int 805. get_shop_item(type) 806. int type; 807. { 808. const struct shclass *shp = shtypes+type; 809. register int i,j; 810. 811. /* select an appropriate object type at random */ 812. for(j = rnd(100), i = 0; (j -= shp->iprobs[i].iprob) > 0; i++) 813. continue; 814. 815. return shp->iprobs[i].itype; 816. } 817. 818. #endif /* OVL0 */ 819. 820. /*shknam.c*/