xref: /netbsd/games/trek/warp.c (revision bf9ec67e)
1 /*	$NetBSD: warp.c,v 1.7 2001/04/25 02:33:10 simonb Exp $	*/
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)warp.c	8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: warp.c,v 1.7 2001/04/25 02:33:10 simonb Exp $");
42 #endif
43 #endif /* not lint */
44 
45 #include <stdio.h>
46 #include <math.h>
47 #include <string.h>
48 #include <unistd.h>
49 #include "trek.h"
50 #include "getpar.h"
51 
52 /*
53 **  MOVE UNDER WARP POWER
54 **
55 **	This is both the "move" and the "ram" commands, differing
56 **	only in the flag 'fl'.  It is also used for automatic
57 **	emergency override mode, when 'fl' is < 0 and 'c' and 'd'
58 **	are the course and distance to be moved.  If 'fl' >= 0,
59 **	the course and distance are asked of the captain.
60 **
61 **	The guts of this routine are in the routine move(), which
62 **	is shared with impulse().  Also, the working part of this
63 **	routine is very small; the rest is to handle the slight chance
64 **	that you may be moving at some riduculous speed.  In that
65 **	case, there is code to handle time warps, etc.
66 */
67 
68 void
69 dowarp(fl)
70 	int fl;
71 {
72 	int c;
73 	double d;
74 
75 	if (getcodi(&c, &d))
76 		return;
77 	warp(fl, c, d);
78 }
79 
80 void
81 warp(fl, c, d)
82 int	fl, c;
83 double	d;
84 {
85 	char	       *p;
86 	int		course;
87 	double		power;
88 	double		dist;
89 	double		time;
90 	double		speed;
91 	double		frac;
92 	int		percent;
93 	int		i;
94 
95 	if (Ship.cond == DOCKED) {
96 		printf("%s is docked\n", Ship.shipname);
97 		return;
98 	}
99 	if (damaged(WARP))
100 	{
101 		out(WARP);
102 		return;
103 	}
104 
105 	course = c;
106 	dist = d;
107 
108 	/* check to see that we are not using an absurd amount of power */
109 	power = (dist + 0.05) * Ship.warp3;
110 	percent = 100 * power / Ship.energy + 0.5;
111 	if (percent >= 85)
112 	{
113 		printf("Scotty: That would consume %d%% of our remaining energy.\n",
114 			percent);
115 		if (!getynpar("Are you sure that is wise"))
116 			return;
117 	}
118 
119 	/* compute the speed we will move at, and the time it will take */
120 	speed = Ship.warp2 / Param.warptime;
121 	time = dist / speed;
122 
123 	/* check to see that that value is not ridiculous */
124 	percent = 100 * time / Now.time + 0.5;
125 	if (percent >= 85)
126 	{
127 		printf("Spock: That would take %d%% of our remaining time.\n",
128 			percent);
129 		if (!getynpar("Are you sure that is wise"))
130 			return;
131 	}
132 
133 	/* compute how far we will go if we get damages */
134 	if (Ship.warp > 6.0 && ranf(100) < 20 + 15 * (Ship.warp - 6.0))
135 	{
136 		frac = franf();
137 		dist *= frac;
138 		time *= frac;
139 		damage(WARP, (frac + 1.0) * Ship.warp * (franf() + 0.25) * 0.20);
140 	}
141 
142 	/* do the move */
143 	Move.time = move(fl, course, time, speed);
144 
145 	/* see how far we actually went, and decrement energy appropriately */
146 	dist = Move.time * speed;
147 	Ship.energy -= dist * Ship.warp3 * (Ship.shldup + 1);
148 
149 	/* test for bizarre events */
150 	if (Ship.warp <= 9.0)
151 		return;
152 	printf("\n\n  ___ Speed exceeding warp nine ___\n\n");
153 	sleep(2);
154 	printf("Ship's safety systems malfunction\n");
155 	sleep(2);
156 	printf("Crew experiencing extreme sensory distortion\n");
157 	sleep(4);
158 	if (ranf(100) >= 100 * dist)
159 	{
160 		printf("Equilibrium restored -- all systems normal\n");
161 		return;
162 	}
163 
164 	/* select a bizzare thing to happen to us */
165 	percent = ranf(100);
166 	if (percent < 70)
167 	{
168 		/* time warp */
169 		if (percent < 35 || !Game.snap)
170 		{
171 			/* positive time warp */
172 			time = (Ship.warp - 8.0) * dist * (franf() + 1.0);
173 			Now.date += time;
174 			printf("Positive time portal entered -- it is now Stardate %.2f\n",
175 				Now.date);
176 			for (i = 0; i < MAXEVENTS; i++)
177 			{
178 				percent = Event[i].evcode;
179 				if (percent == E_FIXDV || percent == E_LRTB)
180 					Event[i].date += time;
181 			}
182 			return;
183 		}
184 
185 		/* s/he got lucky: a negative time portal */
186 		time = Now.date;
187 		p = (char *) Etc.snapshot;
188 		memcpy(p, Quad, sizeof Quad);
189 		p += sizeof Quad;
190 		memcpy(p, Event, sizeof Event);
191 		p += sizeof Event;
192 		memcpy(p, &Now, sizeof Now);
193 		printf("Negative time portal entered -- it is now Stardate %.2f\n",
194 			Now.date);
195 		for (i = 0; i < MAXEVENTS; i++)
196 			if (Event[i].evcode == E_FIXDV)
197 				reschedule(&Event[i], Event[i].date - time);
198 		return;
199 	}
200 
201 	/* test for just a lot of damage */
202 	if (percent < 80)
203 		lose(L_TOOFAST);
204 	printf("Equilibrium restored -- extreme damage occurred to ship systems\n");
205 	for (i = 0; i < NDEV; i++)
206 		damage(i, (3.0 * (franf() + franf()) + 1.0) * Param.damfac[i]);
207 	Ship.shldup = 0;
208 }
209