Source:NetHack 3.4.0/shknam.c

From NetHackWiki
Revision as of 14:00, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.4.0/shknam.c moved to Source:NetHack 3.4.0/shknam.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to shknam.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/shknam.c#line123]], for example.

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