Merge from vendor branch GROFF:
[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 /* $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 }