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