OSDN Git Service

update year to 2020
[jnethack/source.git] / src / shknam.c
1 /* NetHack 3.6  shknam.c        $NHDT-Date: 1454485432 2016/02/03 07:43:52 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* shknam.c -- initialize a shop */
7
8 /* JNetHack Copyright */
9 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
10 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
11 /* JNetHack may be freely redistributed.  See license for details. */
12
13 #include "hack.h"
14
15 STATIC_DCL boolean FDECL(stock_room_goodpos, (struct mkroom *, int, int, int, int));
16 STATIC_DCL boolean FDECL(veggy_item, (struct obj * obj, int));
17 STATIC_DCL int NDECL(shkveg);
18 STATIC_DCL void FDECL(mkveggy_at, (int, int));
19 STATIC_DCL void FDECL(mkshobj_at, (const struct shclass *, int, int,
20                                    BOOLEAN_P));
21 STATIC_DCL void FDECL(nameshk, (struct monst *, const char *const *));
22 STATIC_DCL int FDECL(shkinit, (const struct shclass *, struct mkroom *));
23
24 #define VEGETARIAN_CLASS (MAXOCLASSES + 1)
25
26 /*
27  *  Name prefix codes:
28  *      dash          -  female, personal name
29  *      underscore    _  female, general name
30  *      plus          +  male, personal name
31  *      vertical bar  |  male, general name (implied for most of shktools)
32  *      equals        =  gender not specified, personal name
33  *
34  *  Personal names do not receive the honorific prefix "Mr." or "Ms.".
35  */
36
37 static const char *const shkliquors[] = {
38     /* Ukraine */
39     "Njezjin", "Tsjernigof", "Ossipewsk", "Gorlowka",
40     /* Belarus */
41     "Gomel",
42     /* N. Russia */
43     "Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja", "Narodnaja", "Kyzyl",
44     /* Silezie */
45     "Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice", "Brzeg",
46     "Krnov", "Hradec Kralove",
47     /* Schweiz */
48     "Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm", "Flims",
49     "Vals", "Schuls", "Zum Loch", 0
50 };
51
52 static const char *const shkbooks[] = {
53     /* Eire */
54     "Skibbereen",  "Kanturk",   "Rath Luirc",     "Ennistymon",
55     "Lahinch",     "Kinnegad",  "Lugnaquillia",   "Enniscorthy",
56     "Gweebarra",   "Kittamagh", "Nenagh",         "Sneem",
57     "Ballingeary", "Kilgarvan", "Cahersiveen",    "Glenbeigh",
58     "Kilmihil",    "Kiltamagh", "Droichead Atha", "Inniscrone",
59     "Clonegal",    "Lisnaskea", "Culdaff",        "Dunfanaghy",
60     "Inishbofin",  "Kesh",      0
61 };
62
63 static const char *const shkarmors[] = {
64     /* Turquie */
65     "Demirci",    "Kalecik",    "Boyabai",    "Yildizeli", "Gaziantep",
66     "Siirt",      "Akhalataki", "Tirebolu",   "Aksaray",   "Ermenak",
67     "Iskenderun", "Kadirli",    "Siverek",    "Pervari",   "Malasgirt",
68     "Bayburt",    "Ayancik",    "Zonguldak",  "Balya",     "Tefenni",
69     "Artvin",     "Kars",       "Makharadze", "Malazgirt", "Midyat",
70     "Birecik",    "Kirikkale",  "Alaca",      "Polatli",   "Nallihan",
71     0
72 };
73
74 static const char *const shkwands[] = {
75     /* Wales */
76     "Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach", "Rhaeader",
77     "Llandrindod", "Llanfair-ym-muallt", "Y-Fenni", "Maesteg", "Rhydaman",
78     "Beddgelert", "Curig", "Llanrwst", "Llanerchymedd", "Caergybi",
79     /* Scotland */
80     "Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar", "Kerloch",
81     "Beinn a Ghlo", "Drumnadrochit", "Morven", "Uist", "Storr",
82     "Sgurr na Ciche", "Cannich", "Gairloch", "Kyleakin", "Dunvegan", 0
83 };
84
85 static const char *const shkrings[] = {
86     /* Hollandse familienamen */
87     "Feyfer",     "Flugi",         "Gheel",      "Havic",   "Haynin",
88     "Hoboken",    "Imbyze",        "Juyn",       "Kinsky",  "Massis",
89     "Matray",     "Moy",           "Olycan",     "Sadelin", "Svaving",
90     "Tapper",     "Terwen",        "Wirix",      "Ypey",
91     /* Skandinaviske navne */
92     "Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",  "Enontekis",
93     "Rovaniemi",  "Avasaksa",      "Haparanda",  "Lulea",   "Gellivare",
94     "Oeloe",      "Kajaani",       "Fauske",     0
95 };
96
97 static const char *const shkfoods[] = {
98     /* Indonesia */
99     "Djasinga",    "Tjibarusa",   "Tjiwidej",      "Pengalengan",
100     "Bandjar",     "Parbalingga", "Bojolali",      "Sarangan",
101     "Ngebel",      "Djombang",    "Ardjawinangun", "Berbek",
102     "Papar",       "Baliga",      "Tjisolok",      "Siboga",
103     "Banjoewangi", "Trenggalek",  "Karangkobar",   "Njalindoeng",
104     "Pasawahan",   "Pameunpeuk",  "Patjitan",      "Kediri",
105     "Pemboeang",   "Tringanoe",   "Makin",         "Tipor",
106     "Semai",       "Berhala",     "Tegal",         "Samoe",
107     0
108 };
109
110 static const char *const shkweapons[] = {
111     /* Perigord */
112     "Voulgezac",   "Rouffiac",   "Lerignac",   "Touverac",  "Guizengeard",
113     "Melac",       "Neuvicq",    "Vanzac",     "Picq",      "Urignac",
114     "Corignac",    "Fleac",      "Lonzac",     "Vergt",     "Queyssac",
115     "Liorac",      "Echourgnac", "Cazelon",    "Eypau",     "Carignan",
116     "Monbazillac", "Jonzac",     "Pons",       "Jumilhac",  "Fenouilledes",
117     "Laguiolet",   "Saujon",     "Eymoutiers", "Eygurande", "Eauze",
118     "Labouheyre",  0
119 };
120
121 static const char *const shktools[] = {
122     /* Spmi */
123     "Ymla", "Eed-morra", "Elan Lapinski", "Cubask", "Nieb", "Bnowr Falr",
124     "Sperc", "Noskcirdneh", "Yawolloh", "Hyeghu", "Niskal", "Trahnil",
125     "Htargcm", "Enrobwem", "Kachzi Rellim", "Regien", "Donmyar", "Yelpur",
126     "Nosnehpets", "Stewe", "Renrut", "Senna Hut", "-Zlaw", "Nosalnef",
127     "Rewuorb", "Rellenk", "Yad", "Cire Htims", "Y-crad", "Nenilukah",
128     "Corsh", "Aned", "Dark Eery", "Niknar", "Lapu", "Lechaim",
129     "Rebrol-nek", "AlliWar Wickson", "Oguhmk", "Telloc Cyaj",
130 #ifdef OVERLAY
131     "Erreip", "Nehpets", "Mron", "Snivek", "Kahztiy",
132 #endif
133 #ifdef WIN32
134     "Lexa", "Niod",
135 #endif
136 #ifdef MAC
137     "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s", "Yao-hang",
138     "Tonbar", "Kivenhoug", "Llardom",
139 #endif
140 #ifdef AMIGA
141     "Falo", "Nosid-da\'r", "Ekim-p", "Noslo", "Yl-rednow", "Mured-oog",
142     "Ivrajimsal",
143 #endif
144 #ifdef TOS
145     "Nivram",
146 #endif
147 #ifdef OS2
148     "Nedraawi-nav",
149 #endif
150 #ifdef VMS
151     "Lez-tneg", "Ytnu-haled",
152 #endif
153     0
154 };
155
156 static const char *const shklight[] = {
157     /* Romania */
158     "Zarnesti", "Slanic", "Nehoiasu", "Ludus", "Sighisoara", "Nisipitu",
159     "Razboieni", "Bicaz", "Dorohoi", "Vaslui", "Fetesti", "Tirgu Neamt",
160     "Babadag", "Zimnicea", "Zlatna", "Jiu", "Eforie", "Mamaia",
161     /* Bulgaria */
162     "Silistra", "Tulovo", "Panagyuritshte", "Smolyan", "Kirklareli", "Pernik",
163     "Lom", "Haskovo", "Dobrinishte", "Varvara", "Oryahovo", "Troyan",
164     "Lovech", "Sliven", 0
165 };
166
167 static const char *const shkgeneral[] = {
168     /* Suriname */
169     "Hebiwerie",    "Possogroenoe", "Asidonhopo",   "Manlobbi",
170     "Adjama",       "Pakka Pakka",  "Kabalebo",     "Wonotobo",
171     "Akalapi",      "Sipaliwini",
172     /* Greenland */
173     "Annootok",     "Upernavik",    "Angmagssalik",
174     /* N. Canada */
175     "Aklavik",      "Inuvik",       "Tuktoyaktuk",  "Chicoutimi",
176     "Ouiatchouane", "Chibougamau",  "Matagami",     "Kipawa",
177     "Kinojevis",    "Abitibi",      "Maganasipi",
178     /* Iceland */
179     "Akureyri",     "Kopasker",     "Budereyri",    "Akranes",
180     "Bordeyri",     "Holmavik",     0
181 };
182
183 static const char *const shkhealthfoods[] = {
184     /* Tibet */
185     "Ga'er",    "Zhangmu",   "Rikaze",   "Jiangji",     "Changdu",
186     "Linzhi",   "Shigatse",  "Gyantse",  "Ganden",      "Tsurphu",
187     "Lhasa",    "Tsedong",   "Drepung",
188     /* Hippie names */
189     "=Azura",   "=Blaze",    "=Breanna", "=Breezy",     "=Dharma",
190     "=Feather", "=Jasmine",  "=Luna",    "=Melody",     "=Moonjava",
191     "=Petal",   "=Rhiannon", "=Starla",  "=Tranquilla", "=Windsong",
192     "=Zennia",  "=Zoe",      "=Zora",    0
193 };
194
195 /*
196  * To add new shop types, all that is necessary is to edit the shtypes[]
197  * array.  See mkroom.h for the structure definition.  Typically, you'll
198  * have to lower some or all of the probability fields in old entries to
199  * free up some percentage for the new type.
200  *
201  * The placement type field is not yet used but will be in the near future.
202  *
203  * The iprobs array in each entry defines the probabilities for various kinds
204  * of objects to be present in the given shop type.  You can associate with
205  * each percentage either a generic object type (represented by one of the
206  * *_CLASS macros) or a specific object (represented by an onames.h define).
207  * In the latter case, prepend it with a unary minus so the code can know
208  * (by testing the sign) whether to use mkobj() or mksobj().
209  */
210 const struct shclass shtypes[] = {
211 /*JP
212     { "general store",
213 */
214     { "\8eG\89Ý\89®",
215       RANDOM_CLASS,
216       42,
217       D_SHOP,
218       { { 100, RANDOM_CLASS },
219         { 0, 0 },
220         { 0, 0 },
221         { 0, 0 },
222         { 0, 0 },
223         { 0, 0 } },
224       shkgeneral },
225 /*JP
226     { "used armor dealership",
227 */
228     { "\92\86\8cÃ\8aZ\8f¤\89ï",
229       ARMOR_CLASS,
230       14,
231       D_SHOP,
232       { { 90, ARMOR_CLASS },
233         { 10, WEAPON_CLASS },
234         { 0, 0 },
235         { 0, 0 },
236         { 0, 0 },
237         { 0, 0 } },
238       shkarmors },
239 /*JP
240     { "second-hand bookstore",
241 */
242     { "\8cÃ\8f\91\93X",
243       SCROLL_CLASS,
244       10,
245       D_SHOP,
246       { { 90, SCROLL_CLASS },
247         { 10, SPBOOK_CLASS },
248         { 0, 0 },
249         { 0, 0 },
250         { 0, 0 },
251         { 0, 0 } },
252       shkbooks },
253 /*JP
254     { "liquor emporium",
255 */
256     {"\82¨\8eð\82Ì\95S\89Ý\93X",
257       POTION_CLASS,
258       10,
259       D_SHOP,
260       { { 100, POTION_CLASS },
261         { 0, 0 },
262         { 0, 0 },
263         { 0, 0 },
264         { 0, 0 },
265         { 0, 0 } },
266       shkliquors },
267 /*JP
268     { "antique weapons outlet",
269 */
270     { "\8cÃ\95\90\8aí\90ê\96å\8f¬\94\84\93X",
271       WEAPON_CLASS,
272       5,
273       D_SHOP,
274       { { 90, WEAPON_CLASS },
275         { 10, ARMOR_CLASS },
276         { 0, 0 },
277         { 0, 0 },
278         { 0, 0 },
279         { 0, 0 } },
280       shkweapons },
281 /*JP
282     { "delicatessen",
283 */
284     { "\90H\95i\93X",
285       FOOD_CLASS,
286       5,
287       D_SHOP,
288       { { 83, FOOD_CLASS },
289         { 5, -POT_FRUIT_JUICE },
290         { 4, -POT_BOOZE },
291         { 5, -POT_WATER },
292         { 3, -ICE_BOX },
293         { 0, 0 } },
294       shkfoods },
295 /*JP
296     { "jewelers",
297 */
298     { "\95ó\90Î\93X",
299       RING_CLASS,
300       3,
301       D_SHOP,
302       { { 85, RING_CLASS },
303         { 10, GEM_CLASS },
304         { 5, AMULET_CLASS },
305         { 0, 0 },
306         { 0, 0 },
307         { 0, 0 } },
308       shkrings },
309 /*JP
310     { "quality apparel and accessories",
311 */
312     { "\82¨\83V\83\83\83\8c\82È\97m\95i\93X",
313       WAND_CLASS,
314       3,
315       D_SHOP,
316       { { 90, WAND_CLASS },
317         { 5, -LEATHER_GLOVES },
318         { 5, -ELVEN_CLOAK },
319         { 0, 0 } },
320       shkwands },
321 /*JP
322     { "hardware store",
323 */
324     { "\93¹\8bï\89®",
325       TOOL_CLASS,
326       3,
327       D_SHOP,
328       { { 100, TOOL_CLASS },
329         { 0, 0 },
330         { 0, 0 },
331         { 0, 0 },
332         { 0, 0 },
333         { 0, 0 } },
334       shktools },
335 /*JP
336     { "rare books",
337 */
338     { "\8c\82Ì\96{\89®",
339       SPBOOK_CLASS,
340       3,
341       D_SHOP,
342       { { 90, SPBOOK_CLASS },
343         { 10, SCROLL_CLASS },
344         { 0, 0 },
345         { 0, 0 },
346         { 0, 0 },
347         { 0, 0 } },
348       shkbooks },
349 /*JP
350     { "health food store",
351 */
352     { "\8c\92\8dN\90H\95i\82Ì\93X",
353       FOOD_CLASS,
354       2,
355       D_SHOP,
356       { { 70, VEGETARIAN_CLASS },
357         { 20, -POT_FRUIT_JUICE },
358         { 4, -POT_HEALING },
359         { 3, -POT_FULL_HEALING },
360         { 2, -SCR_FOOD_DETECTION },
361         { 1, -LUMP_OF_ROYAL_JELLY } },
362       shkhealthfoods },
363     /* Shops below this point are "unique".  That is they must all have a
364      * probability of zero.  They are only created via the special level
365      * loader.
366      */
367 /*JP
368     { "lighting store",
369 */
370     { "\8fÆ\96¾\93X",
371       TOOL_CLASS,
372       0,
373       D_SHOP,
374       { { 30, -WAX_CANDLE },
375         { 48, -TALLOW_CANDLE },
376         { 5, -BRASS_LANTERN },
377         { 9, -OIL_LAMP },
378         { 3, -MAGIC_LAMP },
379         { 5, -POT_OIL } },
380       shklight },
381     /* sentinel */
382     { (char *) 0,
383       0,
384       0,
385       0,
386       { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
387       0 }
388 };
389
390 #if 0
391 /* validate shop probabilities; otherwise incorrect local changes could
392    end up provoking infinite loops or wild subscripts fetching garbage */
393 void
394 init_shop_selection()
395 {
396     register int i, j, item_prob, shop_prob;
397
398     for (shop_prob = 0, i = 0; i < SIZE(shtypes); i++) {
399         shop_prob += shtypes[i].prob;
400         for (item_prob = 0, j = 0; j < SIZE(shtypes[0].iprobs); j++)
401             item_prob += shtypes[i].iprobs[j].iprob;
402         if (item_prob != 100)
403             panic("item probabilities total to %d for %s shops!",
404                   item_prob, shtypes[i].name);
405     }
406     if (shop_prob != 100)
407         panic("shop probabilities total to %d!", shop_prob);
408 }
409 #endif /*0*/
410
411 /* decide whether an object or object type is considered vegetarian;
412    for types, items which might go either way are assumed to be veggy */
413 STATIC_OVL boolean
414 veggy_item(obj, otyp)
415 struct obj *obj;
416 int otyp; /* used iff obj is null */
417 {
418     int corpsenm;
419     char oclass;
420
421     if (obj) {
422         /* actual object; will check tin content and corpse species */
423         otyp = (int) obj->otyp;
424         oclass = obj->oclass;
425         corpsenm = obj->corpsenm;
426     } else {
427         /* just a type; caller will have to handle tins and corpses */
428         oclass = objects[otyp].oc_class;
429         corpsenm = PM_LICHEN; /* veggy standin */
430     }
431
432     if (oclass == FOOD_CLASS) {
433         if (objects[otyp].oc_material == VEGGY || otyp == EGG)
434             return TRUE;
435         if (otyp == TIN && corpsenm == NON_PM) /* implies obj is non-null */
436             return (boolean) (obj->spe == 1); /* 0 = empty, 1 = spinach */
437         if (otyp == TIN || otyp == CORPSE)
438             return (boolean) (corpsenm >= LOW_PM
439                               && vegetarian(&mons[corpsenm]));
440     }
441     return FALSE;
442 }
443
444 STATIC_OVL int
445 shkveg()
446 {
447     int i, j, maxprob, prob;
448     char oclass = FOOD_CLASS;
449     int ok[NUM_OBJECTS];
450
451     j = maxprob = 0;
452     ok[0] = 0; /* lint suppression */
453     for (i = bases[(int) oclass]; i < NUM_OBJECTS; ++i) {
454         if (objects[i].oc_class != oclass)
455             break;
456
457         if (veggy_item((struct obj *) 0, i)) {
458             ok[j++] = i;
459             maxprob += objects[i].oc_prob;
460         }
461     }
462     if (maxprob < 1)
463         panic("shkveg no veggy objects");
464     prob = rnd(maxprob);
465
466     j = 0;
467     i = ok[0];
468     while ((prob -= objects[i].oc_prob) > 0) {
469         j++;
470         i = ok[j];
471     }
472
473     if (objects[i].oc_class != oclass || !OBJ_NAME(objects[i]))
474         panic("shkveg probtype error, oclass=%d i=%d", (int) oclass, i);
475     return i;
476 }
477
478 /* make a random item for health food store */
479 STATIC_OVL void
480 mkveggy_at(sx, sy)
481 int sx, sy;
482 {
483     struct obj *obj = mksobj_at(shkveg(), sx, sy, TRUE, TRUE);
484
485     if (obj && obj->otyp == TIN)
486         set_tin_variety(obj, HEALTHY_TIN);
487     return;
488 }
489
490 /* make an object of the appropriate type for a shop square */
491 STATIC_OVL void
492 mkshobj_at(shp, sx, sy, mkspecl)
493 const struct shclass *shp;
494 int sx, sy;
495 boolean mkspecl;
496 {
497     struct monst *mtmp;
498     struct permonst *ptr;
499     int atype;
500
501     /* 3.6 tribute */
502 #if 0 /*JP:T*/
503     if (mkspecl && (!strcmp(shp->name, "rare books")
504                     || !strcmp(shp->name, "second-hand bookstore"))) {
505 #else
506     if (mkspecl && (!strcmp(shp->name, "\8c\82Ì\96{\89®")
507                     || !strcmp(shp->name, "\8cÃ\8f\91\93X"))) {
508 #endif
509         struct obj *novel = mksobj_at(SPE_NOVEL, sx, sy, FALSE, FALSE);
510
511         if (novel)
512             context.tribute.bookstock = TRUE;
513         return;
514     }
515
516     if (rn2(100) < depth(&u.uz) && !MON_AT(sx, sy)
517         && (ptr = mkclass(S_MIMIC, 0)) != 0
518         && (mtmp = makemon(ptr, sx, sy, NO_MM_FLAGS)) != 0) {
519         /* note: makemon will set the mimic symbol to a shop item */
520         if (rn2(10) >= depth(&u.uz)) {
521             mtmp->m_ap_type = M_AP_OBJECT;
522             mtmp->mappearance = STRANGE_OBJECT;
523         }
524     } else {
525         atype = get_shop_item((int) (shp - shtypes));
526         if (atype == VEGETARIAN_CLASS)
527             mkveggy_at(sx, sy);
528         else if (atype < 0)
529             (void) mksobj_at(-atype, sx, sy, TRUE, TRUE);
530         else
531             (void) mkobj_at(atype, sx, sy, TRUE);
532     }
533 }
534
535 /* extract a shopkeeper name for the given shop type */
536 STATIC_OVL void
537 nameshk(shk, nlp)
538 struct monst *shk;
539 const char *const *nlp;
540 {
541     int i, trycnt, names_avail;
542     const char *shname = 0;
543     struct monst *mtmp;
544     int name_wanted;
545     s_level *sptr;
546
547     if (nlp == shkfoods && In_mines(&u.uz) && Role_if(PM_MONK)
548         && (sptr = Is_special(&u.uz)) != 0 && sptr->flags.town) {
549         /* special-case override for minetown food store for monks */
550         nlp = shkhealthfoods;
551     }
552
553     if (nlp == shklight && In_mines(&u.uz) && (sptr = Is_special(&u.uz)) != 0
554         && sptr->flags.town) {
555         /* special-case minetown lighting shk */
556         shname = "+Izchak";
557         shk->female = FALSE;
558     } else {
559         /* We want variation from game to game, without needing the save
560            and restore support which would be necessary for randomization;
561            try not to make too many assumptions about time_t's internals;
562            use ledger_no rather than depth to keep mine town distinct. */
563         int nseed = (int) ((long) ubirthday / 257L);
564
565         name_wanted = ledger_no(&u.uz) + (nseed % 13) - (nseed % 5);
566         if (name_wanted < 0)
567             name_wanted += (13 + 5);
568         shk->female = name_wanted & 1;
569
570         for (names_avail = 0; nlp[names_avail]; names_avail++)
571             continue;
572
573         for (trycnt = 0; trycnt < 50; trycnt++) {
574             if (nlp == shktools) {
575                 shname = shktools[rn2(names_avail)];
576                 shk->female = 0; /* reversed below for '_' prefix */
577             } else if (name_wanted < names_avail) {
578                 shname = nlp[name_wanted];
579             } else if ((i = rn2(names_avail)) != 0) {
580                 shname = nlp[i - 1];
581             } else if (nlp != shkgeneral) {
582                 nlp = shkgeneral; /* try general names */
583                 for (names_avail = 0; nlp[names_avail]; names_avail++)
584                     continue;
585                 continue; /* next `trycnt' iteration */
586             } else {
587                 shname = shk->female ? "-Lucrezia" : "+Dirk";
588             }
589             if (*shname == '_' || *shname == '-')
590                 shk->female = 1;
591             else if (*shname == '|' || *shname == '+')
592                 shk->female = 0;
593
594             /* is name already in use on this level? */
595             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
596                 if (DEADMONSTER(mtmp) || (mtmp == shk) || !mtmp->isshk)
597                     continue;
598                 if (strcmp(ESHK(mtmp)->shknam, shname))
599                     continue;
600                 break;
601             }
602             if (!mtmp)
603                 break; /* new name */
604         }
605     }
606     (void) strncpy(ESHK(shk)->shknam, shname, PL_NSIZ);
607     ESHK(shk)->shknam[PL_NSIZ - 1] = 0;
608 }
609
610 void
611 neweshk(mtmp)
612 struct monst *mtmp;
613 {
614     if (!mtmp->mextra)
615         mtmp->mextra = newmextra();
616     if (!ESHK(mtmp))
617         ESHK(mtmp) = (struct eshk *) alloc(sizeof(struct eshk));
618     (void) memset((genericptr_t) ESHK(mtmp), 0, sizeof(struct eshk));
619     ESHK(mtmp)->bill_p = (struct bill_x *) 0;
620 }
621
622 void
623 free_eshk(mtmp)
624 struct monst *mtmp;
625 {
626     if (mtmp->mextra && ESHK(mtmp)) {
627         free((genericptr_t) ESHK(mtmp));
628         ESHK(mtmp) = (struct eshk *) 0;
629     }
630     mtmp->isshk = 0;
631 }
632
633 /* create a new shopkeeper in the given room */
634 STATIC_OVL int
635 shkinit(shp, sroom)
636 const struct shclass *shp;
637 struct mkroom *sroom;
638 {
639     register int sh, sx, sy;
640     struct monst *shk;
641     struct eshk *eshkp;
642
643     /* place the shopkeeper in the given room */
644     sh = sroom->fdoor;
645     sx = doors[sh].x;
646     sy = doors[sh].y;
647
648     /* check that the shopkeeper placement is sane */
649     if (sroom->irregular) {
650         int rmno = (int) ((sroom - rooms) + ROOMOFFSET);
651
652         if (isok(sx - 1, sy) && !levl[sx - 1][sy].edge
653             && (int) levl[sx - 1][sy].roomno == rmno)
654             sx--;
655         else if (isok(sx + 1, sy) && !levl[sx + 1][sy].edge
656                  && (int) levl[sx + 1][sy].roomno == rmno)
657             sx++;
658         else if (isok(sx, sy - 1) && !levl[sx][sy - 1].edge
659                  && (int) levl[sx][sy - 1].roomno == rmno)
660             sy--;
661         else if (isok(sx, sy + 1) && !levl[sx][sy + 1].edge
662                  && (int) levl[sx][sy + 1].roomno == rmno)
663             sy++;
664         else
665             goto shk_failed;
666     } else if (sx == sroom->lx - 1) {
667         sx++;
668     } else if (sx == sroom->hx + 1) {
669         sx--;
670     } else if (sy == sroom->ly - 1) {
671         sy++;
672     } else if (sy == sroom->hy + 1) {
673         sy--;
674     } else {
675     shk_failed:
676 #ifdef DEBUG
677         /* Said to happen sometimes, but I have never seen it. */
678         /* Supposedly fixed by fdoor change in mklev.c */
679         if (wizard) {
680             register int j = sroom->doorct;
681
682             pline("Where is shopdoor?");
683             pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly, sroom->hx,
684                   sroom->hy);
685             pline("doormax=%d doorct=%d fdoor=%d", doorindex, sroom->doorct,
686                   sh);
687             while (j--) {
688                 pline("door [%d,%d]", doors[sh].x, doors[sh].y);
689                 sh++;
690             }
691             display_nhwindow(WIN_MESSAGE, FALSE);
692         }
693 #endif
694         return -1;
695     }
696
697     if (MON_AT(sx, sy))
698         (void) rloc(m_at(sx, sy), FALSE); /* insurance */
699
700     /* now initialize the shopkeeper monster structure */
701     if (!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, MM_ESHK)))
702         return -1;
703     eshkp = ESHK(shk); /* makemon(...,MM_ESHK) allocates this */
704     shk->isshk = shk->mpeaceful = 1;
705     set_malign(shk);
706     shk->msleeping = 0;
707     shk->mtrapseen = ~0; /* we know all the traps already */
708     eshkp->shoproom = (schar) ((sroom - rooms) + ROOMOFFSET);
709     sroom->resident = shk;
710     eshkp->shoptype = sroom->rtype;
711     assign_level(&eshkp->shoplevel, &u.uz);
712     eshkp->shd = doors[sh];
713     eshkp->shk.x = sx;
714     eshkp->shk.y = sy;
715     eshkp->robbed = eshkp->credit = eshkp->debit = eshkp->loan = 0L;
716     eshkp->following = eshkp->surcharge = eshkp->dismiss_kops = FALSE;
717     eshkp->billct = eshkp->visitct = 0;
718     eshkp->bill_p = (struct bill_x *) 0;
719     eshkp->customer[0] = '\0';
720     mkmonmoney(shk, 1000L + 30L * (long) rnd(100)); /* initial capital */
721     if (shp->shknms == shkrings)
722         (void) mongets(shk, TOUCHSTONE);
723     nameshk(shk, shp->shknms);
724
725     return sh;
726 }
727
728 STATIC_OVL boolean
729 stock_room_goodpos(sroom, rmno, sh, sx, sy)
730 struct mkroom *sroom;
731 int rmno, sh, sx,sy;
732 {
733     if (sroom->irregular) {
734         if (levl[sx][sy].edge
735             || (int) levl[sx][sy].roomno != rmno
736             || distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1)
737             return FALSE;
738     } else if ((sx == sroom->lx && doors[sh].x == sx - 1)
739                || (sx == sroom->hx && doors[sh].x == sx + 1)
740                || (sy == sroom->ly && doors[sh].y == sy - 1)
741                || (sy == sroom->hy && doors[sh].y == sy + 1))
742         return FALSE;
743     return TRUE;
744 }
745
746 /* stock a newly-created room with objects */
747 void
748 stock_room(shp_indx, sroom)
749 int shp_indx;
750 register struct mkroom *sroom;
751 {
752     /*
753      * Someday soon we'll dispatch on the shdist field of shclass to do
754      * different placements in this routine. Currently it only supports
755      * shop-style placement (all squares except a row nearest the first
756      * door get objects).
757      */
758     int sx, sy, sh;
759     int stockcount = 0, specialspot = 0;
760     char buf[BUFSZ];
761     int rmno = (int) ((sroom - rooms) + ROOMOFFSET);
762     const struct shclass *shp = &shtypes[shp_indx];
763
764     /* first, try to place a shopkeeper in the room */
765     if ((sh = shkinit(shp, sroom)) < 0)
766         return;
767
768     /* make sure no doorways without doors, and no trapped doors, in shops */
769     sx = doors[sroom->fdoor].x;
770     sy = doors[sroom->fdoor].y;
771     if (levl[sx][sy].doormask == D_NODOOR) {
772         levl[sx][sy].doormask = D_ISOPEN;
773         newsym(sx, sy);
774     }
775     if (levl[sx][sy].typ == SDOOR) {
776         cvt_sdoor_to_door(&levl[sx][sy]); /* .typ = DOOR */
777         newsym(sx, sy);
778     }
779     if (levl[sx][sy].doormask & D_TRAPPED)
780         levl[sx][sy].doormask = D_LOCKED;
781
782     if (levl[sx][sy].doormask == D_LOCKED) {
783         register int m = sx, n = sy;
784
785         if (inside_shop(sx + 1, sy))
786             m--;
787         else if (inside_shop(sx - 1, sy))
788             m++;
789         if (inside_shop(sx, sy + 1))
790             n--;
791         else if (inside_shop(sx, sy - 1))
792             n++;
793 /*JP
794         Sprintf(buf, "Closed for inventory");
795 */
796         Sprintf(buf, "\92I\89µ\82µ\82Ì\82½\82ß\95Â\93X");
797         make_engr_at(m, n, buf, 0L, DUST);
798     }
799
800     if (context.tribute.enabled && !context.tribute.bookstock) {
801         /*
802          * Out of the number of spots where we're actually
803          * going to put stuff, randomly single out one in particular.
804          */
805         for (sx = sroom->lx; sx <= sroom->hx; sx++)
806             for (sy = sroom->ly; sy <= sroom->hy; sy++)
807                 if (stock_room_goodpos(sroom, rmno, sh, sx,sy))
808                     stockcount++;
809         specialspot = rnd(stockcount);
810         stockcount = 0;
811     }
812
813     for (sx = sroom->lx; sx <= sroom->hx; sx++)
814         for (sy = sroom->ly; sy <= sroom->hy; sy++)
815             if (stock_room_goodpos(sroom, rmno, sh, sx,sy)) {
816                 stockcount++;
817                 mkshobj_at(shp, sx, sy,
818                            ((stockcount) && (stockcount == specialspot)));
819             }
820
821     /*
822      * Special monster placements (if any) should go here: that way,
823      * monsters will sit on top of objects and not the other way around.
824      */
825
826     level.flags.has_shop = TRUE;
827 }
828
829 /* does shkp's shop stock this item type? */
830 boolean
831 saleable(shkp, obj)
832 struct monst *shkp;
833 struct obj *obj;
834 {
835     int i, shp_indx = ESHK(shkp)->shoptype - SHOPBASE;
836     const struct shclass *shp = &shtypes[shp_indx];
837
838     if (shp->symb == RANDOM_CLASS)
839         return TRUE;
840     for (i = 0; i < SIZE(shtypes[0].iprobs) && shp->iprobs[i].iprob; i++) {
841         /* pseudo-class needs special handling */
842         if (shp->iprobs[i].itype == VEGETARIAN_CLASS) {
843             if (veggy_item(obj, 0))
844                 return TRUE;
845         } else if ((shp->iprobs[i].itype < 0)
846                        ? shp->iprobs[i].itype == -obj->otyp
847                        : shp->iprobs[i].itype == obj->oclass)
848             return TRUE;
849     }
850     /* not found */
851     return FALSE;
852 }
853
854 /* positive value: class; negative value: specific object type */
855 int
856 get_shop_item(type)
857 int type;
858 {
859     const struct shclass *shp = shtypes + type;
860     register int i, j;
861
862     /* select an appropriate object type at random */
863     for (j = rnd(100), i = 0; (j -= shp->iprobs[i].iprob) > 0; i++)
864         continue;
865
866     return shp->iprobs[i].itype;
867 }
868
869 /* version of shkname() for beginning of sentence */
870 char *
871 Shknam(mtmp)
872 struct monst *mtmp;
873 {
874     char *nam = shkname(mtmp);
875
876     /* 'nam[]' is almost certainly already capitalized, but be sure */
877     nam[0] = highc(nam[0]);
878     return nam;
879 }
880
881 /* shopkeeper's name, without any visibility constraint; if hallucinating,
882    will yield some other shopkeeper's name (not necessarily one residing
883    in the current game's dungeon, or who keeps same type of shop) */
884 char *
885 shkname(mtmp)
886 struct monst *mtmp;
887 {
888     char *nam;
889     unsigned save_isshk = mtmp->isshk;
890
891     mtmp->isshk = 0; /* don't want mon_nam() calling shkname() */
892     /* get a modifiable name buffer along with fallback result */
893     nam = noit_mon_nam(mtmp);
894     mtmp->isshk = save_isshk;
895
896     if (!mtmp->isshk) {
897         impossible("shkname: \"%s\" is not a shopkeeper.", nam);
898     } else if (!has_eshk(mtmp)) {
899         panic("shkname: shopkeeper \"%s\" lacks 'eshk' data.", nam);
900     } else {
901         const char *shknm = ESHK(mtmp)->shknam;
902
903         if (Hallucination && !program_state.gameover) {
904             const char *const *nlp;
905             int num;
906
907             /* count the number of non-unique shop types;
908                pick one randomly, ignoring shop generation probabilities;
909                pick a name at random from that shop type's list */
910             for (num = 0; num < SIZE(shtypes); num++)
911                 if (shtypes[num].prob == 0)
912                     break;
913             if (num > 0) {
914                 nlp = shtypes[rn2(num)].shknms;
915                 for (num = 0; nlp[num]; num++)
916                     continue;
917                 if (num > 0)
918                     shknm = nlp[rn2(num)];
919             }
920         }
921         /* strip prefix if present */
922         if (!letter(*shknm))
923             ++shknm;
924         Strcpy(nam, shknm);
925     }
926     return nam;
927 }
928
929 boolean
930 shkname_is_pname(mtmp)
931 struct monst *mtmp;
932 {
933     const char *shknm = ESHK(mtmp)->shknam;
934
935     return (boolean) (*shknm == '-' || *shknm == '+' || *shknm == '=');
936 }
937
938 boolean
939 is_izchak(shkp, override_hallucination)
940 struct monst *shkp;
941 boolean override_hallucination;
942 {
943     const char *shknm;
944
945     if (Hallucination && !override_hallucination)
946         return FALSE;
947     if (!shkp->isshk)
948         return FALSE;
949     /* outside of town, Izchak becomes just an ordinary shopkeeper */
950     if (!in_town(shkp->mx, shkp->my))
951         return FALSE;
952     shknm = ESHK(shkp)->shknam;
953     /* skip "+" prefix */
954     if (!letter(*shknm))
955         ++shknm;
956     return (boolean) !strcmp(shknm, "Izchak");
957 }
958
959 /*shknam.c*/