Source:NetHack 3.4.3/src/shknam.c
Below is the full text to src/shknam.c from NetHack 3.4.3. To link to a particular line, write [[shknam.c#line123]], for example.
Contents
Top of file
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.
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.
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.
Shopkeeper names
Potion store
19. static const char * const shkliquors[] = { 20. /* Ukraine */ 21. "Njezjin", "Tsjernigof", "Ossipewsk", "Gorlowka", 22. /* Belarus */ 23. "Gomel", 24. /* N. Russia */ 25. "Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja", 26. "Narodnaja", "Kyzyl", 27. /* Silezie */ 28. "Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice", 29. "Brzeg", "Krnov", "Hradec Kralove", 30. /* Schweiz */ 31. "Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm", 32. "Flims", "Vals", "Schuls", "Zum Loch", 33. 0 34. }; 35.
Spellbook store
36. static const char * const shkbooks[] = { 37. /* Eire */ 38. "Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch", 39. "Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra", 40. "Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan", 41. "Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh", 42. "Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea", 43. "Culdaff", "Dunfanaghy", "Inishbofin", "Kesh", 44. 0 45. }; 46.
"Skibbereen" is a town in Ireland, and the subject of an old song about the famine of 1847; perhaps the rest of these names are also towns in Ireland.
Armor store
47. static const char * const shkarmors[] = { 48. /* Turquie */ 49. "Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep", 50. "Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak", 51. "Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt", 52. "Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni", 53. "Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat", 54. "Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan", 55. 0 56. }; 57.
Wand store
58. static const char * const shkwands[] = { 59. /* Wales */ 60. "Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach", 61. "Rhaeader", "Llandrindod", "Llanfair-ym-muallt", 62. "Y-Fenni", "Maesteg", "Rhydaman", "Beddgelert", 63. "Curig", "Llanrwst", "Llanerchymedd", "Caergybi", 64. /* Scotland */ 65. "Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar", 66. "Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven", 67. "Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch", 68. "Kyleakin", "Dunvegan", 69. 0 70. }; 71.
Ring store
72. static const char * const shkrings[] = { 73. /* Hollandse familienamen */ 74. "Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken", 75. "Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy", 76. "Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix", 77. "Ypey", 78. /* Skandinaviske navne */ 79. "Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko", 80. "Enontekis", "Rovaniemi", "Avasaksa", "Haparanda", 81. "Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske", 82. 0 83. }; 84.
The reason for "Hollandse familienamen" may be that Andries Brouwer is Dutch. The list of ring shop names is unchanged since Hack 1.0.
Food store
85. static const char * const shkfoods[] = { 86. /* Indonesia */ 87. "Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan", 88. "Bandjar", "Parbalingga", "Bojolali", "Sarangan", 89. "Ngebel", "Djombang", "Ardjawinangun", "Berbek", 90. "Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi", 91. "Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan", 92. "Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe", 93. "Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe", 94. 0 95. }; 96.
Weapon store
97. static const char * const shkweapons[] = { 98. /* Perigord */ 99. "Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard", 100. "Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac", 101. "Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac", 102. "Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac", 103. "Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon", 104. "Eymoutiers", "Eygurande", "Eauze", "Labouheyre", 105. 0 106. }; 107.
Tool store
108. static const char * const shktools[] = { 109. /* Spmi */ 110. "Ymla", "Eed-morra", "Cubask", "Nieb", "Bnowr Falr", "Telloc Cyaj", 111. "Sperc", "Noskcirdneh", "Yawolloh", "Hyeghu", "Niskal", "Trahnil", 112. "Htargcm", "Enrobwem", "Kachzi Rellim", "Regien", "Donmyar", 113. "Yelpur", "Nosnehpets", "Stewe", "Renrut", "_Zlaw", "Nosalnef", 114. "Rewuorb", "Rellenk", "Yad", "Cire Htims", "Y-crad", "Nenilukah", 115. "Corsh", "Aned", 116. #ifdef OVERLAY 117. "Erreip", "Nehpets", "Mron", "Snivek", "Lapu", "Kahztiy", 118. #endif 119. #ifdef WIN32 120. "Lechaim", "Lexa", "Niod", 121. #endif 122. #ifdef MAC 123. "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s", 124. "Yao-hang", "Tonbar", "Kivenhoug", 125. #endif 126. #ifdef AMIGA 127. "Falo", "Nosid-da\'r", "Ekim-p", "Rebrol-nek", "Noslo", "Yl-rednow", 128. "Mured-oog", "Ivrajimsal", 129. #endif 130. #ifdef TOS 131. "Nivram", 132. #endif 133. #ifdef VMS 134. "Lez-tneg", "Ytnu-haled", "Niknar", 135. #endif 136. 0 137. }; 138.
"Spmi" is "imps" spelled backward. The tool store keeper names are anagrams of names of various Hack and NetHack developers; usually the names are spelled backwards. This RGRN post gives a nearly complete list as of the then-current version of NetHack. These are matched with the names, and a few more recent additions provided, in the following table.
The names in the OVERLAY section will not appear in any actual version of NetHack, as the 16-bit MS-DOS build is no longer supported (see MS-DOS).
Name | Named after |
---|---|
Ymla | Tom Almy |
Eed-morra | Ken Arromdee |
Cubask | Eric Backus |
Nieb | John S. Bien |
Bnowr Falr | Ralf Brown |
Telloc Cyaj | Jean-Christophe "JC" Collet |
Sperc | Steve Creps |
Noskcirdneh | Eric Hendrickson |
Yawolloh | Bruce Holloway |
Hyeghu | Richard P. Hughey |
Niskal | Greg Laskin |
Trahnil | Steve Linhart |
Htargcm | Roland McGrath |
Enrobwem | Bruce Mewborne |
Kachzi Rellim | Izchak Miller |
Regien | Gil Neiger |
Donmyar | Eric Raymond |
Yelpur | John Rupley |
Nosnehpets | Mike Stephenson |
Stewe | Kevin Sweet |
Renrut | Scott R Turner |
Zlaw | Janet Walz |
Nosalnef | Jay Fenlason |
Rewuorb | Andries Brouwer |
Rellenk | Don G Kneller |
Yad | Matt Day |
Cire Htims | Eric Smith |
Y-crad | Kevin Darcy |
Nenilukah | Timo Hakulinen |
Corsh | David Cohrs |
Aned | Dean Luick? |
Erreip | Pierre Martineau |
Nehpets | Stephen Spackman |
Mron | Norm Melluch |
Snivek | Kevin Smolkowski |
Lapu | Paul Winner |
Kahztiy | Yitzhak Sapir |
Lechaim | Michael Allison |
Lexa | Alex Kompel |
Niod | Dion Nicolaas |
Nhoj-lee | Johnny Lee |
Evad'kh | Dave KH? |
Ettaw-noj | Jon Watte |
Tsew-mot | Tom West |
Ydna-s | Andy Swanson |
Yao-hang | Hao-yang Wang |
Tonbar | Barton House |
Kivenhoug | Kevin Hugo |
Falo | Olaf Seibert |
Nosid-da'r | Richard Addison |
Ekim-p | Mike Passaretti |
Rebrol-nek | Ken Lorber |
Noslo | Greg Olson |
Yl-rednow | Gregg Wonderly |
Mured-oog | Mark Gooderum |
Ivrajimsal | Janne Salmijarvi |
Nivram | Christian "Marvin" Bressler |
Lez-tneg | David Gentzel |
Ytnu-haled | Joshua Delahunty |
Niknar | Pat Rankin |
Light store
139. static const char * const shklight[] = { 140. /* Romania */ 141. "Zarnesti", "Slanic", "Nehoiasu", "Ludus", "Sighisoara", "Nisipitu", 142. "Razboieni", "Bicaz", "Dorohoi", "Vaslui", "Fetesti", "Tirgu Neamt", 143. "Babadag", "Zimnicea", "Zlatna", "Jiu", "Eforie", "Mamaia", 144. /* Bulgaria */ 145. "Silistra", "Tulovo", "Panagyuritshte", "Smolyan", "Kirklareli", 146. "Pernik", "Lom", "Haskovo", "Dobrinishte", "Varvara", "Oryahovo", 147. "Troyan", "Lovech", "Sliven", 148. 0 149. }; 150.
These names were introduced in NetHack 3.1.2, but have been in disuse since NetHack 3.2.0. An unmodified game has only one lighting store, and its keeper is Izchak.
SLASH'EM can generate a lighting store in the "mall" level of its main dungeon; its keeper will have a name from the above list.
General store
151. static const char * const shkgeneral[] = { 152. /* Suriname */ 153. "Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi", 154. "Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo", 155. "Akalapi", "Sipaliwini", 156. /* Greenland */ 157. "Annootok", "Upernavik", "Angmagssalik", 158. /* N. Canada */ 159. "Aklavik", "Inuvik", "Tuktoyaktuk", 160. "Chicoutimi", "Ouiatchouane", "Chibougamau", 161. "Matagami", "Kipawa", "Kinojevis", 162. "Abitibi", "Maganasipi", 163. /* Iceland */ 164. "Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri", 165. "Holmavik", 166. 0 167. }; 168.
shtypes
169. /* 170. * To add new shop types, all that is necessary is to edit the shtypes[] array. 171. * See mkroom.h for the structure definition. Typically, you'll have to lower 172. * some or all of the probability fields in old entries to free up some 173. * percentage for the new type. 174. * 175. * The placement type field is not yet used but will be in the near future. 176. * 177. * The iprobs array in each entry defines the probabilities for various kinds 178. * of objects to be present in the given shop type. You can associate with 179. * each percentage either a generic object type (represented by one of the 180. * *_CLASS macros) or a specific object (represented by an onames.h define). 181. * In the latter case, prepend it with a unary minus so the code can know 182. * (by testing the sign) whether to use mkobj() or mksobj(). 183. */ 184. 185. const struct shclass shtypes[] = { 186. {"general store", RANDOM_CLASS, 44, 187. D_SHOP, {{100, RANDOM_CLASS}, {0, 0}, {0, 0}}, shkgeneral}, 188. {"used armor dealership", ARMOR_CLASS, 14, 189. D_SHOP, {{90, ARMOR_CLASS}, {10, WEAPON_CLASS}, {0, 0}}, 190. shkarmors}, 191. {"second-hand bookstore", SCROLL_CLASS, 10, D_SHOP, 192. {{90, SCROLL_CLASS}, {10, SPBOOK_CLASS}, {0, 0}}, shkbooks}, 193. {"liquor emporium", POTION_CLASS, 10, D_SHOP, 194. {{100, POTION_CLASS}, {0, 0}, {0, 0}}, shkliquors}, 195. {"antique weapons outlet", WEAPON_CLASS, 5, D_SHOP, 196. {{90, WEAPON_CLASS}, {10, ARMOR_CLASS}, {0, 0}}, shkweapons}, 197. {"delicatessen", FOOD_CLASS, 5, D_SHOP, 198. {{83, FOOD_CLASS}, {5, -POT_FRUIT_JUICE}, {4, -POT_BOOZE}, 199. {5, -POT_WATER}, {3, -ICE_BOX}}, shkfoods}, 200. {"jewelers", RING_CLASS, 3, D_SHOP, 201. {{85, RING_CLASS}, {10, GEM_CLASS}, {5, AMULET_CLASS}, {0, 0}}, 202. shkrings}, 203. {"quality apparel and accessories", WAND_CLASS, 3, D_SHOP, 204. {{90, WAND_CLASS}, {5, -LEATHER_GLOVES}, {5, -ELVEN_CLOAK}, {0, 0}}, 205. shkwands}, 206. {"hardware store", TOOL_CLASS, 3, D_SHOP, 207. {{100, TOOL_CLASS}, {0, 0}, {0, 0}}, shktools}, 208. /* Actually shktools is ignored; the code specifically chooses a 209. * random implementor name (along with candle shops having 210. * random shopkeepers) 211. */ 212. {"rare books", SPBOOK_CLASS, 3, D_SHOP, 213. {{90, SPBOOK_CLASS}, {10, SCROLL_CLASS}, {0, 0}}, shkbooks}, 214. /* Shops below this point are "unique". That is they must all have a 215. * probability of zero. They are only created via the special level 216. * loader. 217. */ 218. {"lighting store", TOOL_CLASS, 0, D_SHOP, 219. {{32, -WAX_CANDLE}, {50, -TALLOW_CANDLE}, 220. {5, -BRASS_LANTERN}, {10, -OIL_LAMP}, {3, -MAGIC_LAMP}}, shklight}, 221. {(char *)0, 0, 0, 0, {{0, 0}, {0, 0}, {0, 0}}, 0} 222. }; 223.
init_shop_selection
224. #if 0 225. /* validate shop probabilities; otherwise incorrect local changes could 226. end up provoking infinite loops or wild subscripts fetching garbage */ 227. void 228. init_shop_selection() 229. { 230. register int i, j, item_prob, shop_prob; 231. 232. for (shop_prob = 0, i = 0; i < SIZE(shtypes); i++) { 233. shop_prob += shtypes[i].prob; 234. for (item_prob = 0, j = 0; j < SIZE(shtypes[0].iprobs); j++) 235. item_prob += shtypes[i].iprobs[j].iprob; 236. if (item_prob != 100) 237. panic("item probabilities total to %d for %s shops!", 238. item_prob, shtypes[i].name); 239. } 240. if (shop_prob != 100) 241. panic("shop probabilities total to %d!", shop_prob); 242. } 243. #endif /*0*/ 244.
mkshobj_at
245. STATIC_OVL void 246. mkshobj_at(shp, sx, sy) 247. /* make an object of the appropriate type for a shop square */ 248. const struct shclass *shp; 249. int sx, sy; 250. { 251. struct monst *mtmp; 252. int atype; 253. struct permonst *ptr; 254. 255. if (rn2(100) < depth(&u.uz) && 256. !MON_AT(sx, sy) && (ptr = mkclass(S_MIMIC,0)) && 257. (mtmp = makemon(ptr,sx,sy,NO_MM_FLAGS)) != 0) { 258. /* note: makemon will set the mimic symbol to a shop item */ 259. if (rn2(10) >= depth(&u.uz)) { 260. mtmp->m_ap_type = M_AP_OBJECT; 261. mtmp->mappearance = STRANGE_OBJECT; 262. } 263. } else { 264. atype = get_shop_item(shp - shtypes); 265. if (atype < 0) 266. (void) mksobj_at(-atype, sx, sy, TRUE, TRUE); 267. else 268. (void) mkobj_at(atype, sx, sy, TRUE); 269. } 270. } 271.
nameshk
272. /* extract a shopkeeper name for the given shop type */ 273. STATIC_OVL void 274. nameshk(shk, nlp) 275. struct monst *shk; 276. const char * const *nlp; 277. { 278. int i, trycnt, names_avail; 279. const char *shname = 0; 280. struct monst *mtmp; 281. int name_wanted; 282. s_level *sptr; 283. 284. if (nlp == shklight && In_mines(&u.uz) 285. && (sptr = Is_special(&u.uz)) != 0 && sptr->flags.town) { 286. /* special-case minetown lighting shk */ 287. shname = "Izchak"; 288. shk->female = FALSE; 289. } else { 290. /* We want variation from game to game, without needing the save 291. and restore support which would be necessary for randomization; 292. try not to make too many assumptions about time_t's internals; 293. use ledger_no rather than depth to keep mine town distinct. */ 294. int nseed = (int)((long)u.ubirthday / 257L); 295. 296. name_wanted = ledger_no(&u.uz) + (nseed % 13) - (nseed % 5); 297. if (name_wanted < 0) name_wanted += (13 + 5); 298. shk->female = name_wanted & 1; 299. 300. for (names_avail = 0; nlp[names_avail]; names_avail++) 301. continue; 302. 303. for (trycnt = 0; trycnt < 50; trycnt++) { 304. if (nlp == shktools) { 305. shname = shktools[rn2(names_avail)]; 306. shk->female = (*shname == '_'); 307. if (shk->female) shname++; 308. } else if (name_wanted < names_avail) { 309. shname = nlp[name_wanted]; 310. } else if ((i = rn2(names_avail)) != 0) { 311. shname = nlp[i - 1]; 312. } else if (nlp != shkgeneral) { 313. nlp = shkgeneral; /* try general names */ 314. for (names_avail = 0; nlp[names_avail]; names_avail++) 315. continue; 316. continue; /* next `trycnt' iteration */ 317. } else { 318. shname = shk->female ? "Lucrezia" : "Dirk"; 319. } 320. 321. /* is name already in use on this level? */ 322. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 323. if (DEADMONSTER(mtmp) || (mtmp == shk) || !mtmp->isshk) continue; 324. if (strcmp(ESHK(mtmp)->shknam, shname)) continue; 325. break; 326. } 327. if (!mtmp) break; /* new name */ 328. } 329. } 330. (void) strncpy(ESHK(shk)->shknam, shname, PL_NSIZ); 331. ESHK(shk)->shknam[PL_NSIZ-1] = 0; 332. } 333.
shkinit
334. STATIC_OVL int 335. shkinit(shp, sroom) /* create a new shopkeeper in the given room */ 336. const struct shclass *shp; 337. struct mkroom *sroom; 338. { 339. register int sh, sx, sy; 340. struct monst *shk; 341. 342. /* place the shopkeeper in the given room */ 343. sh = sroom->fdoor; 344. sx = doors[sh].x; 345. sy = doors[sh].y; 346. 347. /* check that the shopkeeper placement is sane */ 348. if(sroom->irregular) { 349. int rmno = (sroom - rooms) + ROOMOFFSET; 350. if (isok(sx-1,sy) && !levl[sx-1][sy].edge && 351. (int) levl[sx-1][sy].roomno == rmno) sx--; 352. else if (isok(sx+1,sy) && !levl[sx+1][sy].edge && 353. (int) levl[sx+1][sy].roomno == rmno) sx++; 354. else if (isok(sx,sy-1) && !levl[sx][sy-1].edge && 355. (int) levl[sx][sy-1].roomno == rmno) sy--; 356. else if (isok(sx,sy+1) && !levl[sx][sy+1].edge && 357. (int) levl[sx][sy+1].roomno == rmno) sx++; 358. else goto shk_failed; 359. } 360. else if(sx == sroom->lx-1) sx++; 361. else if(sx == sroom->hx+1) sx--; 362. else if(sy == sroom->ly-1) sy++; 363. else if(sy == sroom->hy+1) sy--; else { 364. shk_failed: 365. #ifdef DEBUG 366. # ifdef WIZARD 367. /* Said to happen sometimes, but I have never seen it. */ 368. /* Supposedly fixed by fdoor change in mklev.c */ 369. if(wizard) { 370. register int j = sroom->doorct; 371. 372. pline("Where is shopdoor?"); 373. pline("Room at (%d,%d),(%d,%d).", 374. sroom->lx, sroom->ly, sroom->hx, sroom->hy); 375. pline("doormax=%d doorct=%d fdoor=%d", 376. doorindex, sroom->doorct, sh); 377. while(j--) { 378. pline("door [%d,%d]", doors[sh].x, doors[sh].y); 379. sh++; 380. } 381. display_nhwindow(WIN_MESSAGE, FALSE); 382. } 383. # endif 384. #endif 385. return(-1); 386. } 387. 388. if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), FALSE); /* insurance */ 389. 390. /* now initialize the shopkeeper monster structure */ 391. if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS))) 392. return(-1); 393. shk->isshk = shk->mpeaceful = 1; 394. set_malign(shk); 395. shk->msleeping = 0; 396. shk->mtrapseen = ~0; /* we know all the traps already */ 397. ESHK(shk)->shoproom = (sroom - rooms) + ROOMOFFSET; 398. sroom->resident = shk; 399. ESHK(shk)->shoptype = sroom->rtype; 400. assign_level(&(ESHK(shk)->shoplevel), &u.uz); 401. ESHK(shk)->shd = doors[sh]; 402. ESHK(shk)->shk.x = sx; 403. ESHK(shk)->shk.y = sy; 404. ESHK(shk)->robbed = 0L; 405. ESHK(shk)->credit = 0L; 406. ESHK(shk)->debit = 0L; 407. ESHK(shk)->loan = 0L; 408. ESHK(shk)->visitct = 0; 409. ESHK(shk)->following = 0; 410. ESHK(shk)->billct = 0; 411. #ifndef GOLDOBJ 412. shk->mgold = 1000L + 30L*(long)rnd(100); /* initial capital */ 413. #else 414. mkmonmoney(shk, 1000L + 30L*(long)rnd(100)); /* initial capital */ 415. #endif 416. if (shp->shknms == shkrings) 417. (void) mongets(shk, TOUCHSTONE); 418. nameshk(shk, shp->shknms); 419. 420. return(sh); 421. } 422.
stock_room
423. /* stock a newly-created room with objects */ 424. void 425. stock_room(shp_indx, sroom) 426. int shp_indx; 427. register struct mkroom *sroom; 428. { 429. /* 430. * Someday soon we'll dispatch on the shdist field of shclass to do 431. * different placements in this routine. Currently it only supports 432. * shop-style placement (all squares except a row nearest the first 433. * door get objects). 434. */ 435. register int sx, sy, sh; 436. char buf[BUFSZ]; 437. int rmno = (sroom - rooms) + ROOMOFFSET; 438. const struct shclass *shp = &shtypes[shp_indx]; 439. 440. /* first, try to place a shopkeeper in the room */ 441. if ((sh = shkinit(shp, sroom)) < 0) 442. return; 443. 444. /* make sure no doorways without doors, and no */ 445. /* trapped doors, in shops. */ 446. sx = doors[sroom->fdoor].x; 447. sy = doors[sroom->fdoor].y; 448. 449. if(levl[sx][sy].doormask == D_NODOOR) { 450. levl[sx][sy].doormask = D_ISOPEN; 451. newsym(sx,sy); 452. } 453. if(levl[sx][sy].typ == SDOOR) { 454. cvt_sdoor_to_door(&levl[sx][sy]); /* .typ = DOOR */ 455. newsym(sx,sy); 456. } 457. if(levl[sx][sy].doormask & D_TRAPPED) 458. levl[sx][sy].doormask = D_LOCKED; 459. 460. if(levl[sx][sy].doormask == D_LOCKED) { 461. register int m = sx, n = sy; 462. 463. if(inside_shop(sx+1,sy)) m--; 464. else if(inside_shop(sx-1,sy)) m++; 465. if(inside_shop(sx,sy+1)) n--; 466. else if(inside_shop(sx,sy-1)) n++; 467. Sprintf(buf, "Closed for inventory"); 468. make_engr_at(m, n, buf, 0L, DUST); 469. } 470. 471. for(sx = sroom->lx; sx <= sroom->hx; sx++) 472. for(sy = sroom->ly; sy <= sroom->hy; sy++) { 473. if(sroom->irregular) { 474. if (levl[sx][sy].edge || (int) levl[sx][sy].roomno != rmno || 475. distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1) 476. continue; 477. } else if((sx == sroom->lx && doors[sh].x == sx-1) || 478. (sx == sroom->hx && doors[sh].x == sx+1) || 479. (sy == sroom->ly && doors[sh].y == sy-1) || 480. (sy == sroom->hy && doors[sh].y == sy+1)) continue; 481. mkshobj_at(shp, sx, sy); 482. } 483. 484. /* 485. * Special monster placements (if any) should go here: that way, 486. * monsters will sit on top of objects and not the other way around. 487. */ 488. 489. level.flags.has_shop = TRUE; 490. } 491. 492. #endif /* OVLB */
saleable
493. #ifdef OVL0 494. 495. /* does shkp's shop stock this item type? */ 496. boolean 497. saleable(shkp, obj) 498. struct monst *shkp; 499. struct obj *obj; 500. { 501. int i, shp_indx = ESHK(shkp)->shoptype - SHOPBASE; 502. const struct shclass *shp = &shtypes[shp_indx]; 503. 504. if (shp->symb == RANDOM_CLASS) return TRUE; 505. else for (i = 0; i < SIZE(shtypes[0].iprobs) && shp->iprobs[i].iprob; i++) 506. if (shp->iprobs[i].itype < 0 ? 507. shp->iprobs[i].itype == - obj->otyp : 508. shp->iprobs[i].itype == obj->oclass) return TRUE; 509. /* not found */ 510. return FALSE; 511. } 512.
get_shop_item
513. /* positive value: class; negative value: specific object type */ 514. int 515. get_shop_item(type) 516. int type; 517. { 518. const struct shclass *shp = shtypes+type; 519. register int i,j; 520. 521. /* select an appropriate object type at random */ 522. for(j = rnd(100), i = 0; (j -= shp->iprobs[i].iprob) > 0; i++) 523. continue; 524. 525. return shp->iprobs[i].itype; 526. } 527. 528. #endif /* OVL0 */ 529. 530. /*shknam.c*/