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