hack.o_init.c revision 1.6
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
18int
19letindex(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
30void
31init_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();
55check:
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
83int
84probtype(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
96void
97setgemprobs()
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
115void
116oinit()
117{				/* level dependent initialization */
118	setgemprobs();
119}
120
121void
122savenames(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
142void
143restnames(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
158int
159dodiscovered()
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
182int
183interesting_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