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