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