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