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