xref: /netbsd-src/games/trek/help.c (revision da121b333149705fd908f272187095dff6b9353c)
1*da121b33Sdholland /*	$NetBSD: help.c,v 1.13 2009/08/12 08:54:54 dholland Exp $	*/
2887dd216Scgd 
361f28255Scgd /*
4887dd216Scgd  * Copyright (c) 1980, 1993
5887dd216Scgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
32ef383c95Schristos #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
34887dd216Scgd #if 0
35887dd216Scgd static char sccsid[] = "@(#)help.c	8.1 (Berkeley) 5/31/93";
36887dd216Scgd #else
37*da121b33Sdholland __RCSID("$NetBSD: help.c,v 1.13 2009/08/12 08:54:54 dholland Exp $");
38887dd216Scgd #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd 
41ef383c95Schristos #include <stdio.h>
42ef383c95Schristos #include <math.h>
43ef383c95Schristos #include <unistd.h>
446fb30065Schristos #include <limits.h>
4561f28255Scgd #include "trek.h"
4661f28255Scgd 
4761f28255Scgd /*
4861f28255Scgd **  call starbase for help
4961f28255Scgd **
5061f28255Scgd **	First, the closest starbase is selected.  If there is a
5161f28255Scgd **	a starbase in your own quadrant, you are in good shape.
5261f28255Scgd **	This distance takes quadrant distances into account only.
5361f28255Scgd **
5461f28255Scgd **	A magic number is computed based on the distance which acts
5561f28255Scgd **	as the probability that you will be rematerialized.  You
5661f28255Scgd **	get three tries.
5761f28255Scgd **
5861f28255Scgd **	When it is determined that you should be able to be remater-
5961f28255Scgd **	ialized (i.e., when the probability thing mentioned above
6061f28255Scgd **	comes up positive), you are put into that quadrant (anywhere).
6161f28255Scgd **	Then, we try to see if there is a spot adjacent to the star-
6261f28255Scgd **	base.  If not, you can't be rematerialized!!!  Otherwise,
6361f28255Scgd **	it drops you there.  It only tries five times to find a spot
6461f28255Scgd **	to drop you.  After that, it's your problem.
6561f28255Scgd */
6661f28255Scgd 
67*da121b33Sdholland static const char *const Cntvect[3] = {
6850b862e2Sdholland 	"first", "second", "third"
6950b862e2Sdholland };
7061f28255Scgd 
71ef383c95Schristos /*ARGSUSED*/
72ef383c95Schristos void
help(int v __unused)73bf0917b6Sdholland help(int v __unused)
7461f28255Scgd {
75ef383c95Schristos 	int		i;
7661f28255Scgd 	double		dist, x;
77ef383c95Schristos 	int		dx = 0, dy = 0;
78ef383c95Schristos 	int		j, l = 0;
7961f28255Scgd 
8061f28255Scgd 	/* check to see if calling for help is reasonable ... */
81ef383c95Schristos 	if (Ship.cond == DOCKED) {
82ef383c95Schristos 		printf("Uhura: But Captain, we're already docked\n");
83ef383c95Schristos 		return;
84ef383c95Schristos 	}
8561f28255Scgd 
8661f28255Scgd 	/* or possible */
87ef383c95Schristos 	if (damaged(SSRADIO)) {
88ef383c95Schristos 		out(SSRADIO);
89ef383c95Schristos 		return;
90ef383c95Schristos 	}
91ef383c95Schristos 	if (Now.bases <= 0) {
92ef383c95Schristos 		printf("Uhura: I'm not getting any response from starbase\n");
93ef383c95Schristos 		return;
94ef383c95Schristos 	}
9561f28255Scgd 
9661f28255Scgd 	/* tut tut, there goes the score */
9761f28255Scgd 	Game.helps += 1;
9861f28255Scgd 
9961f28255Scgd 	/* find the closest base */
1006fb30065Schristos 	dist = TOOLARGE;
10150b862e2Sdholland 	if (Quad[Ship.quadx][Ship.quady].bases <= 0) {
10261f28255Scgd 		/* there isn't one in this quadrant */
10350b862e2Sdholland 		for (i = 0; i < Now.bases; i++) {
10461f28255Scgd 			/* compute distance */
10561f28255Scgd 			dx = Now.base[i].x - Ship.quadx;
10661f28255Scgd 			dy = Now.base[i].y - Ship.quady;
10761f28255Scgd 			x = dx * dx + dy * dy;
10861f28255Scgd 			x = sqrt(x);
10961f28255Scgd 
11061f28255Scgd 			/* see if better than what we already have */
11150b862e2Sdholland 			if (x < dist) {
11261f28255Scgd 				dist = x;
11361f28255Scgd 				l = i;
11461f28255Scgd 			}
11561f28255Scgd 		}
11661f28255Scgd 
11761f28255Scgd 		/* go to that quadrant */
11861f28255Scgd 		Ship.quadx = Now.base[l].x;
11961f28255Scgd 		Ship.quady = Now.base[l].y;
12061f28255Scgd 		initquad(1);
12150b862e2Sdholland 	} else {
12261f28255Scgd 		dist = 0.0;
12361f28255Scgd 	}
12461f28255Scgd 
12561f28255Scgd 	/* dematerialize the Enterprise */
12661f28255Scgd 	Sect[Ship.sectx][Ship.secty] = EMPTY;
12761f28255Scgd 	printf("Starbase in %d,%d responds\n", Ship.quadx, Ship.quady);
12861f28255Scgd 
12961f28255Scgd 	/* this next thing acts as a probability that it will work */
13061f28255Scgd 	x = pow(1.0 - pow(0.94, dist), 0.3333333);
13161f28255Scgd 
13261f28255Scgd 	/* attempt to rematerialize */
13350b862e2Sdholland 	for (i = 0; i < 3; i++) {
13461f28255Scgd 		sleep(2);
13561f28255Scgd 		printf("%s attempt to rematerialize ", Cntvect[i]);
13650b862e2Sdholland 		if (franf() > x) {
13761f28255Scgd 			/* ok, that's good.  let's see if we can set her down */
13850b862e2Sdholland 			for (j = 0; j < 5; j++) {
13961f28255Scgd 				dx = Etc.starbase.x + ranf(3) - 1;
14061f28255Scgd 				if (dx < 0 || dx >= NSECTS)
14161f28255Scgd 					continue;
14261f28255Scgd 				dy = Etc.starbase.y + ranf(3) - 1;
14361357867Sdholland 				if (dy < 0 || dy >= NSECTS ||
14461357867Sdholland 				    Sect[dx][dy] != EMPTY)
14561f28255Scgd 					continue;
14661f28255Scgd 				break;
14761f28255Scgd 			}
14850b862e2Sdholland 			if (j < 5) {
14961f28255Scgd 				/* found an empty spot */
15061f28255Scgd 				printf("succeeds\n");
15161f28255Scgd 				Ship.sectx = dx;
15261f28255Scgd 				Ship.secty = dy;
15361f28255Scgd 				Sect[dx][dy] = Ship.ship;
154ef383c95Schristos 				dock(0);
15561f28255Scgd 				compkldist(0);
15661f28255Scgd 				return;
15761f28255Scgd 			}
15861f28255Scgd 			/* the starbase must have been surrounded */
15961f28255Scgd 		}
16061f28255Scgd 		printf("fails\n");
16161f28255Scgd 	}
16261f28255Scgd 
16361f28255Scgd 	/* one, two, three strikes, you're out */
16461f28255Scgd 	lose(L_NOHELP);
16561f28255Scgd }
166