Source:NetHack 3.1.0/shknam.c

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

Warning! This is the source code from an old release. For the latest release, see Source code

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