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