Source:NetHack 3.0.0/o init.c

Below is the full text to o_init.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/07/06 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include	"hack.h"		/* for typedefs */ 6.    7.    /* note that NROFOBJECTS is the number of legal objects, which does not count 8.    * the strange object and null object that take up positions 0 and NROFOBJECTS+1 9.    * in the objects array 10.   */  11.   #define TOTAL_OBJS	(NROFOBJECTS+2) 12.   13.   const char obj_symbols[] = { 14.  	ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, 15.  	BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, 16.  	POTION_SYM, SCROLL_SYM, WAND_SYM, 17.  #ifdef SPELLS 18.  	SPBOOK_SYM, 19.  #endif 20.  	RING_SYM, GEM_SYM, 0 }; 21.   22.   int bases[sizeof(obj_symbols)] = DUMMY; 23.  static int disco[TOTAL_OBJS] = DUMMY; 24.   25.   int 26.  letindex(let) register char let; { 27.  register int i = 0; 28.  register char ch; 29.  	while((ch = obj_symbols[i++]) != 0) 30.  		if(ch == let) return(i); 31.  	return(0); 32.  }  33.    34.   static void 35.  setgemprobs 36.  {  37.   	register int j,first; 38.  #ifdef STRONGHOLD 39.  	int level = (dlevel > MAXLEVEL) ? MAXLEVEL : dlevel; 40.  #endif 41.   42.   	first = bases[letindex(GEM_SYM)]; 43.   44.   #ifdef STRONGHOLD 45.  	for(j = 0; j < 9-level/3; j++) 46.  #else 47.  	for(j = 0; j < 9-dlevel/3; j++) 48.  #endif 49.  		objects[first+j].oc_prob = 0; 50.  	first += j;  51. if(first >= LAST_GEM || first > NROFOBJECTS || 52.   	    objects[first].oc_olet != GEM_SYM ||  53.   	    objects[first].oc_name == NULL) 54.  		Printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",  55.   			first, j, LAST_GEM); 56.  	for(j = first; j < LAST_GEM; j++) 57.  		objects[j].oc_prob = (180+j-first)/(LAST_GEM-first); 58.  }  59.    60.   /* shuffle descriptions on objects o_low to o_high */ 61.  static void 62.  shuffle(o_low, o_high, domaterial) 63.   64.   	register int o_low, o_high; 65.  	register boolean domaterial; 66.  {  67.   	register int i, j;  68. char *desc; 69.  	int tmp; 70.   71.   	for(j=o_low; j <= o_high; j++) { 72.  		i = o_low + rn2(j+1-o_low); 73.  		desc = objects[j].oc_descr; 74.  		objects[j].oc_descr = objects[i].oc_descr; 75.  		objects[i].oc_descr = desc; 76.  		/* shuffle discovery list */ 77.  		tmp = disco[j]; 78.  		disco[j] = disco[i]; 79.  		disco[i] = tmp; 80.  		/* shuffle material */ 81.  		if(domaterial) { 82.  			tmp = objects[j].oc_material; 83.  			objects[j].oc_material = objects[i].oc_material; 84.  			objects[i].oc_material = tmp; 85.  		}  86.   	}  87.   }  88.    89.   void 90.  init_objects{ 91.  register int i, j, first, last, sum, end; 92.  register char let; 93.   94.   	/* bug fix to prevent "initialization error" abort on Intel Xenix. 95.  	 * reported by mikew@semike 96.  	 */  97.   	for(i = 0; i != sizeof(obj_symbols); i++) 98.  		bases[i] = 0; 99.  	for(i = 0; i != TOTAL_OBJS; i++) 100. 		disco[i] = i;  101. 102. 	/* init base; if probs given check that they add up to 1000, 103. 	   otherwise compute probs; shuffle descriptions */ 104. 	end = TOTAL_OBJS; 105. 	first = 0; 106. 	while( first < end ) { 107. 		let = objects[first].oc_olet; 108. 		last = first+1; 109. 		while(last < end && objects[last].oc_olet == let  110.  				 && objects[last].oc_name != NULL) last++; 111. 		i = letindex(let); 112. 		if((!i && let != ILLOBJ_SYM && let != '.') || bases[i] != 0) 113. 			error("initialization error for %c", let); 114. 		bases[i] = first; 115.  116.  		if(let == GEM_SYM) setgemprobs; 117. 	check: 118. 		sum = 0; 119. 		for(j = first; j < last; j++) sum += objects[j].oc_prob; 120. 		if(sum == 0) { 121. 			for(j = first; j < last; j++) 122. 			    objects[j].oc_prob = (1000+j-first)/(last-first); 123. 			goto check; 124. 		}  125.  		if(sum != 1000) 126. 			error("init-prob error for %c (%d%%)", let, sum); 127.  128.  		if(objects[first].oc_descr != NULL &&  129.  		   let != TOOL_SYM && let != WEAPON_SYM && let != ARMOR_SYM) { 130.  131.  			/* shuffle, also some additional descriptions */ 132. 			while(last < end && objects[last].oc_olet == let) 133. 				last++; 134. 			j = last; 135. 			if (let == GEM_SYM) { 136. 			    while(--j > first) 137. 				/* NOTE:  longest color name must be default */ 138. 				if(!strcmp(objects[j].oc_name,"turquoise")) { 139. 				    if(rn2(2)) /* change from green? */ 140.  					Strcpy(objects[j].oc_descr, blue); 141. 				} else if (!strcmp(objects[j].oc_name,"aquamarine")) { 142. 				    if(rn2(2)) /* change from green? */ 143.  					Strcpy(objects[j].oc_descr, blue); 144. 				} else if (!strcmp(objects[j].oc_name,"fluorite")) { 145. 				    switch (rn2(4)) { /* change from violet? */ 146.  					case 0:  break; 147. 					case 1: 148. 					    Strcpy(objects[j].oc_descr, blue); 149. 					    break; 150. 					case 2: 151. 					    Strcpy(objects[j].oc_descr, white); 152. 					    break; 153. 					case 3: 154. 					    Strcpy(objects[j].oc_descr, green); 155. 					    break; 156. 					}  157.  				}  158.  			} else { 159. 			    if (let == AMULET_SYM || let == POTION_SYM) 160. 				j--;  /* THE amulet doesn't have description */ 161. 			    /* and water is always "clear" - 3. */ 162.  			    shuffle(first, --j, TRUE); 163. 			}  164.  		}  165.  		first = last; 166. 	}  167.   168.  	/* shuffle the helmets */ 169. 	shuffle(HELMET, HELM_OF_TELEPATHY, FALSE); 170.  171.  	/* shuffle the gloves */ 172. 	shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE); 173.  174.  	/* shuffle the cloaks */ 175. 	shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE); 176.  177.  	/* shuffle the boots */ 178. 	shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); 179. }  180.   181.  void 182. oinit			/* level dependent initialization */ 183. {  184.  	setgemprobs; 185. }  186.   187.  void 188. savenames(fd) 189. register int fd; 190. {  191.  	register int i;  192. unsigned int len; 193. 	struct objclass *now = &objects[0]; 194. 	bwrite(fd, (genericptr_t)&now, sizeof now); 195. 	bwrite(fd, (genericptr_t)bases, sizeof bases); 196. 	bwrite(fd, (genericptr_t)disco, sizeof disco); 197. 	bwrite(fd, (genericptr_t)objects, sizeof(struct objclass) * TOTAL_OBJS); 198. 	/* as long as we use only one version of Hack we  199. need not save oc_name and oc_descr, but we must save 200. 	   oc_uname for all objects */ 201. 	for(i=0; i < TOTAL_OBJS; i++) { 202. 		if(objects[i].oc_uname) { 203. 			len = strlen(objects[i].oc_uname)+1; 204. 			bwrite(fd, (genericptr_t)&len, sizeof len); 205. 			bwrite(fd, (genericptr_t)objects[i].oc_uname, len); 206. 		}  207.  	}  208.  }  209.   210.  void 211. restnames(fd) 212. register int fd; 213. {  214.  	register int i;  215. unsigned int len; 216. 	struct objclass *then; 217. 	long differ; 218. 	mread(fd, (genericptr_t) &then, sizeof then); 219. 	mread(fd, (genericptr_t) bases, sizeof bases); 220. 	mread(fd, (genericptr_t) disco, sizeof disco); 221. 	mread(fd, (genericptr_t) objects, sizeof(struct objclass) * TOTAL_OBJS); 222. #ifndef MSDOS 223. 	differ = (genericptr_t)&objects[0] - (genericptr_t)then; 224. #else 225. 	differ = (long)&objects[0] - (long)then; 226. #endif 227. 	for(i=0; i < TOTAL_OBJS; i++) { 228. 		if (objects[i].oc_name) { 229. #ifndef MSDOS 230. 			objects[i].oc_name += differ; 231. #else 232. 			objects[i].oc_name = 233. 			    (char *)((long)(objects[i].oc_name) + differ); 234. #endif 235. 		}  236.  		if (objects[i].oc_descr) { 237. #ifndef MSDOS 238. 			objects[i].oc_descr += differ; 239. #else 240. 			objects[i].oc_descr = 241. 			    (char *)((long)(objects[i].oc_descr) + differ); 242. #endif 243. 		}  244.  		if (objects[i].oc_uname) { 245. 			mread(fd, (genericptr_t) &len, sizeof len); 246. 			objects[i].oc_uname = (char *) alloc(len); 247. 			mread(fd, (genericptr_t)objects[i].oc_uname, len); 248. 		}  249.  	}  250.  }  251.   252.  static boolean 253. interesting_to_discover(i) 254. register int i;  255. { 256.      return objects[i].oc_uname != NULL || 257. 		(objects[i].oc_name_known && objects[i].oc_descr != NULL); 258. }  259.   260.  int 261. dodiscovered				/* free after Robert Viduya */ 262. {  263.      register int i, dis; 264.     int	ct = 0; 265.     char class = -1; 266.  267.      cornline(0, "Discoveries"); 268.  269.      for (i = 0; i <= NROFOBJECTS; i++) { 270. 	if (interesting_to_discover(dis = disco[i])) { 271. 	    ct++; 272. 	    if (objects[dis].oc_olet != class) { 273. 		class = objects[dis].oc_olet; 274. 		cornline(1, let_to_name(class)); 275. 	    }  276.  	    cornline(1, typename(dis)); 277. 	}  278.      }  279.      if (ct == 0) { 280. 	You("haven't discovered anything yet..."); 281. 	cornline(3, NULL); 282.     } else 283. 	cornline(2, NULL); 284.  285.      return 0; 286. }