xref: /netbsd-src/games/hack/hack.o_init.c (revision 2a399c6883d870daece976daec6ffa7bb7f934ce)
1 /*	$NetBSD: hack.o_init.c,v 1.5 1997/10/19 16:58:37 christos Exp $	*/
2 
3 /*
4  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5  */
6 
7 #include <sys/cdefs.h>
8 #ifndef lint
9 __RCSID("$NetBSD: hack.o_init.c,v 1.5 1997/10/19 16:58:37 christos Exp $");
10 #endif				/* not lint */
11 
12 #include <string.h>
13 #include "hack.h"
14 #include "extern.h"
15 #include "def.objects.h"
16 #include "hack.onames.h"	/* for LAST_GEM */
17 
18 int
19 letindex(let)
20 	char            let;
21 {
22 	int             i = 0;
23 	char            ch;
24 	while ((ch = obj_symbols[i++]) != 0)
25 		if (ch == let)
26 			return (i);
27 	return (0);
28 }
29 
30 void
31 init_objects()
32 {
33 	int             i, j, first, last, sum, end;
34 	char            let, *tmp;
35 	/*
36 	 * init base; if probs given check that they add up to 100, otherwise
37 	 * compute probs; shuffle descriptions
38 	 */
39 	end = SIZE(objects);
40 	first = 0;
41 	while (first < end) {
42 		let = objects[first].oc_olet;
43 		last = first + 1;
44 		while (last < end && objects[last].oc_olet == let
45 		       && objects[last].oc_name != NULL)
46 			last++;
47 		i = letindex(let);
48 		if ((!i && let != ILLOBJ_SYM) || bases[i] != 0)
49 			error("initialization error");
50 		bases[i] = first;
51 
52 		if (let == GEM_SYM)
53 			setgemprobs();
54 check:
55 		sum = 0;
56 		for (j = first; j < last; j++)
57 			sum += objects[j].oc_prob;
58 		if (sum == 0) {
59 			for (j = first; j < last; j++)
60 				objects[j].oc_prob = (100 + j - first) / (last - first);
61 			goto check;
62 		}
63 		if (sum != 100)
64 			error("init-prob error for %c", let);
65 
66 		if (objects[first].oc_descr != NULL && let != TOOL_SYM) {
67 			/* shuffle, also some additional descriptions */
68 			while (last < end && objects[last].oc_olet == let)
69 				last++;
70 			j = last;
71 			while (--j > first) {
72 				i = first + rn2(j + 1 - first);
73 				tmp = objects[j].oc_descr;
74 				objects[j].oc_descr = objects[i].oc_descr;
75 				objects[i].oc_descr = tmp;
76 			}
77 		}
78 		first = last;
79 	}
80 }
81 
82 int
83 probtype(let)
84 	char            let;
85 {
86 	int             i = bases[letindex(let)];
87 	int             prob = rn2(100);
88 	while ((prob -= objects[i].oc_prob) >= 0)
89 		i++;
90 	if (objects[i].oc_olet != let || !objects[i].oc_name)
91 		panic("probtype(%c) error, i=%d", let, i);
92 	return (i);
93 }
94 
95 void
96 setgemprobs()
97 {
98 	int             j, first;
99 
100 	first = bases[letindex(GEM_SYM)];
101 
102 	for (j = 0; j < 9 - dlevel / 3; j++)
103 		objects[first + j].oc_prob = 0;
104 	first += j;
105 	if (first >= LAST_GEM || first >= SIZE(objects) ||
106 	    objects[first].oc_olet != GEM_SYM ||
107 	    objects[first].oc_name == NULL)
108 		printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
109 		       first, j, LAST_GEM);
110 	for (j = first; j < LAST_GEM; j++)
111 		objects[j].oc_prob = (20 + j - first) / (LAST_GEM - first);
112 }
113 
114 void
115 oinit()
116 {				/* level dependent initialization */
117 	setgemprobs();
118 }
119 
120 void
121 savenames(fd)
122 	int             fd;
123 {
124 	int             i;
125 	unsigned        len;
126 	bwrite(fd, (char *) bases, sizeof bases);
127 	bwrite(fd, (char *) objects, sizeof objects);
128 	/*
129 	 * as long as we use only one version of Hack/Quest we need not save
130 	 * oc_name and oc_descr, but we must save oc_uname for all objects
131 	 */
132 	for (i = 0; i < SIZE(objects); i++) {
133 		if (objects[i].oc_uname) {
134 			len = strlen(objects[i].oc_uname) + 1;
135 			bwrite(fd, (char *) &len, sizeof len);
136 			bwrite(fd, objects[i].oc_uname, len);
137 		}
138 	}
139 }
140 
141 void
142 restnames(fd)
143 	int             fd;
144 {
145 	int             i;
146 	unsigned        len;
147 	mread(fd, (char *) bases, sizeof bases);
148 	mread(fd, (char *) objects, sizeof objects);
149 	for (i = 0; i < SIZE(objects); i++)
150 		if (objects[i].oc_uname) {
151 			mread(fd, (char *) &len, sizeof len);
152 			objects[i].oc_uname = (char *) alloc(len);
153 			mread(fd, objects[i].oc_uname, len);
154 		}
155 }
156 
157 int
158 dodiscovered()
159 {				/* free after Robert Viduya */
160 	int             i, end;
161 	int             ct = 0;
162 
163 	cornline(0, "Discoveries");
164 
165 	end = SIZE(objects);
166 	for (i = 0; i < end; i++) {
167 		if (interesting_to_discover(i)) {
168 			ct++;
169 			cornline(1, typename(i));
170 		}
171 	}
172 	if (ct == 0) {
173 		pline("You haven't discovered anything yet...");
174 		cornline(3, (char *) 0);
175 	} else
176 		cornline(2, (char *) 0);
177 
178 	return (0);
179 }
180 
181 int
182 interesting_to_discover(i)
183 	int             i;
184 {
185 	return (
186 		objects[i].oc_uname != NULL ||
187 		(objects[i].oc_name_known && objects[i].oc_descr != NULL)
188 		);
189 }
190