Source:NetHack 3.0.0/o init.c

From NetHackWiki
Jump to navigation Jump to search

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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.  }