Source:NetHack 1.4f/o init.c

From NetHackWiki
Jump to: navigation, search

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