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