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