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