OSDN Git Service

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