Source:NetHack 3.2.0/o init.c

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

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

1.   /*	SCCS Id: @(#)o_init.c	3.2	94/07/10	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "lev.h"	/* save & restore info */ 7.    8.    static void NDECL(setgemprobs); 9.   static void FDECL(shuffle,(int,int,BOOLEAN_P)); 10.  static void NDECL(shuffle_all); 11.  static boolean FDECL(interesting_to_discover,(int)); 12.   13.    14.   static NEARDATA short disco[NUM_OBJECTS] = DUMMY; 15.   16.   #ifdef USE_TILES 17.  static void NDECL(shuffle_tiles); 18.  extern short glyph2tile[];	/* from tile.c */ 19.   20.   /* Shuffle tile assignments to match descriptions, so a red potion isn't  21. * displayed with a blue tile and so on. 22.   *  23.    * Tile assignments are not saved, and shouldn't be so that a game can 24.   * be resumed on an otherwise identical non-tile-using binary, so we have 25.   * to reshuffle the assignments from oc_descr_idx information when a game 26.   * is restored. So might as well do that the first time instead of writing 27.   * another routine. 28.   */  29.   static void 30.  shuffle_tiles 31.  {  32.   	int i;  33. short tmp_tilemap[NUM_OBJECTS]; 34.   35.   	for (i = 0; i < NUM_OBJECTS; i++) 36.  		tmp_tilemap[i] = 37.  			glyph2tile[objects[i].oc_descr_idx + GLYPH_OBJ_OFF]; 38.   39.   	for (i = 0; i < NUM_OBJECTS; i++) 40.  		glyph2tile[i + GLYPH_OBJ_OFF] = tmp_tilemap[i]; 41.  }  42.   #endif	/* USE_TILES */ 43.   44.   static void 45.  setgemprobs 46.  {  47.   	register int j, first; 48.  	int lev = (ledger_no(&u.uz) > maxledgerno) 49.  				? maxledgerno : ledger_no(&u.uz); 50.   51.   	first = bases[GEM_CLASS]; 52.   53.   	for(j = 0; j < 9-lev/3; j++) 54.  		objects[first+j].oc_prob = 0; 55.  	first += j;  56. if (first > LAST_GEM || objects[first].oc_class != GEM_CLASS || 57.   	    OBJ_NAME(objects[first]) == (char *)0) { 58.  		raw_printf("Not enough gems? - first=%d j=%d LAST_GEM=%d",  59.   			first, j, LAST_GEM); 60.  		wait_synch; 61.  	    }  62.   	for (j = first; j <= LAST_GEM; j++) 63.  		objects[j].oc_prob = (184+j-first)/(LAST_GEM+1-first); 64.  }  65.    66.   /* shuffle descriptions on objects o_low to o_high */ 67.  static void 68.  shuffle(o_low, o_high, domaterial) 69.  	int o_low, o_high; 70.  	boolean domaterial; 71.  {  72.   	int i, j, num_to_shuffle; 73.  	short sw; 74.  #ifdef TEXTCOLOR 75.  	int color; 76.  #endif /* TEXTCOLOR */ 77.   78.   	for (num_to_shuffle = 0, j=o_low; j <= o_high; j++) 79.  		if (!objects[j].oc_name_known) num_to_shuffle++; 80.  	if (num_to_shuffle < 2) return; 81.   82.   	for (j=o_low; j <= o_high; j++) { 83.  		if (objects[j].oc_name_known) continue; 84.  		do 85.  			i = j + rn2(o_high-j+1); 86.  		while (objects[i].oc_name_known); 87.  		sw = objects[j].oc_descr_idx; 88.  		objects[j].oc_descr_idx = objects[i].oc_descr_idx; 89.  		objects[i].oc_descr_idx = sw; 90.  		sw = objects[j].oc_tough; 91.  		objects[j].oc_tough = objects[i].oc_tough; 92.  		objects[i].oc_tough = sw; 93.  #ifdef TEXTCOLOR 94.  		color = objects[j].oc_color; 95.  		objects[j].oc_color = objects[i].oc_color; 96.  		objects[i].oc_color = color; 97.  #endif /* TEXTCOLOR */ 98.  		/* shuffle material */ 99.  		if (domaterial) { 100. 			sw = objects[j].oc_material; 101. 			objects[j].oc_material = objects[i].oc_material; 102. 			objects[i].oc_material = sw; 103. 		}  104.  	}  105.  }  106.   107.  void 108. init_objects 109. {  110.  register int i, first, last, sum; 111. register char oclass; 112. #ifdef TEXTCOLOR 113. # define COPY_OBJ_DESCR(o_dst,o_src) \ 114. 			o_dst.oc_descr_idx = o_src.oc_descr_idx,\ 115. 			o_dst.oc_color = o_src.oc_color 116. #else 117. # define COPY_OBJ_DESCR(o_dst,o_src) o_dst.oc_descr_idx = o_src.oc_descr_idx 118. #endif 119.  120.  	/* bug fix to prevent "initialization error" abort on Intel Xenix. 121. 	 * reported by mikew@semike 122. 	 */  123.  	for (i = 0; i < MAXOCLASSES; i++) 124. 		bases[i] = 0; 125. 	/* initialize object descriptions */ 126. 	for (i = 0; i < NUM_OBJECTS; i++) 127. 		objects[i].oc_name_idx = objects[i].oc_descr_idx = i;  128. /* init base; if probs given check that they add up to 1000, 129. 	   otherwise compute probs */ 130. 	first = 0; 131. 	while( first < NUM_OBJECTS ) { 132. 		oclass = objects[first].oc_class; 133. 		last = first+1; 134. 		while (last < NUM_OBJECTS && objects[last].oc_class == oclass) last++; 135. 		bases[(int)oclass] = first; 136.  137.  		if (oclass == GEM_CLASS) { 138. 			setgemprobs; 139.  140.  			if (rn2(2)) { /* change turquoise from green to blue? */ 141.  			    COPY_OBJ_DESCR(objects[TURQUOISE],objects[SAPPHIRE]); 142. 			}  143.  			if (rn2(2)) { /* change aquamarine from green to blue? */ 144.  			    COPY_OBJ_DESCR(objects[AQUAMARINE],objects[SAPPHIRE]); 145. 			}  146.  			switch (rn2(4)) { /* change fluorite from violet? */ 147.  			    case 0:  break; 148. 			    case 1:	/* blue */ 149. 				COPY_OBJ_DESCR(objects[FLUORITE],objects[SAPPHIRE]); 150. 				break; 151. 			    case 2:	/* white */ 152. 				COPY_OBJ_DESCR(objects[FLUORITE],objects[DIAMOND]); 153. 				break; 154. 			    case 3:	/* green */ 155. 				COPY_OBJ_DESCR(objects[FLUORITE],objects[EMERALD]); 156. 				break; 157. 			}  158.  		}  159.  	check: 160. 		sum = 0; 161. 		for(i = first; i < last; i++) sum += objects[i].oc_prob; 162. 		if(sum == 0) { 163. 			for(i = first; i < last; i++) 164. 			    objects[i].oc_prob = (1000+i-first)/(last-first); 165. 			goto check; 166. 		}  167.  		if(sum != 1000) 168. 			error("init-prob error for class %d (%d%%)", oclass, sum); 169. 		first = last; 170. 	}  171.  	/* shuffle descriptions */ 172. 	shuffle_all; 173. #ifdef USE_TILES 174. 	shuffle_tiles; 175. #endif 176. }  177.   178.  static void 179. shuffle_all 180. {  181.  	int first, last, oclass; 182.  183.  	for (oclass = 1; oclass < MAXOCLASSES; oclass++) { 184. 		first = bases[oclass]; 185. 		last = first+1; 186. 		while (last < NUM_OBJECTS && objects[last].oc_class == oclass) 187. 			last++; 188.  189.  		if (OBJ_DESCR(objects[first]) != (char *)0 &&  190.  				oclass != TOOL_CLASS &&  191.  				oclass != WEAPON_CLASS &&  192.  				oclass != ARMOR_CLASS &&  193.  				oclass != GEM_CLASS) { 194. 			int j = last-1; 195.  196.  			if (oclass == POTION_CLASS) 197. 			    j -= 1;  /* only water has a fixed description */ 198. 			else if (oclass == AMULET_CLASS ||  199.  				 oclass == SCROLL_CLASS ||  200.  				 oclass == SPBOOK_CLASS) { 201. 			    while (!objects[j].oc_magic || objects[j].oc_unique) 202. 				j--; 203. 			}  204.   205.  			/* non-magical amulets, scrolls, and spellbooks 206. 			 * (ex. imitation Amulets, blank, scrolls of mail) 207. 			 * and one-of-a-kind magical artifacts at the end of  208. * their class in objects[] have fixed descriptions. 209. 			 */  210.  			shuffle(first, j, TRUE); 211. 		}  212.  	}  213.   214.  	/* shuffle the helmets */ 215. 	shuffle(HELMET, HELM_OF_TELEPATHY, FALSE); 216.  217.  	/* shuffle the gloves */ 218. 	shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE); 219.  220.  	/* shuffle the cloaks */ 221. 	shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE); 222.  223.  	/* shuffle the boots [if they change, update find_skates below] */ 224. 	shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); 225. }  226.   227.  /* find the object index for snow boots; used [once] by slippery ice code */ 228. int 229. find_skates 230. {  231.      register int i;  232. register const char *s; 233.  234.      for (i = SPEED_BOOTS; i <= LEVITATION_BOOTS; i++) 235. 	if ((s = OBJ_DESCR(objects[i])) != 0 && !strcmp(s, "snow boots")) 236. 	    return i;  237. 238.     impossible("snow boots not found?"); 239.     return -1;	/* not 0, or caller would try again each move */ 240. }  241.   242.  void 243. oinit			/* level dependent initialization */ 244. {  245.  	setgemprobs; 246. }  247.   248.  void 249. savenames(fd, mode) 250. int fd, mode; 251. {  252.  	register int i;  253. unsigned int len; 254.  255.  	if (perform_bwrite(mode)) { 256. 	    bwrite(fd, (genericptr_t)bases, sizeof bases); 257. 	    bwrite(fd, (genericptr_t)disco, sizeof disco); 258. 	    bwrite(fd, (genericptr_t)objects,  259.  		   sizeof(struct objclass) * NUM_OBJECTS); 260. 	}  261.  	/* as long as we use only one version of Hack we  262. need not save oc_name and oc_descr, but we must save 263. 	   oc_uname for all objects */ 264. 	for (i = 0; i < NUM_OBJECTS; i++) 265. 	    if (objects[i].oc_uname) { 266. 		if (perform_bwrite(mode)) { 267. 		    len = strlen(objects[i].oc_uname)+1; 268. 		    bwrite(fd, (genericptr_t)&len, sizeof len); 269. 		    bwrite(fd, (genericptr_t)objects[i].oc_uname, len); 270. 		}  271.  		if (release_data(mode)) { 272. 		    free((genericptr_t)objects[i].oc_uname); 273. 		    objects[i].oc_uname = 0; 274. 		}  275.  	    }  276.  }  277.   278.  void 279. restnames(fd) 280. register int fd; 281. {  282.  	register int i;  283. unsigned int len; 284.  285.  	mread(fd, (genericptr_t) bases, sizeof bases); 286. 	mread(fd, (genericptr_t) disco, sizeof disco); 287. 	mread(fd, (genericptr_t) objects, sizeof(struct objclass) * NUM_OBJECTS); 288. 	for (i = 0; i < NUM_OBJECTS; i++) 289. 	    if (objects[i].oc_uname) { 290. 		mread(fd, (genericptr_t) &len, sizeof len); 291. 		objects[i].oc_uname = (char *) alloc(len); 292. 		mread(fd, (genericptr_t)objects[i].oc_uname, len); 293. 	    }  294.  #ifdef USE_TILES 295. 	shuffle_tiles; 296. #endif 297. }  298.   299.  void 300. discover_object(oindx, mark_as_known) 301. register int oindx; 302. boolean mark_as_known; 303. {  304.      if (!objects[oindx].oc_name_known) { 305. 	register int dindx, acls = objects[oindx].oc_class; 306.  307.  	/* Loop thru disco[] 'til we find the target (which may have been  308.  	   uname'd) or the next open slot; one or the other will be found 309. 	   before we reach the next class...  310. */ 311.  	for (dindx = bases[acls]; disco[dindx] != 0; dindx++) 312. 	    if (disco[dindx] == oindx) break; 313. 	disco[dindx] = oindx; 314.  315.  	if (mark_as_known) { 316. 	    objects[oindx].oc_name_known = 1; 317. 	    exercise(A_WIS, TRUE); 318. 	}  319.      }  320.  }  321.   322.  /* if a class name has been cleared, we may need to purge it from disco[] */ 323. void 324. undiscover_object(oindx) 325. register int oindx; 326. {  327.      if (!objects[oindx].oc_name_known) { 328. 	register int dindx, acls = objects[oindx].oc_class; 329. 	register boolean found = FALSE; 330.  331.  	/* find the object; shift those behind it forward one slot */ 332. 	for (dindx = bases[acls];  333.  	      dindx < NUM_OBJECTS && disco[dindx] != 0  334.  		&& objects[dindx].oc_class == acls; dindx++) 335. 	    if (found) 336. 		disco[dindx-1] = disco[dindx]; 337. 	    else if (disco[dindx] == oindx) 338. 		found = TRUE; 339.  340.  	/* clear last slot */ 341. 	if (found) disco[dindx-1] = 0; 342. 	else impossible("named object not in disco"); 343.     }  344.  }  345.   346.  static boolean 347. interesting_to_discover(i) 348. register int i;  349. { 350.      if (objects[i].oc_pre_discovered) return FALSE; 351.     return((boolean)(objects[i].oc_uname != (char *)0 || 352. 	    (objects[i].oc_name_known && OBJ_DESCR(objects[i]) != (char *)0))); 353. }  354.   355.  int 356. dodiscovered				/* free after Robert Viduya */ 357. {  358.      register int i, dis; 359.     int	ct = 0; 360.     char *s, oclass, prev_class, classes[MAXOCLASSES]; 361.     winid tmpwin; 362.  363.      tmpwin = create_nhwindow(NHW_MENU); 364.     putstr(tmpwin, 0, "Discoveries"); 365.     putstr(tmpwin, 0, ""); 366.  367.      /* several classes are omitted from packorder; one is of interest here */ 368.     Strcpy(classes, flags.inv_order); 369.     if (!index(classes, VENOM_CLASS)) { 370. 	s = eos(classes); 371. 	*s++ = VENOM_CLASS; 372. 	*s = '\0'; 373.     }  374.   375.      for (s = classes; *s; s++) { 376. 	oclass = *s; 377. 	prev_class = oclass + 1;	/* forced different from oclass */ 378. 	for (i = bases[(int)oclass];  379.  	     i < NUM_OBJECTS && objects[i].oc_class == oclass; i++) { 380. 	    if ((dis = disco[i]) && interesting_to_discover(dis)) { 381. 		ct++; 382. 		if (oclass != prev_class) { 383. 		    putstr(tmpwin, ATR_INVERSE, let_to_name(oclass, FALSE)); 384. 		    prev_class = oclass; 385. 		}  386.  		putstr(tmpwin, 0, typename(dis)); 387. 	    }  388.  	}  389.      }  390.      if (ct == 0) { 391. 	You("haven't discovered anything yet..."); 392.     } else 393. 	display_nhwindow(tmpwin, TRUE); 394.     destroy_nhwindow(tmpwin); 395.  396.      return 0; 397. }  398.   399.  /*o_init.c*/