xref: /openbsd/games/hack/hack.o_init.c (revision dc14b708)
1 /*	$OpenBSD: hack.o_init.c,v 1.9 2019/04/05 09:02:27 bentley Exp $	*/
2 
3 /*
4  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5  * Amsterdam
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * - Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * - Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  *
19  * - Neither the name of the Stichting Centrum voor Wiskunde en
20  * Informatica, nor the names of its contributors may be used to endorse or
21  * promote products derived from this software without specific prior
22  * written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 /*
38  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39  * All rights reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. The name of the author may not be used to endorse or promote products
50  *    derived from this software without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 #include <stdio.h>
65 
66 #include "hack.h"
67 #include "def.objects.h"
68 
69 static void setgemprobs(void);
70 static int  interesting_to_discover(int);
71 
72 int
letindex(char let)73 letindex(char let)
74 {
75 	int i = 0;
76 	char ch;
77 
78 	while((ch = obj_symbols[i++]) != 0)
79 		if(ch == let) return(i);
80 	return(0);
81 }
82 
83 void
init_objects(void)84 init_objects(void)
85 {
86 	int i, j, first, last, sum, end;
87 	char let, *tmp;
88 
89 	/* init base; if probs given check that they add up to 100,
90 	   otherwise compute probs; shuffle descriptions */
91 	end = SIZE(objects);
92 	first = 0;
93 	while( first < end ) {
94 		let = objects[first].oc_olet;
95 		last = first+1;
96 		while(last < end && objects[last].oc_olet == let
97 				&& objects[last].oc_name != NULL)
98 			last++;
99 		i = letindex(let);
100 		if((!i && let != ILLOBJ_SYM) || bases[i] != 0)
101 			error("initialization error");
102 		bases[i] = first;
103 
104 		if(let == GEM_SYM)
105 			setgemprobs();
106 	check:
107 		sum = 0;
108 		for(j = first; j < last; j++) sum += objects[j].oc_prob;
109 		if(sum == 0) {
110 			for(j = first; j < last; j++)
111 			    objects[j].oc_prob = (100+j-first)/(last-first);
112 			goto check;
113 		}
114 		if(sum != 100)
115 			error("init-prob error for %c", let);
116 
117 		if(objects[first].oc_descr != NULL && let != TOOL_SYM){
118 			/* shuffle, also some additional descriptions */
119 			while(last < end && objects[last].oc_olet == let)
120 				last++;
121 			j = last;
122 			while(--j > first) {
123 				i = first + rn2(j+1-first);
124 				tmp = objects[j].oc_descr;
125 				objects[j].oc_descr = objects[i].oc_descr;
126 				objects[i].oc_descr = tmp;
127 			}
128 		}
129 		first = last;
130 	}
131 }
132 
133 int
probtype(char let)134 probtype(char let)
135 {
136 	int i = bases[letindex(let)];
137 	int prob = rn2(100);
138 
139 	while((prob -= objects[i].oc_prob) >= 0) i++;
140 	if(objects[i].oc_olet != let || !objects[i].oc_name)
141 		panic("probtype(%c) error, i=%d", let, i);
142 	return(i);
143 }
144 
145 static void
setgemprobs(void)146 setgemprobs(void)
147 {
148 	int j,first;
149 	extern xchar dlevel;
150 
151 	first = bases[letindex(GEM_SYM)];
152 
153 	for(j = 0; j < 9-dlevel/3; j++)
154 		objects[first+j].oc_prob = 0;
155 	first += j;
156 	if(first >= LAST_GEM || first >= SIZE(objects) ||
157 	    objects[first].oc_olet != GEM_SYM ||
158 	    objects[first].oc_name == NULL)
159 		printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
160 			first, j, LAST_GEM);
161 	for(j = first; j < LAST_GEM; j++)
162 		objects[j].oc_prob = (20+j-first)/(LAST_GEM-first);
163 }
164 
165 void
oinit(void)166 oinit(void)			/* level dependent initialization */
167 {
168 	setgemprobs();
169 }
170 
171 void
savenames(int fd)172 savenames(int fd)
173 {
174 	int i;
175 	unsigned len;
176 	unsigned zero = 0;
177 
178 	bwrite(fd, bases, sizeof bases);
179 	bwrite(fd, objects, sizeof objects);
180 	for(i=0; i < SIZE(objects); i++) {
181 		if(objects[i].oc_name) {
182 			len = strlen(objects[i].oc_name)+1;
183 			bwrite(fd, &len, sizeof len);
184 			bwrite(fd, objects[i].oc_name, len);
185 		} else
186 			bwrite(fd, &zero, sizeof len);
187 		if(objects[i].oc_descr) {
188 			len = strlen(objects[i].oc_descr)+1;
189 			bwrite(fd, &len, sizeof len);
190 			bwrite(fd, objects[i].oc_descr, len);
191 		} else
192 			bwrite(fd, &zero, sizeof len);
193 		if(objects[i].oc_uname) {
194 			len = strlen(objects[i].oc_uname)+1;
195 			bwrite(fd, &len, sizeof len);
196 			bwrite(fd, objects[i].oc_uname, len);
197 		} else
198 			bwrite(fd, &zero, sizeof len);
199 	}
200 }
201 
202 void
restnames(int fd)203 restnames(int fd)
204 {
205 	int i;
206 	unsigned len;
207 
208 	mread(fd, (char *) bases, sizeof bases);
209 	mread(fd, (char *) objects, sizeof objects);
210 	for(i=0; i < SIZE(objects); i++) {
211 		mread(fd, (char *) &len, sizeof len);
212 		if(len) {
213 			objects[i].oc_name = (char *) alloc(len);
214 			mread(fd, objects[i].oc_name, len);
215 		} else
216 			objects[i].oc_name = 0;
217 		mread(fd, (char *) &len, sizeof len);
218 		if(len) {
219 			objects[i].oc_descr = (char *) alloc(len);
220 			mread(fd, objects[i].oc_descr, len);
221 		} else
222 			objects[i].oc_descr = 0;
223 		mread(fd, (char *) &len, sizeof len);
224 		if(len) {
225 			objects[i].oc_uname = (char *) alloc(len);
226 			mread(fd, objects[i].oc_uname, len);
227 		} else
228 			objects[i].oc_uname = 0;
229 	}
230 }
231 
232 int
dodiscovered(void)233 dodiscovered(void)				/* free after Robert Viduya */
234 {
235     int i, end;
236     int	ct = 0;
237 
238     cornline(0, "Discoveries");
239 
240     end = SIZE(objects);
241     for (i = 0; i < end; i++) {
242 	if (interesting_to_discover (i)) {
243 	    ct++;
244 	    cornline(1, typename(i));
245 	}
246     }
247     if (ct == 0) {
248 	pline ("You haven't discovered anything yet...");
249 	cornline(3, NULL);
250     } else
251 	cornline(2, NULL);
252 
253     return(0);
254 }
255 
256 static int
interesting_to_discover(int i)257 interesting_to_discover(int i)
258 {
259     return(
260 	objects[i].oc_uname != NULL ||
261 	 (objects[i].oc_name_known && objects[i].oc_descr != NULL)
262     );
263 }
264