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 } 185