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