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