Below is the full text to o_init.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/o_init.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license. |
1. /* SCCS Id: @(#)o_init.c 2.0 87/09/16 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "config.h" /* for typedefs */ 5. #include "objects.h" 6. #include "onames.h" /* for LAST_GEM */ 7. extern char *index(); 8. 9. int 10. letindex(let) register char let; { 11. register int i = 0; 12. register char ch; 13. while((ch = obj_symbols[i++]) != 0) 14. if(ch == let) return(i); 15. return(0); 16. } 17. 18. init_objects(){ 19. register int i, j, first, last, sum, end; 20. #ifdef MSDOS 21. register int tmp_i; 22. #endif 23. register char let, *tmp; 24. 25. /* bug fix to prevent "initialization error" abort on Intel Xenix. 26. * reported by mikew@semike 27. */ 28. for(i = 0; i != sizeof(obj_symbols); i++) 29. bases[i] = 0; 30. 31. /* init base; if probs given check that they add up to 100, 32. otherwise compute probs; shuffle descriptions */ 33. end = SIZE(objects); 34. #ifdef MSDOS 35. /* Assign indices to all oc_descr_i first */ 36. for (i = 0; i < end; i++) 37. objects[i].oc_descr_i = i; 38. #endif 39. first = 0; 40. while( first < end ) { 41. let = objects[first].oc_olet; 42. last = first+1; 43. while(last < end && objects[last].oc_olet == let 44. && objects[last].oc_name != NULL) last++; 45. i = letindex(let); 46. if((!i && let != ILLOBJ_SYM) || bases[i] != 0) 47. error("initialization error"); 48. bases[i] = first; 49. 50. if(let == GEM_SYM) setgemprobs(); 51. check: 52. sum = 0; 53. for(j = first; j < last; j++) sum += objects[j].oc_prob; 54. if(sum == 0) { 55. for(j = first; j < last; j++) 56. objects[j].oc_prob = (100+j-first)/(last-first); 57. goto check; 58. } 59. if(sum != 100) 60. error("init-prob error for %c (%d%%)", let, sum); 61. 62. if(objects[first].oc_descr != NULL && let != TOOL_SYM){ 63. /* shuffle, also some additional descriptions */ 64. while(last < end && objects[last].oc_olet == let) 65. last++; 66. j = last; 67. while(--j > first) { 68. i = first + rn2(j+1-first); 69. tmp = objects[j].oc_descr; 70. objects[j].oc_descr = objects[i].oc_descr; 71. objects[i].oc_descr = tmp; 72. #ifdef MSDOS 73. /* keep track of where the description came from */ 74. tmp_i = objects[j].oc_descr_i; 75. objects[j].oc_descr_i = objects[i].oc_descr_i; 76. objects[i].oc_descr_i = tmp_i; 77. #endif 78. } 79. } 80. first = last; 81. } 82. } 83. 84. probtype(let) register char let; { 85. register int i = bases[letindex(let)]; 86. register int prob = rn2(100); 87. while((prob -= objects[i].oc_prob) >= 0) i++; 88. if(objects[i].oc_olet != let || !objects[i].oc_name) 89. panic("probtype(%c) error, i=%d", let, i); 90. return(i); 91. } 92. 93. setgemprobs() 94. { 95. register int j,first; 96. extern xchar dlevel; 97. 98. first = bases[letindex(GEM_SYM)]; 99. 100. for(j = 0; j < 9-dlevel/3; j++) 101. objects[first+j].oc_prob = 0; 102. first += j; 103. if(first >= LAST_GEM || first >= SIZE(objects) || 104. objects[first].oc_olet != GEM_SYM || 105. objects[first].oc_name == NULL) 106. printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n", 107. first, j, LAST_GEM); 108. for(j = first; j < LAST_GEM; j++) 109. objects[j].oc_prob = (20+j-first)/(LAST_GEM-first); 110. } 111. 112. oinit() /* level dependent initialization */ 113. { 114. setgemprobs(); 115. } 116. 117. extern long *alloc(); 118. 119. savenames(fd) register fd; { 120. register int i; 121. unsigned len; 122. bwrite(fd, (char *) bases, sizeof bases); 123. bwrite(fd, (char *) objects, sizeof objects); 124. /* as long as we use only one version of Hack/Quest we 125. need not save oc_name and oc_descr, but we must save 126. oc_uname for all objects */ 127. for(i=0; i < SIZE(objects); i++) { 128. if(objects[i].oc_uname) { 129. len = strlen(objects[i].oc_uname)+1; 130. bwrite(fd, (char *) &len, sizeof len); 131. bwrite(fd, objects[i].oc_uname, len); 132. } 133. } 134. } 135. 136. restnames(fd) register fd; { 137. register int i; 138. unsigned len; 139. #ifdef MSDOS 140. char *oc_descr[NROFOBJECTS + 1], *oc_name; 141. 142. mread(fd, (char *) bases, sizeof bases); 143. 144. /* Read in objects 1 at a time, correcting oc_name pointer and 145. * saving pointer to current description. 146. */ 147. for (i = 0; i < SIZE(objects); i++) { 148. oc_name = objects[i].oc_name; 149. oc_descr[i] = objects[i].oc_descr; 150. mread(fd, (char *) &objects[i], sizeof (struct objclass)); 151. objects[i].oc_name = oc_name; 152. } 153. 154. /* Convert from saved indices into pointers */ 155. for (i = 0; i < SIZE(objects); i++) 156. objects[i].oc_descr = oc_descr[objects[i].oc_descr_i]; 157. #else 158. mread(fd, (char *) bases, sizeof bases); 159. mread(fd, (char *) objects, sizeof objects); 160. #endif 161. for(i=0; i < SIZE(objects); i++) if(objects[i].oc_uname) { 162. mread(fd, (char *) &len, sizeof len); 163. objects[i].oc_uname = (char *) alloc(len); 164. mread(fd, objects[i].oc_uname, len); 165. } 166. } 167. 168. dodiscovered() /* free after Robert Viduya */ 169. { 170. extern char *typename(); 171. register int i, end; 172. int ct = 0; 173. #ifdef DGKMOD 174. char class = -1; 175. extern char *let_to_name(); 176. #endif 177. 178. cornline(0, "Discoveries"); 179. 180. end = SIZE(objects); 181. for (i = 0; i < end; i++) { 182. if (interesting_to_discover (i)) { 183. ct++; 184. #ifdef DGKMOD 185. if (objects[i].oc_olet != class) { 186. class = objects[i].oc_olet; 187. cornline(1, let_to_name(class)); 188. } 189. #endif 190. cornline(1, typename(i)); 191. } 192. } 193. if (ct == 0) { 194. pline ("You haven't discovered anything yet..."); 195. cornline(3, (char *) 0); 196. } else 197. cornline(2, (char *) 0); 198. 199. return(0); 200. } 201. 202. interesting_to_discover(i) 203. register int i; 204. { 205. return( 206. objects[i].oc_uname != NULL || 207. (objects[i].oc_name_known && objects[i].oc_descr != NULL) 208. ); 209. } 210. 211. init_corpses() { 212. 213. #ifdef SPIDERS 214. strcpy(objects[DEAD_GIANT_SPIDER].oc_name, "dead giant spider"); 215. #endif 216. 217. #ifdef KOPS 218. strcpy(objects[DEAD_KOP].oc_name, "dead Kop"); 219. # endif 220. 221. #ifdef ROCKMOLE 222. strcpy(objects[DEAD_ROCKMOLE].oc_name, "dead rockmole"); 223. #endif 224. 225. #ifndef KAA 226. strcpy(objects[DEAD_QUASIT].oc_name, "dead quasit"); 227. strcpy(objects[DEAD_VIOLET_FUNGI].oc_name, "dead violet fungi"); 228. #endif 229. return(0); 230. }