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