pc-hack

PC HACK 3.61 source code (archival)
git clone http://frotz.net/git/pc-hack.git
Log | Files | Refs

o_init.c (4982B)


      1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
      2 /* o_init.c - version 1.0.3 */
      3 
      4 #include	"config.h"		/* for typedefs */
      5 #include	"objects.h"
      6 #include	"onames.h"		/* for LAST_GEM */
      7 extern char *index();
      8 
      9 int
     10 letindex(let) register char let; {
     11 register int i = 0;
     12 register char ch;
     13 	while((ch = obj_symbols[i++]) != 0)
     14 		if(ch == let) return(i);
     15 	return(0);
     16 }
     17 
     18 init_objects(){
     19 register int i, j, first, last, sum, end, tmp_i;
     20 register char let, *tmp;
     21 	/* init base; if probs given check that they add up to 100, 
     22 	   otherwise compute probs; shuffle descriptions */
     23 	end = SIZE(objects);
     24 #ifdef MSDOS
     25 	/* Assign indices to all oc_descr_i first */
     26 	for (i = 0; i < end; i++)
     27 		objects[i].oc_descr_i = i;
     28 #endif
     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 #ifdef MSDOS
     65 	/* keep track of where the description came from */
     66 				tmp_i = objects[j].oc_descr_i;
     67 				objects[j].oc_descr_i = objects[i].oc_descr_i;
     68 				objects[i].oc_descr_i = tmp_i;
     69 #endif
     70 			}
     71 		}
     72 		first = last;
     73 	}
     74 }
     75 
     76 probtype(let) register char let; {
     77 register int i = bases[letindex(let)];
     78 register int prob = rn2(100);
     79 	while((prob -= objects[i].oc_prob) >= 0) i++;
     80 	if(objects[i].oc_olet != let || !objects[i].oc_name)
     81 		panic("probtype(%c) error, i=%d", let, i);
     82 	return(i);
     83 }
     84 
     85 setgemprobs()
     86 {
     87 	register int j,first;
     88 	extern xchar dlevel;
     89 
     90 	first = bases[letindex(GEM_SYM)];
     91 
     92 	for(j = 0; j < 9-dlevel/3; j++)
     93 		objects[first+j].oc_prob = 0;
     94 	first += j;
     95 	if(first >= LAST_GEM || first >= SIZE(objects) ||
     96 	    objects[first].oc_olet != GEM_SYM ||
     97 	    objects[first].oc_name == NULL)
     98 		printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
     99 			first, j, LAST_GEM);
    100 	for(j = first; j < LAST_GEM; j++)
    101 		objects[j].oc_prob = (20+j-first)/(LAST_GEM-first);
    102 }
    103 
    104 oinit()			/* level dependent initialization */
    105 {
    106 	setgemprobs();
    107 }
    108 
    109 extern long *alloc();
    110 
    111 savenames(fd) register fd; {
    112 register 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 restnames(fd) register fd; {
    129 register int i;
    130 unsigned len;
    131 #ifdef MSDOS
    132 	char *oc_descr[NROFOBJECTS + 1], *oc_name;
    133 
    134 	mread(fd, (char *) bases, sizeof bases);
    135 
    136 	/* Read in objects 1 at a time, correcting oc_name pointer and
    137 	 * saving pointer to current description.
    138 	 */
    139 	for (i = 0; i < SIZE(objects); i++) {
    140 		oc_name = objects[i].oc_name;
    141 		oc_descr[i] = objects[i].oc_descr;
    142 		mread(fd, (char *) &objects[i], sizeof (struct objclass));
    143 		objects[i].oc_name = oc_name;
    144 	}
    145 
    146 	/* Convert from saved indices into pointers */
    147 	for (i = 0; i < SIZE(objects); i++)
    148 		objects[i].oc_descr = oc_descr[objects[i].oc_descr_i];
    149 #else
    150 	mread(fd, (char *) bases, sizeof bases);
    151 	mread(fd, (char *) objects, sizeof objects);
    152 #endif
    153 	for(i=0; i < SIZE(objects); i++) if(objects[i].oc_uname) {
    154 		mread(fd, (char *) &len, sizeof len);
    155 		objects[i].oc_uname = (char *) alloc(len);
    156 		mread(fd, objects[i].oc_uname, len);
    157 	}
    158 }
    159 
    160 dodiscovered()				/* free after Robert Viduya */
    161 {
    162     extern char *typename();
    163     register int i, end;
    164     int	ct = 0;
    165 #ifdef DGK
    166     char class = -1;
    167     extern char *let_to_name();
    168 #endif
    169 
    170     cornline(0, "Discoveries");
    171 
    172     end = SIZE(objects);
    173     for (i = 0; i < end; i++) {
    174 	if (interesting_to_discover (i)) {
    175 	    ct++;
    176 #ifdef DGK
    177             if (objects[i].oc_olet != class) {
    178 		class = objects[i].oc_olet;
    179 		cornline(1, let_to_name(class));
    180             }
    181 #endif
    182 	    cornline(1, typename(i));
    183 	}
    184     }
    185     if (ct == 0) {
    186 	pline ("You haven't discovered anything yet...");
    187 	cornline(3, (char *) 0);
    188     } else
    189 	cornline(2, (char *) 0);
    190 
    191     return(0);
    192 }
    193 
    194 interesting_to_discover(i)
    195 register int i;
    196 {
    197     return(
    198 	objects[i].oc_uname != NULL ||
    199 	 (objects[i].oc_name_known && objects[i].oc_descr != NULL)
    200     );
    201 }